On this post
- Information Gathering
- Privilege Escalation
Sink is a retired vulnerable VM from Hack The Box.
Let’s start with a
masscan probe to establish the open ports in the host.
masscan -e tun0 -p1-65535,U:1-65535 10.10.10.225 --rate=500 Starting masscan 1.3.2 (http://bit.ly/14GZzcT) at 2021-02-10 08:30:28 GMT Initiating SYN Stealth Scan Scanning 1 hosts [131070 ports/host] Discovered open port 22/tcp on 10.10.10.225 Discovered open port 3000/tcp on 10.10.10.225 Discovered open port 5000/tcp on 10.10.10.225
Nothing unusual stood out. Let’s do one better with
nmap scanning the discovered ports to establish their services.
nmap -n -v -Pn -p22,3000,5000 -A --reason 10.10.10.225 -oN nmap.txt ... PORT STATE SERVICE REASON VERSION 22/tcp open ssh syn-ack ttl 63 OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 3072 48:ad:d5:b8:3a:9f:bc:be:f7:e8:20:1e:f6:bf:de:ae (RSA) | 256 b7:89:6c:0b:20:ed:49:b2:c1:86:7c:29:92:74:1c:1f (ECDSA) |_ 256 18:cd:9d:08:a6:21:a8:b8:b6:f7:9f:8d:40:51:54:fb (ED25519) 3000/tcp open ppp? syn-ack ttl 63 | 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=029412539056da57; Path=/; HttpOnly | Set-Cookie: _csrf=wDZf6EYuO6ahzcpdgUTA7lI_21s6MTYxMzEwNzk1Mjg5MzMxNjkzNg; Path=/; Expires=Sat, 13 Feb 2021 05:32:32 GMT; HttpOnly | X-Frame-Options: SAMEORIGIN | Date: Fri, 12 Feb 2021 05:32:32 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=2ee2f644cf40c4ca; Path=/; HttpOnly | Set-Cookie: _csrf=UA4Fmja9ShJ3SYAytyqCSEHq1lk6MTYxMzEwNzk1Nzk0OTcyMTc5NQ; Path=/; Expires=Sat, 13 Feb 2021 05:32:37 GMT; HttpOnly | X-Frame-Options: SAMEORIGIN | Date: Fri, 12 Feb 2021 05:32:37 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 syn-ack ttl 62 Gunicorn 20.0.0 | http-methods: |_ Supported Methods: OPTIONS POST HEAD GET |_http-server-header: gunicorn/20.0.0 |_http-title: Sink Devops
Looks like we have two http services:
5000/tcp. This is what they look like.
I uncover three usernames while cursorily exploring the site.
This site offers a way to sign up for an account.
I got redirected to
/home immediately after signing up.
I’d better include map
This site has a Comment section in the home page to leave a comment and to delete that comment if you so desire. In addition, there’s also a Notes section to save, view and delete notes.
Be it posting a comment or saving a note, there’s something interesting with the response if you look closely.
The site is served from Gunicorn 20.0.0 via HAProxy (likely in a reverse proxy capacity), i.e. the backend server behind HAProxy is Gunicorn.
HAProxy HTTP request smuggling (CVE-2019-18277) with Gunicorn 20.0.0
According to this article,
To actually exploit HTTP smuggling using the issue described in this writeup, the backend server(s) behind HAProxy would also have to be vulnerable in the sense they too would need to suffer from a bug, but one which parses and accepts a poorly formed Transfer-Encoding header (almost certainly violating RFC7230). The backend must also support HTTP keep-alive.
According to synk, Gunicorn 20.0.0 is also vulnerable to HTTP request smuggling.
Affected versions of this package are vulnerable to HTTP Request Smuggling. It fails to properly process the
Content-Lengthheaders when both are present in a package request. This allows for conflicting information to be sent regarding the length of the package, which when processed by back-end servers under certain configurations would allow for malicious users to bypass security controls, gain unauthorized access to sensitive data, and directly compromise other application users.
Perfect. Taking a leaf from the Turbo Intruder script in the article, we can test for HTTP request smuggling with Burp Suite’s Repeater. The only thing to take note is that the backend server must support HTTP
This is the HTTP request that I’m going to send.
Ctrl-Shift-U to do a URL-decode on the highlighted
%0b to turn it into a vertical tab character. The following shows Burp Suite Repeater displaying the non-printable characters.
The idea is to smuggle the second POST request (line 20 onwards) with the hope that the HTTP connection is reused by someone, say, the Administrator. Note that the
Content-Length of the second request is 300-bytes more than 4-bytes (
msg=). If the HTTP request smuggling is successful, we should see request headers posted as comments like so.
This must be Administrator’s session!
Once we replace our session cookie with the Administrator’s, refresh
http://sink.htb:5000/home. And we should see ourselves logged in as Administrator.
Administrator has three notes.
Recall that Gitea had three users? The credential (
root:[email protected]>Z3})zzfQ3) works for
Voila! We have an archived repository. I’m sure something juicy resides in there!
Marcus’ SSH Private Key
b01a6b7ed3, we have a SSH private key!
If I had to guess, I would say that’s
marcus’ private key.
Bingo. The file
user.txt is at
marcus’ home directory.
During enumeration of
marcus’ account, I notice the presence of another user account
We need to look for
david’s password. How do I know that? Look at
david can’t SSH in, then surely we need to use
su. Simple as that.
What better way to keep a secret than using AWS Secrets Manager? To list the secrets stored in the Secrets Manager we can use AWS CLI like so. But in order to do that we need to run
aws configure first. The required information pertaining to
marcus such as endpoint, key, secrets, region, etc can be found in the Gitea Log_Management repository. You just need to know where to look. Hint: it’s in one of them commits.
Armed with this information, we can run
aws configure like so.
Note that all this information is stored in the
.aws directory. Once that’s done, we can
list-secrets like so.
get-secret-value like so.
david’s password is
During enumeration of
david’s account, I noticed the presence of
server.enc, which appears to be an encrypted file.
AWS Key Management Service (AWS KMS) is an encryption and key management web service. Perhaps we can use it to decrypt the file? Check this out in one of the commits in Key_Management repository.
david is able to
decrypt. But first, let’s do a
We can reuse the
marcus’ information in the
There are so many keys, which one is the encryption/decryption key? To that end, I’d to use a little Linux-fu.
There’s only one way to find out.
I think we are done here.