我正在为uni分配共享内存,我已经“借用”和“按摩”了一些我在这里和其他地方阅读的帖子中看到的shellcode。我已经能够构造一个可以在MacBook(Mojave)上运行的示例,并且几乎可以完成我想要的操作。
但是,由于我没有在OS环境(本例中为MacOS)中进行汇编编程的经验,并且由于我不完全了解下面的汇编,因此我需要一点帮助来克服我的上一个问题。 / p>
在我的C样板包装器中,我有一个循环定期调用我的shellcode,但是该循环仅执行一次迭代。这使我得出结论,第二个syscall
(在下面的代码中)正在执行exit 0
,从而终止了该过程。
如何将程序集修改为 return 而不是 exit ?
注意,如果有要求,我可以发布有关我使用的包装器代码和工具的更多信息。
bits 64
Section .text
global start
start:
jmp short MESSAGE ;00000000 EB24 jmp short 0x26
GOBACK:
mov eax, 0x2000004 ;00000002 B804000002 mov eax,0x2000004 ; write
mov edi, 0x1 ;00000007 BF01000000 mov edi,0x1
lea rsi, [rel msg] ;0000000C 488D3518000000 lea rsi,[rel 0x2b]
mov edx, 0xf ;00000013 BA0F000000 mov edx,0xf
syscall ;00000018 0F05 syscall
mov eax,0x2000001 ;0000001A B801000002 mov eax,0x2000001 ;exit
mov edi,0x0 ;0000001F BF00000000 mov edi,0x0
syscall ;00000024 0F05 syscall
MESSAGE:
call GOBACK
msg: db "Hello, world!", 0dh, 0ah
.len: equ $ - msg
这是我的C样板代码,其中包括上面的shellcode。
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
const char shellcode[] = "\xeb\x24\xb8\x04\x00\x00\x02\xbf\x01\x00\x00\x00\x48\x8d\x35\x18\x00\x00\x00\xba\x0f\x00\x00\x00\x0f\x05\xb8\x01\x00\x00\x02\xbf\x00\x00\x00\x00\x0f\x05\xe8\xd7\xff\xff\xff\x48\x65\x6c\x6c\x6f\x2c\x20\x77\x6f\x72\x6c\x64\x21\x0d\x0a";
int main(int argc, char **argv)
{
void *mem = mmap(0, sizeof(shellcode), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
memcpy(mem, shellcode, sizeof(shellcode));
mprotect(mem, sizeof(shellcode), PROT_READ|PROT_WRITE|PROT_EXEC);
for (int i = 0; i < 10; i++) {
int (*func)();
func = (int (*)())mem;
(int)(*func)();
sleep(5);
}
munmap(mem, sizeof(shellcode));
return 0;
}
答案 0 :(得分:2)
我有一个循环调用我的shellcode
因此,如果它是实际的call
,那么您就很好了,唯一需要做的更改就是删除最后3条指令(mov
,mov
和{{1 }}),并用syscall
替换它们,因为返回地址已经在堆栈中了。但是我们还需要稍微清理一下堆栈,因为文本字符串的地址是为了ret
而放在这里,我们希望在返回之前将其清除。
此外,由于您的shellcode包含偏移量(第一个syscall
操作码的值为jmp
),因此不删除任何内容(因为它将更改偏移量)而是用{{1 }}。除非您修改shellcode的源代码并每次生成它-否则最好将其删除。
所以我实际上建议做的是用0x24
(NOP)替换最后3个操作码的字节,用NOP
替换最后3个操作码的字节{{ 1}}和0x90
。最终的shellcode可能看起来像这样:
pop rax\ret