最近在练习pwn,pwnable.kr这个网站有很多很有意思的pwn题,现放出我的部分刷题writeup:

1.fd

源码如下:

第一题送分,文件描述符中0为标准输入,1为标准输出,2为标准错误输出,输入如下得到flag:

2. col

源码如下:

输入20字节,每4字节作为一个整数,相加后得到 0x21DD09EC即可。由于是通过strlen判断长度,所以不能有0x00出现,将0x21DD09EC拆分成5个整数相加(0x01010101 + 0x01010101 + 0x01010101 + 0x01010101 + 0x1DD905E8)

 3.bof

用objdump看bof的反汇编,找到overflowme数组起始地址距离ebp的长度为0x2c(44),加上ebp,eip8字节,共要填充52字节:

bof
python脚本跑出flag:

4.flag

ida打开发现程序被加壳了,用010editor打开发现是UPX的壳,用upx命令脱壳:

脱壳后用ida直接找到flag字符串 flag: UPX…? sounds like a delivery service 🙂

5.passcode

漏洞代码如下:

这段代码存在scanf误用,读入的数据并没有写入passcode1,passcode2,而是写入了passcode1,passcode2未被初始化时所存储的内容,经过gdb调试发现welcome函数中的name变量最后4字节刚好可以覆盖到passcode1(堆栈平衡之后并没有情况栈,所以栈中残留着局部变量name),这样就可以通过控制name的最后4字节达到任意地址写。

最简单的想法是让代码直接跳转到system(“/bin/cat flag”);但是又不能直接修改eip,这时想到了修改GOT表,直接把下一个要执行的函数地址改成输出flag的代码的起始地址,通过objdump找到system(“/bin/cat flag”);代码起始地址:

可以看到起始地址为0x80485e3。scanf下一句代码是fflush(stdin); 同样用objdump找到fflush的GOT表地址:

GOT表项地址为0x804a004 。最终构造shellcode输入:

134514147为0x80485e3的十进制数值(因为 %d是取出整数),得到flag:Sorry mom.. I got confused about scanf usage 🙁

6.random

c中的rand函数产生的是伪随机数,每次产生出的是固定值,在本地跑一下发现固定为1804289383,于0xdeadbeef异或后得到3039230856,输入后得到flag:

Mommy, I thought libc random is unpredictable…

7.input

这里主要考察Linux编程,题目如下:

通过代码及注释如下:

由于只有/tmp目录下才有写权限,而最后读flag的语句为 /bin/cat flag,所以要将flag文件链接到/tmp目录下,在/tmp目录下新建软链接:

运行得到flag:Mommy! I learned how to pass various input in Linux 🙂

8.leg

这题是arm汇编,代码如下:

关键是要找到key1,key2,key3的返回值。对于arm汇编要知道几点:

  • 前4个参数分别放在R0,R1,R2,R3中,多出来的才存在栈上
  • 函数返回值存在R0中
  • LR保存函数的返回地址(函数调用时的下一条指令地址)
  • PC保存当前指令的下2条指令地址,在arm模式下为 当前指令地址+8,在thumb模式下为 当前指令地址+4

先来看key1的汇编:

可以看到把PC的值作为返回值,在执行到mov r3,pc时,PC的值为0x8cdc+8,即0x8ce4。

key2的汇编:

在key2中进行了arm到thumb的切换,其中add r6,pc #1只是为了跳转到thumb,跳转之后地址并没有加一。当执行到mov r3,pc时,PC的值为0x8d04+4,即0x8d08,后面再加上4得到返回值为0x8d0c。

key3的汇编:

key3中将lr的值作为返回值,lr的值为调用函数的下一条指令:

所以key3返回值为0x8d80。所有返回值相加得到 0x8ce4 + 0x8d0c + 0x8d80 =  108400

得到flag为:My daddy has a lot of ARMv5te muscle!

 

 

观看更多有关 的文章?

*

+
跳转到评论