SSRF

SSRF
LuooU介绍
SSRF(Server-Side Request Forgery),服务端请求伪造,是通过构造形成由服务器端发起请求的一个漏洞,可以以此访问外网无法访问的内网系统。
一般SSRF会出现在以下场景中:
- 能够对外发起网络请求的场景。
- 从远程服务器请求资源的场景(Upload from URL,Import & Export RSS Feed)。
- 数据库内置功能(Oracle、MongoDB、MSSQL、Postgres、CouchDB)。
- Webmail收取其他邮箱邮件(POP3、IMAP、SMTP)。
- 文件处理、编码处理、属性信息处理(ffmpeg、ImageMagic、DOCX、PDF、XML)。
常见的后端实现
file_get_contents():
1 |
|
这段代码从用户指定的url中获取图片,然后写入一个路径随机的文件中,最后显示该图片。
rand()函数返回伪随机整数。
语法:
rand(min,max).
file_put_contents()函数将字符串、数组或数据流写入文件。
用法:
- 如果设置了 FILE_USE_INCLUDE_PATH,那么将检查 filename 副本的内置路径
- 如果文件不存在,将创建一个文件
- 打开文件
- 如果设置了 LOCK_EX,那么将锁定文件
- 如果设置了 FILE_APPEND,那么将移至文件末尾。否则,将会清除文件的内容
- 向文件中写入数据
- 关闭文件并对所有文件解锁
fsockopen():
1 |
|
从fsockopen开始建立与指定host的连接,再通过fwrite()对$fp写入$out内容($out即为请求头),向host发送请求头,使用$contents储存响应头和响应体,最后返回$contents内容。
但是因为host是用户指定,所以也存在SSRF漏洞。
fsockopen即file socket open。
套接字(socket)是一个抽象层,应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开、读写和关闭等操作。套接字允许应用程序将I/O插入到网络中,并与网络中的其他应用程序进行通信。网络套接字是IP地址与端口的组合。
简单理解,
Socket给每个应用程序提供了一个唯一的入口(ip:端口)便于发送和接收数据。
fsockopen()函数可以打开Internet或者Unix套接字连接,连接到指定hostname资源。用法:
1
2
3
4
5
6
7 fsockopen(
string $hostname,
int $port = -1,
int &$error_code = null,
string &$error_message = null,
?float $timeout = null
): resource|false然后就可以把由fsockopen返回的句柄当成文件进行读写,写入即发送请求。
curl_exec():
1 |
|
这段代码使用curl获取用户指定url的数据,将数据放到伪随机文件名的文件中。
关于
curl:
curl(Client URL)是一个强大的命令行工具,用于在 Linux/Unix 系统中传输数据,支持HTTP、HTTPS、FTP、SFTP等协议。语法如下:
1 curl [options] [url]
options可选的多种参数,包括:
参数 说明 示例 -X 指定HTTP方法 curl -X POST http://… -d 发送POST数据 curl -d “key=a” http://… -G 将-d数据作为GET参数发送 curl -G -d “key=a” http://… -H 添加请求头 curl -H “Content-Type=application/json” http://… -o 将输出保存到文件 curl -o output.txt http://… -O 使用远程文件名保存 -L 跟随重定向 -I 只获取头部信息 -c 保存服务器返回的Cookie curl -c cookies.txt -b cookies.txt http://… -b 发送存储的Cookie curl -c cookies.txt -b cookies.txt http://… -F 用于multipart/form-data类型的表单提交 curl -F “file=@localfile.txt” http://… -v 显示请求 -i 只显示响应头 带
JSON数据的请求:
1
2
3 curl -X POST -H "Content-Type: application/json" \
-d '{"name":"John","age":30}' \
https://api.example.com/users测试网站响应时间:
1 curl -o /dev/null -s -w "Connect: %{time_connect} TTFB: %{time_starttransfer} Total: %{time_total}\n" https://example.com使用代理服务器:
1 curl -x http://proxy.example.com:8080 https://target.com
php中的cURL:
需要引入
libcurl包。
函数 描述 用法 curl_init() 初始化一个curl会话 curl_setopt() 设置一个curl传输选项 bool curl_setopt ( resource $ch , int $option , mixed $value ) curl_exec() 执行一个curl会话
curl_setopt()中$option说明
参数 描述 CURLOPT_POST 启用时发送一个常规的POST请求,类型为 application/www-form-urlencoded。CURLOPT_URL 设置需要获取的URL,也可以在 curl_init()中设置。CURLOPT_RETURNTRANSFER 将 curl_exec()返回的信息以文件流的形式而不是纯文本的形式输出。
对应值为true,curl_exec()返回的信息才可以用变量接收。
curl_setopt()中$value说明:0为false,1为true。false代表关闭功能,true代表打开功能。
有时候需要对功能进行显式设置,因为功能的默认值可能不合预期。



