- Mark loves cat
- 考点
- wp
- 方法1
- 方法2
- Cookie is so stable
- 考点:
- Twig模板注入
- wp
- The mystery of ip
- 考点:
- wp
- smarty的模板学习
- 对模板注入的判别
- EasySearch
- 考点
- EzPHP
- 考点
- wp
- 1.主页
- 2. 绕过$_SERVER['QUERY_STRING']
- 3.绕过preg_match
- 常见绕过preg_match的方法
- 4.绕过$_REQUEST的字母匹配
- $_REQUEST的一些小特性
- $_REQUEST使用不当绕过WAF
- 漏洞代码
- $_REQUEST导致的HPP漏洞
- 漏洞代码
- 5. file_get_contents绕过
- 常见的绕过方式
- 6.sha1强比较绕过
- 7.create_function()注入
- 8.出flag
GitHack泄露,$$
变量覆盖
变量覆盖的介绍
wp利用GitHack获取源码
index.php
比较简单的代码,需要满足password的md5值的前六位要等于6d0bc1
直接写脚本
import hashlib
for i in range(1000000000):
a = hashlib.md5(str(i).encode('utf-8')).hexdigest()
if a[0:6] == '6d0bc1':
print(i)
print(a)
随便登陆一下
看到返回了内容写进去的文件路径
有个shtml
,想到Apache SSI 远程命令执行漏洞,参考https://cloud.tencent.com/developer/article/1540513
直接命令执行
查flag也是一样的
EzPHP 考点- 绕过QUERY_STRING的正则匹配
- 绕过preg_match
- 绕过$_REQUEST的字母匹配
- file_get_contents绕过
- sha1强比较绕过
- create_function()注入
F12,有个编码,但是不是base64
,是base32
,这个比较少见了。
解码后直接访问URL/1nD3x.php
得到代码,好多过滤,确实有点麻
This is a very simple challenge and if you solve it I will give you a flag. Good Luck!
fxck you! I hate English!
一步一步来绕过
2. 绕过$_SERVER[‘QUERY_STRING’]if($_SERVER) {
if (
preg_match('/shana|debu|aqua|cute|arg|code|flag|system|exec|passwd|ass|eval|sort|shell|ob|start|mail|\$|sou|show|cont|high|reverse|flip|rand|scan|chr|local|sess|id|source|arra|head|light|read|inc|info|bin|hex|oct|echo|print|pi|\.|\"|\'|log/i', $_SERVER['QUERY_STRING'])
)
die('You seem to want to do something bad?');
}
对URL的解析
url: http😕/127.0.0.1/aaa/index.php?m=222&n=333
$_SERVER[‘QUERY_STRING’] = “m=222&n=333”; $_SERVER[‘REQUEST_URI’] = “/aaa/index.php?m=222&n=333”; $_SERVER[‘SCRIPT_NAME’] = “/aaa/index.php”; $_SERVER[‘PHP_SELF’] = “/aaa/index.php”;
绕过利用点:
$_SERVER['QUERY_STRING']
在读取url时并不会对url进行解码,而$_GET['x']
是会自动进行url解码的,所以我们要把可能出现在黑名单的字符串进行url编码后再传入,就可以绕过。
1.%0A绕过 类似于preg_match("/^.*flag.*$/",$cmd)
这种的正则匹配,默认只匹配第一行 ?cmd=%0acat flag
即可绕过
2.PCRE回溯次数限制绕过 当正则匹配回溯次数超过上限时将返回false
3.数组绕过 preg_match只能处理字符串,当传入的是数组时将会返回false。
if (!preg_match('/http|https/i', $_GET['file'])) {
if (preg_match('/^aqua_is_cute$/', $_GET['debu']) && $_GET['debu'] !== 'aqua_is_cute') {
$file = $_GET["file"];
echo "Neeeeee! Good Job!";
}
} else die('fxck you! What do you want to do ?!');
这儿首先对file
的值判断,不能有http
和https
preg_match('/^aqua_is_cute$/', $_GET['debu'])
要求debu的值满足正则/^aqua_is_cute$/
,^和$
用来表示开头和结尾 $_GET['debu'] !== 'aqua_is_cute'
要求debu的值不能强等于'aqua_is_cute'
。
所以这儿,我们采用换行符%0a
绕过就可以了。构造
deb%75=aq%75a_is_c%75te%0a
4.绕过$_REQUEST的字母匹配
if($_REQUEST) {
foreach($_REQUEST as $value) {
if(preg_match('/[a-zA-Z]/i', $value))
die('fxck you! I hate English!');
}
}
$_REQUEST
包括所有以cookie,post或者get方式传入的变量,如果含有字母则无法通过,但我们所有的参数构造都离不开字母。
一个$_REQUEST
特性,优先级:cookie>post>get
所以get传入变量后,再用post方式传入数字值进行覆盖即可。
$_REQUEST的一些小特性 $_REQUEST使用不当绕过WAFphp手册上面对于$_REQUEST
的说法是:
由于 $_REQUEST 中的变量通过 GET,POST 和 COOKIE 输入机制传递给脚本文件,因此可以被远程用户篡改而并不可信
$_REQUEST
是直接从GET,POST 和 COOKIE中取值,不是他们的引用。即使后续GET,POST 和 COOKIE
发生了变化,也不会影响$_REQUEST
的结果。如下:
foreach ($_REQUEST as $key=>$value) {
$_REQUEST[$key] = md5($value);
}
var_dump($_REQUEST);
var_dump($_GET);
可以看到$_REQUEST
的结果发生了改变,但是$_GET
的结果并没有改变
代码显示
foreach ($_REQUEST as $key=>$value) {
$_REQUEST[$key] = waf($value);
}
if(isset($_POST['submit'])) {
$id = $_POST['id'];
$sql = "select * from user where id=$id";
mysql_query($sql);
//....
}
虽然使用了waf
进行过滤,但是waf过滤的是$_REQUEST
,在业务代码中使用的是$_POST
。这样就导致前面的WAF过滤没有任何的作用,防护完全失效。
1.php自身在解析请求的时候,如果参数名字中包含空格、.
、[
这几个字符,会将他们转换成_
。测试如下:
2.php在遇到相同参数时接受的是第二个参数。
这个就不用测试了。
3.通过$_SERVER['REQUEST_URI']
方式获得的参数并不会进行转换
代码
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?