NCTF-2019

 · 2019-11-25 · 次阅读


MISC
1.a_good_idea
  下载后是一个TOM猫的图片,用foremost分离,可以得到jpg和zip,zip解压后有两张tom猫图片,用wenhex打开会发现它们的十六进制有所不同,还有一个hint.txt提示秘密在像素中,猜测可能要将两张图片综合或是比较,这里使用Beyond Compare这个工具可以直接比较两个的区别并进行合并处理,如下图所示:

扫描二维码即可得到flag

2.pipinstall
 &emps;先进入linux下下载题目所给pip,

pip install --user nctf-2019-installme

在下载过程中会给出一个链接,我们在windows下打开那个链接,
然后会下载一个压缩包,打开后会有一个setup.py文件,用记事本打开后有一段奇怪的像BASE64的一段字符串,解码即可拿下flag.

Web
两道XML的XXE在XXE文章中写了WP了,故这里不写了,下面写一下其他题的WP。

1.Upload your Shell
  一进入这个花哨的界面,就看见头像那个向黑客致敬的表情包,点击它,跟换头像即可上传图片,找到上传点。接下来使用BP抓包,并上传一个一句话木马试试。虽然上传了个1.jpg,内容为:

GIF98a<script language="php">system("Is")</script>

就得到了一个上传路径,访问一下,给出了如下提示:

<script language="php">
eval(system('cat /flag'));
</script>

回到页面,发现访问路径采用的是action=文件,那么我们直接访问

filepath:/var/www/html/upload-imgs/0b5b907c20528edfadb855745911f998/Th1s_is_a_fl4g.jpg

这个路径。访问这个页面便拿到了flag:NCTF{upload_1s_s0_funn7}
.这里我们需要掌握其访问页面的规则,这个页面是用$_GET[‘action’]或者是$_REQUEST[‘action’] 这样定义的变量来充当访问文件的路径的,于是,我们在访问最后flag路径的时候不是直接在地址栏中输入路径,而是采用这个action变量去访问。
  summary:这道题考点挺简单的,就只考了文件的内容中不能包括’<?’这样的成分,并且文件头要以图片类的开头,这里我使用了gif的GIF98a开头来绕过,这里并没有让我们上传真正的一句话木马,因为最终上传的任然只是一个jpg文件,可能只是让我们学习一下上传绕过文件内容的检测吧。
2.easy_php
  这是一道代码审计题目,下面粘贴出代码:

<?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');
}


//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??????');
}


//3rd
$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');
}
?> 

这里要满足三个条件,也就是get提交三个合法参数就会给flag,我们一一来构造,第一个要让num的值不为23333但正则匹配又必须为23333,这不是难为我吗,但我知道这个preg_match是可以绕过的,在仔细搜索了各种资料后查到%0a是换行符‘\n’的URL编码,这里使用%0a可以绕过第一个条件。因为在它匹配的时候,由于换行了,所以匹配第一行成功,但实际上我们输入的num又不为23333故绕过了第一个条件。

接下来构造第二个条件,这里先温习一下strtr这个函数的用法,给出一个例子

<?php
echo strtr("Hilla Warld","ia","eo");
?>

这里输出为Hello warld,也就是在第一个参数里面搜索第二个参数的内容,如果有就替换为第三个参数。这里我们知道md5函数处理不了数组,因而构造str1[]与str2[]可满足其相等,但这里反过来了,先让其md5不相等,再让他们两个经过strtr处理过后的值相等,这里采用寻找md5后为0e的数字即可满足条件,

$b=2120624;
    $a=240610708;

上面两个变量刚好就是满足条件的,但是为什么他们俩的md5值不相等呢,

接下来是第三个条件,构造q.w.q=tac%20f*,这里的下划线可以直接用.绕过,这是什么原理,在笑师傅的帮助下,理解到了,在PHP中有这么一个规则,变量名中是不允许有.和空格的,如果存在就会被转换成下划线
这里记录一下tac命令是从最后一行倒叙显示内容,并将所有内容输出,跟cat命令刚好相反,cat是由第一行开始显示内容,并将所有内容输出.这里可以使用l${x}s绕过这里的判断条件依然可以执行ls命令,原理看下面的例子:

$str = 'l${x}s';

这个输出为ls,原因是$x会解析为一个变量,加上{}是为了分界,解析为$x而不是$xs变量,然后由于$x变量不存在,故其为null,然后整个字符串最后结果为ls.{}还可以表示字符串的下标例如一个字符串$str{1}代表其第二个字母。
最后拿下flag:NCTF{t3is_So_siiimpppllleeee_to_u}