Xman资格选拔赛-web

variacover

这道题一打开就是源码,主要就是根据源码构造url。其中,它接收的参数只有b,但源码中要获取flag的关键参数是a[0]parse_str()函数的做用是把查询字符串解析到变量中,因而咱们能够经过将a[0]嵌入b的传参中,而后由这个函数再将a[0]提取出来,解析出a[0]后,还须要知足其值是MD5加密后与MD5('QNKCDZO’)的值相等,但加密前的字符串不相等,由于QNKCDZOMD5匹配很常见,在网上就能够搜到,或者也本身写个脚本暴破,之因此会存在这种状况,是由于PHP的弱性质,字符串QNKCDZO经MD5加密后的密文是0e830400451993494058024219903391,而php在作hash比较时,会将0e\d+这类字符串解析成科学计数法,所以若两个不一样的字符串经MD5加密后的密文为0e\d+类型则比较相等,一样的0e\d+类密文和0比较也是相等的。故最后构造以下payload?b=a[0]=240610708php

urldecode

一开始的提示很明显,首先尝试get方式传一个me的参数,页面会返回下一条提示:json

 

因而更改传参的值为XMAN后,页面返回great,查看源码可得提示:数组

因而立马想到的是url的二次加密,将XMAN作两次url加密可得浏览器

之因此会想到二次加密是由于,urldecode()url解密函数,字符串XMAN不可能作解密,那么最大的可能就是将二次加密的参数传到服务端,经服务端作了一次解密后,绕过检测,获取信息url信息XMAN,因而paylaod以下:服务器

unserialize

从题目信息能够知道这是一道php反序列化的题,一开始仍是跟着题目的提示作,随便传入一个参数code,获得提示flag.php,因而访问这个php页面,获得提示help.php,接着访问help.php获得最终的提示:函数

看这段代码的意思是读入filename文件的内容而后返回,filename的初始值是’error.log’,因而想到能够改为flag.php,试了下,最后是在./index.php页面,将php反序列化的代码做为code的值上传,最后的payload以下:学习

PHP

这道题一打开就是一片空白,很明显是源码泄露了,随手一试就爆出源码了:加密

这里有点浏览器的兼容问题,firefox上显示的源码不全,可是chorm上能够显示完整的源码:url

<?phpspa

$a=0;

$b=0;

$c=0;

if (isset($_GET['aaa']))

{

        $aaa = $_GET['aaa'];

$aaa=="1"?die("Emmm..."):NULL;

        switch ($aaa)

        {

        case 0:

        case 1:

                $a=1;

                break;

}

}

$bbb=(array)json_decode(@$_GET['bbb']);

if(is_array($bbb)){

    is_numeric(@$bbb["ccc"])?die("Emmm..."):NULL;

    if(@$bbb["ccc"]){

        ($bbb["ccc"]>2017)?$b=1:NULL;

    }

if(is_array(@$bbb["ddd"])){

        if(count($bbb["ddd"])!==2 OR !is_array($bbb["ddd"][0])) die("Emmm...");

        $eee = array_search("XMAN", $bbb["ddd"]);

        $eee===false?die("Emmm..."):NULL;

        foreach($bbb["ddd"] as $key=>$val){

            $val==="XMAN"?die("Emmm..."):NULL;

        }

        $c=1;

}

}

if($a && $b && $c){

    include "flag.php";

echo $flag;

}?>

因而根据源码的意思,须要上传两个参数aaabbb,最后拿到flag的条件是知足代码中的一些规则,使得a,b,c三个变量都为1。这道题主要考的是php的弱性质,其中,aaa的判断用的是==,须要使aaa为数字1,根据phpGET或者是POST的参数转换为int类型,或者是两个变量不匹配的时候,会自动地进行变量转换,能够用aaa=1a传参,且phpswicth有一个特色,当它是数字类型的case的判断时,switch会将其中的参数转换为int类型,故$a=1这里就实现了

而后是ccc的传参,不能为整数或整数型字符串,但其值要大于2017,和前面的道理同样,传2018a就能够了,因而$b=1就达成了。最后是ddd的构造,bbbddd还有ddd[0]均要为数组,这里因为json_decode(@$_GET['bbb'])bbb自动就是数组了

还要知足ddd的每个元素都不为’XMAN’,且array_search("XMAN", $bbb["ddd"])函数返回的键名要为’XMAN’,这看起来有点矛盾,但其实也是一个php的弱特性,phparray_search()函数和in_array()都存在一个问题,若是strict参数没有提供,那么这两个函数就会使用松散比较来判断第一个参数是否在第二个数组参数中。当strince的值为true时,函数会比较两个参数的类型是否相同,而用来比较的’XAMN’又会转化成0,因而咱们能够构造以下的payload:

Welcome2IRC

这道题根据题目irc就知道,多半是要下载什么客户端,题目的提示也很明显,一个不能打开的地址,还有“欢迎加入#XMAN”,因而,果断去下了一个irc的客户端,注册后用/server 202.112.51.184:6667链接服务器,而后join#XMAN,就看到flag了:

CTF用户登陆

尝试了下基本的注入,发现字符串注入可行

可是过滤了空格、加号和逗号,由于他的登陆结果都是有明确的结果回显,因此首先想到了bool盲注,这里的绕过仍是很常见的,用括号代替空格,屏蔽符号用#,逗号用for循环代替,因而以下初步的一个paylaod

而后就是写脚本跑flag,先爆库名:

uaername=admin'and(select(length(database()))=4)#&password=admin&submit=

uaername=admin'and(ascii(mid(database()from(%d)for(1)))>0)#&password=admin&submit=

表名:

这里过滤了逗号,limit 0,1能够用limit 1 offset 0代替,可是很狗血的是空格也过滤了,limit 1 offset 0不能用limit(1)offset(0)代替,因而想到group_concat(),嗯,成功注出表名:

admin'and(ascii(mid((select(group_concat(table_name))from(information_schema.tables)where(table_schema='xman'))from(%d)for(1)))=%d)#

 

字段名:

admin'and(ascii(mid((select(group_concat(column_name))from(information_schema.columns)where(table_name='ctf_flags'))from(%d)for(1)))=%d)#

Ctf_users的:

Ctf_flags的:

比赛方是个坑逼,flagctf_users表的gpass字段ctf_flags表的ggflag字段里都有:

admin'and(ascii(mid((select(group_concat(ggflag))from(ctf_flags))from(%d)for(1)))=%d)#

ctf_users的flag:

ctf_flags里的经Base64解密后是:

 

然而这是个错的。。通常谁会去注意看,按照他的提示在ctf_users里找到正确的flag

ctf_users里的解密后是:

 

------------------------------------------------------------------------------------------------------------------------

看了官方的wp,不想说话,很迷啊这道题

官方的说法是这道题是不用写脚本的,也不是什么bool盲注(我选择狗带),就是让大家花式绕过滤简单的注一下,而后莫名其妙的在登陆成功后访问一下index.php(黑人问号.jpg),关于index.php一点提示也没有,一点逻辑也没有,可是flag就出来了【摊手】,如图:

好吧,这种神逻辑暂且不说,可是wp仍是有值得学习的地方,好比,用%0a或%0b代替空格,用join代替逗号,双引号能够转换成16进制,join这种方法第一次见,嗯,学习了

未完待续...

相关文章
相关标签/搜索