某公司网站渗透
下面都假设网址是 fake.com, 毕竟我也不能给出具体网址
账号密码以及 ip 等等, 都不是真实数据
信息收集
域名相关
首先对网站进行了 dns 解析追踪, 看看是否有负载均衡
使用命令:
dig +trace fake.com
回显结果显示无负载均衡, 一条 A 记录直接指向了 IP
同时也查到他的域名注册商是 alibaba
我使用工具搜索了这个 IP 发现是一个 aliyun 的云服务器
子域名扫瞄后发现只有 www 的子域名
当然我还不止搜集了 .com, 有 .com 可能会有 .cn 等等, 我也顺利找到了 .cn, 两个都搭建了一个网站, 这里暂且先以 .com 为目标
服务相关
这里我使用了一个端口扫瞄工具叫 RustScan
输入以下命令进行端口扫瞄:
rustscan -a fakeIP
最终只扫瞄出了两个端口
PORT STATE SERVICE REASON
80/tcp open http syn-ack
443/tcp open https syn-ack
那这里就只能从 web 的角度考虑了
网站信息收集
技术架构分析
这里用的是一个 Chrome 插件: Wappalynze
分析显示
-
PHP - 5.2.17
-
Apache
-
JQuery - 1.10.2
并没有其他有价值的信息了
目录遍历
这里用的工具是 feroxbuster, 也是一个 Rust 编写的工具
输入下面命令开始扫瞄:
feroxbuster -u test.com
这里我只扫了一点点, 没有全扫
根据扫瞄出来的路径, 通过浏览器访问之后, 出现以下页面:
这里说 404 但实际上返回的 code 是 503, 真正 404 应该是如下页面:
有一些敏感路径访问是 403, 所以我感觉上面的 503 或许真的是服务器的问题, 比如有路由但是没有对应的文件, 不过这里还是得看开发是否规范
然后我想挨个访问他顶部 bar 栏的内容, 访问第二个的时候浏览器的 url 变成了这样:
http://test.com/index.php?m=content&c=index&a=lists&catid=100
那这个 m 就很可疑, 看到 content, 我就想到应该是通过 m=content 来决定当前访问是显示内容的, 那么这个 m 也许可以控制页面, 也许是 method/model 的首字母?
那么我尝试了 m=admin 的情况, 果然, 他跳转到了管理登录页面
那这里也确定了 m 就是 model, c 是 controller
url: http://test.com/index.php?m=admin&c=index&a=login&pc_hash=
这个我们先暂且放着, 先继续收集网站信息
我将 m 改成了一个随机字符串, 网站显示如下:
这里就知道了原来 m 是控制访问哪个 controller
c 字段随意输了一个值也是 "找不到控制器", a 不用多说就是 action, pc_hash 随便输了一个暂不知道是干嘛的
翻找的时候看到 URL 的参数挺多的, 而且感觉很多可以检测是否有注点, 有很多 *id 的这种字段
到此我认为可以开始尝试注入了
漏洞检测
既然有登陆框了, 首先想到的是要检测一下有没有弱口令的
但是我想了一下, 不能先检测弱口令, 毕竟暂不清楚是否有登录限制包括账号锁定策略等等
于是我先尝试注入
注入检测
先是尝试一下登录的手工注入, 无果, 并且看样子没有 WAF
本想用 sqlmap + brupsuite 来测试, brupsuite 配置验证码识别后有问题
如果要重新写一个程序太费时间了, 还是采用手工的方式
看起来登陆没有注点, 那只能想其他的了
一般来说, 这种系统都会有记录访客, 记录 User-Agent, IP, Referer 等等信息
IP 无法控制, 于是从 User-Agent 开始
要测试这些东西就没必要在特定页面了, 在特定页面还会收到页面的限制, 所以直接在根下测试
User-Agent 字段测试无果
接下来试试 Referer 字段
直接输入一个 '
, 发现了注点:
漏洞利用
从这个报错来分析:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '1722883394','','')' at line 1
- 首先大概率是
INSERT
语句 1722883394
应该是一个时间戳, 是访问网站的时间- 从报错位置之后有三个字段
- 最后有一个括号, 应该是
VALUES()
这样的形式 - 页面报错, 可以用报错注入
还原一下 SQL 语句:
INSERT into table VALUES (v1,v2,v3,...,referer,timestamp,n1,n2)
报错是从 referer 字段开始的, 我们目前并不知道前面有多少个字段, 可以通过报错提示来补全字段, 最终得出一个是 6 个字段
构造下面的 payload 进行尝试:
'and (updatexml(1,(concat(0x7e,(select version()),0x7e)),3))and '','','','','')#
当然这里也可以不用测出字段数用另外一种, 这里就不列举了
可以看到成功获取到了版本, 似乎没有任何过滤, 于是就可以将数据全部查出来
我对感兴趣的表进行了查看
有一个叫 v9_admin 的表
结构如下:
v9_admin(
userid,
username,
password,
roleid,
encrypt,
lastloginip,
lastlogintime,
email,
realname,
card,
lang
)
这应该是管理员表, 还记得刚才的后台登录页面吗, 这里的账号密码就很有用了
查到账号密码: admin e10adc3949ba59abbe56e057f20f883 (这里并非真实查到的账号密码, 为了保密), 只有一个管理员, 公司规模本身也比较小
密码大概率是 md5
可我解密的时候发现格式不对, 这个密码是一个 31 位的 hash, 应该是截掉了一位
返回的格式是下面这样的:
XPATH syntax error: '~e10adc3949ba59abbe56e057f20f883'
这是因为长度限制, 使用 substring 函数截取到了完整密码
既然有密码了, 就可以尝试一下破解
尝试了号称最好的 hash 破解网站: https://cmd5.com/, 失败
于是我想尝试一下暴力破解, 首先我手动测试一下后台登陆, 发现有密码错误限制, 这条路也走不通了
到这里实际上是只能看到他的数据库, 并不能 getshell, 于是我想尝试其他的方法
继续信息收集
回到刚刚的地址: http://test.com/index.php?m=admin&c=index&a=login&pc_hash=
既然 m 是 model, c 是 controller, a 函数 action, 那么可以 fuzz 测试一下, 获取他有那些
先暂且不测, 刚开始没有跑完目录扫瞄, 我现在决定先跑完
扫瞄完成后的结果先存起来
由于上面检测指纹的时候没有测出框架, 但是我认为绝对用了框架, 我请教了大佬, 他说这个 url 大概率是 phpcms 的, 并且在 robots.txt 中也许可以看到框架版本和后台路径
我访问后果然有:
这下就有另外的思路了, 既然知道了框架就直接搜一下, 搜到了官网: https://www.phpcmsv9.cn/
上面的后台管理系统的开发公司是: xx科技, 搜索了一下这个公司, 这个公司的官网跟上面的是一套的, 也存在同样的问题, 不过做了相应措施, 这次的目标不是这个
漏洞查找
既然知道了用的什么框架了, 那直接搜索对应漏洞, 搜索引擎结合各大漏洞库搜索
由于只知道是 phpcms v9, 并不知道具体版本, 只能尽量全搜出来一个一个试
找到任意文件读取, 任意文件上传, 和一个与我这个不一样的 sql 注入漏洞, 漏洞先放在这里
还记得刚刚无法解密的密码吗, 既然有了源码, 那就可以看到如何加密, 就有机会解密了
在 admin 的 login函数中:
$password = md5(md5(trim((!isset($_GET['card']) ? $_POST['password'] : $_SESSION['card_password']))).$r['encrypt']);
通过把密码进行一次 md5 后加盐再进行 md5:
md5(md5($pass).$salt)
通过 SQL 注入, 我们拿到了 encrypt 字段, 这里假设为 ABCD
我觉得到这里就算是渗透结束了, 密码算是已经破解
上面还找到了其他漏洞, 接下来我们验证一下
漏洞验证
任意文件上传
我对任意文件上传比较感兴趣, 先试试这个
这个漏洞是 m=member, 用户注册功能的漏洞
当我测试的时候我发现, 目标公司是直接关掉注册功能的, 这个漏洞无法利用
任意文件读取
同样无法利用
漏洞挖掘
既然现有的漏洞无法利用, 那就只能自己挖了, 由于没有这个系统的源码, 只能尝试挖挖 phpcms 的漏洞