我正在处理类似ctf的挑战,并且正在过滤我的shellcode,以确保我分别没有syscall,sysenter和int指令0x0f05 0x0f34和0x80cd的十六进制值编码。基本上,我有一个可以打开文件的shellcode,但是它包含syscall指令。在理解如何操作方面有任何帮助,因此我仍然可以进行系统调用而无需在我的shellcode中显式放置序列0x0f05。
lea rdi, _string[rip]
xor rsi, rsi
xor rax, rax
mov al, 2
syscall
我不一定要寻找确切的答案,而只是寻找一些帮助来理解一些可能的方法来操纵程序在运行时进行系统调用。
答案 0 :(得分:1)
是的,如果要利用的程序已加载包含syscall
指令的共享库(例如libc
),则可以制作一个跳到那里的shellcode。甚至直接跳转到glibc中的sendfile
包装函数,并将其args传递给寄存器。
另一种方法,您可以使用替代的syscall,例如read和socket syscall。
答案 1 :(得分:1)
由于您已经可以插入代码,因此可以将代码保存在具有write + exec权限的页面中,这样您就可以对其进行自我修改,并一次存储一条syscall
指令的字节(因此它们不会作为imm16的一部分被过滤掉。)
或更简单的是,从内存中的0e 05 ...
开始,然后使用inc byte ptr syscall_location[rip]
将其修改为0f 05 ...
。 RIP相对寻址模式意味着您不需要知道要修改的字节的地址,只需知道它的相对距离即可(汇编器会为您计算)。您可能需要向前跳,以使rel32
为负且没有任何零字节。或先将syscall
指令放回原处。
正如Sinkmanu所指出的那样,您可能会在进程的内存映射中的某处找到一条syscall
指令,在这种情况下,可能会使用像ret2reg这样的技术。
但是共享库代码往往相对于可执行文件是ASLR格式的,除非主可执行文件中有sendfile
的PLT存根,否则动态链接程序将找不到它的帮助。