Commit 943c9a0b authored by Chu's avatar Chu

call_shellcode

parent a13ee8d9
......@@ -19,38 +19,28 @@ int main(int argc, char *argv[])
Process process(std::stoi(argv[1]));
// find libc.so in target process
std::cout << "[*] find libc.so in target process\n";
std::cout << "[*] try to find libc.so in target process\n";
auto [libc_path, libc_base] = process.find_libc();
std::cout << "[+] libc: " << libc_path << " 0x" << std::hex << libc_base << std::endl;
// find __libc_dlopen_mode in libc.so
std::cout << "[*] find __libc_dlopen_mode in " << libc_path << std::endl;
std::cout << "[*] try to find __libc_dlopen_mode in " << libc_path << std::endl;
Elf libc(libc_path);
libc.set_base(libc_base);
auto libc_dlopen_mode = libc.find_symbol_address_by_name("__libc_dlopen_mode");
std::cout << "[+] __libc_dlopen_mode: 0x" << libc_dlopen_mode << std::endl;
// get target process' entry point
std::cout << "[*] get target process' entry point\n";
auto entry_point = process.get_entry_point();
std::cout << "[+] entry point: 0x" << entry_point << std::endl;
// call shellcode in target process
std::cout << "[*] get shellcode in current process\n";
std::cout << "[*] try to get shellcode in current process\n";
auto call_libc_dlopen_mode_addr = reinterpret_cast<unsigned char *>(&call_libc_dlopen_mode);
auto call_libc_dlopen_mode_size =
Elf(argv[0]).get_func_size(reinterpret_cast<std::size_t>(call_libc_dlopen_mode_addr));
std::cout << "[+] shellcode: 0x" << reinterpret_cast<std::size_t>(call_libc_dlopen_mode_addr) << " " << std::dec
<< call_libc_dlopen_mode_size << std::endl;
std::cout << "[*] call shellcode in target process\n";
std::cout << "[*] try to call shellcode in target process\n";
process.call_shellcode(
std::vector(call_libc_dlopen_mode_addr, call_libc_dlopen_mode_addr + call_libc_dlopen_mode_size));
std::cout << "[+] done\n";
// resume target process
std::cout << "[*] resume target process\n";
process.detach();
std::cout << "[+] done\n";
std::cout << "[+] injected\n";
return 0;
}
......
#include "process.h"
#include <sys/wait.h>
#include <unistd.h>
#include <cstring>
#include <fstream>
#include <iostream>
#include <regex>
#include "elf.h"
......@@ -57,6 +59,89 @@ std::size_t Process::get_entry_point()
return elf.get_entry();
}
void Process::call_shellcode(std::vector<unsigned char> shellcode) {}
void Process::call_shellcode(std::vector<unsigned char> shellcode)
{
attach();
std::cout << "[*] try to get target process's entry point\n";
auto entry_point = get_entry_point();
std::cout << "[+] entry point: 0x" << std::hex << entry_point << std::endl;
// int3
shellcode.emplace_back(0xcc);
// align
while (shellcode.size() % sizeof(void *) != 0)
shellcode.emplace_back(0x90);
std::cout << "[*] try to backup original code\n";
auto original_code = read_memory(entry_point, shellcode.size());
std::cout << "[+] done\n";
std::cout << "[*] try to backup original registers\n";
auto original_registers = get_registers();
std::cout << "[+] done\n";
std::cout << "[*] try to write shellcode to target process's entry point\n";
write_memory(entry_point, shellcode);
std::cout << "[+] done\n";
detach();
}
void Process::attach()
{
if (ptrace(PTRACE_ATTACH, pid_, nullptr, nullptr) == -1)
throw std::runtime_error(std::strerror(errno));
wait(nullptr);
}
void Process::detach()
{
if (ptrace(PTRACE_DETACH, pid_, nullptr, nullptr) == -1)
throw std::runtime_error(std::strerror(errno));
wait(nullptr);
}
std::vector<unsigned char> Process::read_memory(std::size_t address, std::size_t size)
{
std::vector<unsigned char> data;
data.resize(size);
auto ptr = data.data();
std::size_t n = 0;
while (n != size)
{
auto word = ptrace(PTRACE_PEEKTEXT, pid_, address, nullptr);
if (word == -1)
throw std::runtime_error(std::strerror(errno));
auto to_copy = size - n > sizeof(void *) ? sizeof(void *) : size - n;
std::memcpy(ptr, &word, to_copy);
ptr += to_copy;
n += to_copy;
address += sizeof(void *);
}
return data;
}
void Process::write_memory(std::size_t address, std::vector<unsigned char> data)
{
auto ptr = data.data();
std::size_t n = 0;
while (n != data.size())
{
void *to_write = nullptr;
std::memcpy(&to_write, ptr, sizeof(to_write));
if (ptrace(PTRACE_POKETEXT, pid_, address, to_write) == -1)
throw std::runtime_error(std::strerror(errno));
address += sizeof(to_write);
ptr += sizeof(to_write);
n += sizeof(to_write);
}
}
user_regs_struct Process::get_registers()
{
user_regs_struct registers = {0};
if (ptrace(PTRACE_GETREGS, pid_, nullptr, &registers) == -1)
throw std::runtime_error(std::strerror(errno));
return registers;
}
void Process::detach() {}
void Process::set_registers(user_regs_struct registers) {}
#ifndef LINUX_LIBRARY_INJECT_PROCESS_H
#define LINUX_LIBRARY_INJECT_PROCESS_H
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/user.h>
#include <string>
#include <utility>
......@@ -14,13 +16,18 @@ public:
std::pair<std::string, std::size_t> find_libc();
std::size_t get_entry_point();
void call_shellcode(std::vector<unsigned char> shellcode);
void detach();
private:
pid_t pid_;
std::size_t get_base();
std::string get_execute();
void attach();
void detach();
std::vector<unsigned char> read_memory(std::size_t address, std::size_t size);
void write_memory(std::size_t address, std::vector<unsigned char> data);
user_regs_struct get_registers();
void set_registers(user_regs_struct registers);
};
#endif // LINUX_LIBRARY_INJECT_PROCESS_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment