parent
522682c48f
commit
184b769dea
2 changed files with 111 additions and 0 deletions
@ -0,0 +1,111 @@ |
|||||||
|
+++ |
||||||
|
author = "Maik de Kruif" |
||||||
|
title = "Challenge 14 - AdventOfCTF" |
||||||
|
date = 2020-12-14T19:45:51+01:00 |
||||||
|
description = "A writeup for challenge 14 of AdventOfCTF." |
||||||
|
cover = "img/adventofctf/dd04640480d764ab09eea047cde749cd.png" |
||||||
|
tags = [ |
||||||
|
"AdventOfCTF", |
||||||
|
"challenge", |
||||||
|
"ctf", |
||||||
|
"hacking", |
||||||
|
"writeup", |
||||||
|
"web", |
||||||
|
"php", |
||||||
|
] |
||||||
|
categories = [ |
||||||
|
"ctf", |
||||||
|
"writeups", |
||||||
|
"hacking", |
||||||
|
] |
||||||
|
+++ |
||||||
|
|
||||||
|
- Points: 1400 |
||||||
|
|
||||||
|
## Description |
||||||
|
|
||||||
|
We are testing a new 2-factor security system for Santa's deepest secrets. It should be pretty secure! |
||||||
|
|
||||||
|
Visit <https://14.adventofctf.com> to start the challenge. |
||||||
|
|
||||||
|
## Finding the vulnerability |
||||||
|
|
||||||
|
Upon opening the challenge website we're greeted with some PHP code, as well as two input fields. The PHP code is the following: |
||||||
|
|
||||||
|
```php |
||||||
|
<?php |
||||||
|
|
||||||
|
ini_set('display_errors', 0); |
||||||
|
|
||||||
|
include("flag.php"); |
||||||
|
|
||||||
|
if (isset($_POST["password"], $_POST["verifier"])) { |
||||||
|
$password = $_POST["password"]; |
||||||
|
$verifier = $_POST["verifier"]; |
||||||
|
|
||||||
|
$hash = sha1($password + $secret_salt); |
||||||
|
$reference = substr($hash, 0, 7); |
||||||
|
|
||||||
|
if ($verifier === $reference) { |
||||||
|
echo $flag; |
||||||
|
die(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
header("Location: /index.php?error=That was not right."); |
||||||
|
exit(); |
||||||
|
|
||||||
|
?> |
||||||
|
``` |
||||||
|
|
||||||
|
As we can see, we only get the flag if `$verifier` is equal to `$reference`, where `$reference` is the `SHA-1` hash of the password in our request together with `$secret_salt`. |
||||||
|
|
||||||
|
_Note: when I started with this challenge, [@credmp](https://twitter.com/credmp) had already posted a hint which I, unfortunately, saw. It said "The salt is a number."._ |
||||||
|
|
||||||
|
## Type Juggling |
||||||
|
|
||||||
|
Because we already know `$secret_salt` is a number, we can leverage PHP type juggling to generate a known value for the hashing algorithm. But first, what is type juggling? |
||||||
|
|
||||||
|
Because PHP does not support explicit type definition in a variable declaration, a variable's type is determined by the context in which the variable is used. For instance, if a `string` value is assigned to a variable `$var`, `$var` becomes a string. But if an `int` value is then assigned to `$var`, it becomes an int. This means that if we have a `string` and add an `int` to it, the outcome will be an `int`. The value of this `int` depends on what is inside the `string`. If the `string` starts with a number, it will be interpreted as an `int` with the value of the number inside the `string`, and if it starts with a letter, it will be interpreted as `0`. |
||||||
|
|
||||||
|
For example, if we have a variable with the value `"hello"`, it will be converted to `0`. And if we have a variable with the value `"24"` or `"12ab"` it will be interpreted as `24` and `12` respectively. |
||||||
|
|
||||||
|
## Generating a verifier value |
||||||
|
|
||||||
|
To see what input will be converted to what output, we can create a little script that will generate those values for us. An example would be the following: |
||||||
|
|
||||||
|
```php |
||||||
|
<?php |
||||||
|
$password = "1a"; |
||||||
|
$secret_salt = "11"; |
||||||
|
|
||||||
|
$hash = sha1($password + $secret_salt); |
||||||
|
$reference = substr($hash, 0, 7); |
||||||
|
|
||||||
|
echo ($password + $secret_salt)."\n"; |
||||||
|
echo $hash."\n"; |
||||||
|
echo $reference."\n"; |
||||||
|
?> |
||||||
|
``` |
||||||
|
|
||||||
|
We can then run this script on our local machine or on a website like <https://sandbox.onlinephpfunctions.com/>. |
||||||
|
|
||||||
|
This script will take the two inputs and give us the outcome of the addition with the `$secret_salt` (I used 11 as the salt number but it could be any number), the generated hash and thus the `$verifier` input we need for the original script. |
||||||
|
|
||||||
|
If we make `$password` a really big number like `922337203685477580792233720368547758079223372036854775807` we see that the output of the addition will be written in the scientific notation if it is converted to a string. And because the `sha1()` function wants a `string` for the input, it will also get the shrunk-down version. This means that if we make `$password` big enough, the value of `$secret_salt` will not matter as it is not significant enough for the output. |
||||||
|
|
||||||
|
If we thus enter `922337203685477580792233720368547758079223372036854775807` as `$password` in the above script, we get the following output: |
||||||
|
|
||||||
|
```text |
||||||
|
9.2233720368548E+56 |
||||||
|
48a888ebec04f516e8b765bc3879354411ac2387 |
||||||
|
48a888e |
||||||
|
``` |
||||||
|
|
||||||
|
If we thus use `922337203685477580792233720368547758079223372036854775807` as the password and `48a888e` as the verifier, it should echo the flag. |
||||||
|
|
||||||
|
## Solution |
||||||
|
|
||||||
|
After entering the above form data and submitting it, we get the flag: `NOVI{typ3_juggl1ng_f0r_l1fe}`! |
||||||
|
|
||||||
|
This flag can then be submitted for the [challenge](https://ctfd.adventofctf.com/challenges#14-15). |
After Width: | Height: | Size: 564 KiB |
Loading…
Reference in new issue