Description
Vulnhub
靶机PwnLab:init
的练习记录。整体难度不高,最终目的是拿到/root/flag.txt
文件。
首先找下靶机地址:
扫描一下靶机的开放端口和服务:
Game Start
先看下80端口的服务:
Login界面是一个看起来很简陋的登陆界面:
尝试对登录接口爆破和SQL注入均无结果。
但是针对界面的URL:http://172.16.83.142/?page=login和http://172.16.83.142/?page=upload
的形式,猜测可能存在文件包含的问题。
结合nikto
给出的信息:
/config.php
文件存在可能泄露数据库的信息,但是直接访问是没有数据的。
接下来就尝试读取/config.php
文件的内容,详细内容可参考这篇文章php伪协议实现命令执行的七种姿势。最终通过php://filter
实现内容读取,这个技巧也是CTF中经常用到的。
最终payload是这样的:http://172.16.83.142/?page=php://filter/read=convert.base64-encode/resource=config
(注意不用加.php后缀)
base64解码出来之后的结果中果然含有数据库的信息:
同样的方法我们可以获得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
| <?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 }
|
以及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'); } } }
?>
|
通过泄露的数据库账号密码可以通过root远程登录mysql数据库:
根据提示在Users表中找到了3个账号。
密码很明显是base64编码的,解码之后得到3对账户和密码:
kent/JWzXuBJJNy
mike/SIfdsTEn6I
kane/iSv5Ym2GRo
登录系统之后直接跳转到upload界面,允许上传文件。但是通过上面我们down下来的upload.php
源码来看,上传文件是后端的白名单验证后缀,而且上传上去之后会改文件名再添加后缀。但是只是检查了imageinfo
,那可以伪造一个文件头加后缀就可以了。
就在kali自带的php webshell里挑一个php-reverse-shell.php
改一下就可以。
先加个文件头:
再把反连IP和端口改成自己的:
最后文件名加上.gif
的后缀,就可以成功上传:
Hint
但是又出现了新的问题,我们没法访问这个图片……
在网上找了一些提示之后才想起来,我们下载了config.php
,login.php
,upload.php
3个源码文件,但是还有主页的源码没看。再次利用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>
|
可以看到cookie里有个有趣的参数lang
可以实现访问任意文件:
于是利用这个漏洞触发webshell反弹shell:
可以看到利用Burp发包之后kali就接收到里反弹的shell。通过下面的命令即可转换成交互式shell。
1
| python -c '__import__("pty").spawn("/bin/bash")’
|
Exploring
现在我们已经拿到目标机器的shell,下一步就是寻找有价值的信息。在home
下发现4个用户:
尝试切换到这几个用户,kent
下什么也没有:
mike
的密码不对:
在kane
目录下找到一个奇怪的文件msgmike
:
是个可执行文件且存在setuid
,setgid
。执行发现调用了cat
命令:
接下来将cat
命令换成bash
:
通过export PATH=.:$PATH
命令修改一下系统路径PATH,再次运行msgmike
就可以得到mike
的bash:
回到mike
的目录下,有个新的msg2root
的程序,根据名字感觉是提权到root
权限的东西:
但是看起来就是简单的将输入变成输出:
联想到PwnLab
的名字,通过scp
命令将这个程序传回本地,逆向分析一下:
msg2root
逆向后的主函数伪代码如下:
其实是个很简单的程序,将输入写入到/root/message.txt
中,然后system
执行。那通过;
截断就可以绕过了。
Finished
可以看到我们已经得到了root
的权限,最后就是去根目录下读flag.txt
文件了:
完结,撒花~~