# picoCTF Cryptography # Easy ## hashcrack ![image](https://hackmd.io/_uploads/B1NpvEuaJe.png) https://crackstation.net/ ![image](https://hackmd.io/_uploads/H1x0PEua1g.png) ## 13 ![image](https://hackmd.io/_uploads/BkST1Kqa1l.png) rot13 online decode https://cryptii.com/pipes/rot13-decoder ![image](https://hackmd.io/_uploads/HyAJeK5aye.png) # Medium ## rotation ![image](https://hackmd.io/_uploads/Skumz1MHJe.png) Hints : Sometimes rotation is right encrypted.txt ![image](https://hackmd.io/_uploads/rJfUM1MHke.png) 說了 sometimes rotation 會對 那就用 rot13 bruteforce 試試看 https://gchq.github.io/CyberChef ![image](https://hackmd.io/_uploads/ryN3MJzH1l.png) ## HideToSee ![image](https://hackmd.io/_uploads/BkryHX7HJe.png) 用`steghide`找出秘密訊息 ``` steghide extract -sf atbash.jpg ``` ![image](https://hackmd.io/_uploads/S1oBLQQrJl.png) 看了一下圖片的檔名 atbash https://blog.csdn.net/weixin_43211186/article/details/123703113 以下破爛的script ```python= path = 'encrypted.txt' f = open(path, 'r') ar_1 = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M','N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X','Y','Z'] ar_2 = ['z','y','x','w','v','u','t','s','r','q','p','o','n','m','l','k','j','i','h','g','f','e','d','c','b','a'] ans = '' def is_digit(char): ascii = ord(char) if ascii >= ord('0') and ascii <= ord('9'): return True else : return False def convert_char(char): if(char.isupper()): return char.lower() else: return char.upper() while 1: char = f.read(1) a1_len = len(ar_1) a2_len = len(ar_2) if not char: break if char == '}' or char == '{' or char == '_' or is_digit(char): ans = ans + char if char.isupper(): for i in range(a1_len): if char == ar_1[i]: ans = ans + convert_char(ar_2[i]) break else: for i in range(a2_len): if char == ar_2[i]: ans = ans + convert_char(ar_1[i]) break print(ans) f.close() ``` ## ReadMyCert ![image](https://hackmd.io/_uploads/ryJ7QY4Hyg.png) ``` echo "<text>" | base64 -d ``` 這樣就結束了= = ![image](https://hackmd.io/_uploads/BJfcmYNrye.png) ## Vigenere ![image](https://hackmd.io/_uploads/BJbwCLSrJe.png) Vigenere https://ithelp.ithome.com.tw/articles/10288227?sc=rss.iron 就是假設今天有一個key是DOG 假設明文是MUWL 密文就是PICO ![image](https://hackmd.io/_uploads/SkOtlPrBJl.png) (https://upload.wikimedia.org/wikipedia/commons/thumb/2/25/Vigen%C3%A8re_square.svg/450px-Vigen%C3%A8re_square.svg.png) 我超懶得寫matrix,直接找有沒有online工具 ![image](https://hackmd.io/_uploads/BJ0TePSrJl.png) ## transposition-trial ![image](https://hackmd.io/_uploads/H1f_khBBJl.png) ![image](https://hackmd.io/_uploads/SkvqJnSB1g.png) 仔細觀察可以發現他是三個為一組去選轉的 ```python= f = open("message.txt", "r") message = f.read() ans = "" for i in range(0,len(message),3): ans = ans + message[i+2] + message[i] + message[i+1] print(ans) ``` ![image](https://hackmd.io/_uploads/SyVkg2BSye.png) ## basic-mod1 ![image](https://hackmd.io/_uploads/ryp_WbDBkx.png) number mod 37 = ans ans 0~25 => 大寫alphabet ans 26~35 => 數字 `0~9` ans 36 => 底線 `_` 白癡的暴力破解 ```python= apl = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','0','1','2','3','4','5','6','7','8','9','_'] f = open("message.txt","r") f = f.read().split() ans = "" for num in f: ans = ans + apl[int(num) % 37] print(ans) ``` ![image](https://hackmd.io/_uploads/BkkEG-PHJx.png) ## substitution0 ![image](https://hackmd.io/_uploads/H166zJj8yg.png) 簡單還說就是每個字母被替換成不同的字母 online crack substitution 工具 - https://planetcalc.com/8047/ ![image](https://hackmd.io/_uploads/BJ0zmks81e.png) ## Easy1 ![image](https://hackmd.io/_uploads/B13JctGuJe.png) Hints 1. Submit your answer in our flag format. For example, if your answer was 'hello', you would submit 'picoCTF{HELLO}' as the flag. 2. Please use all caps for the message. table ![image](https://hackmd.io/_uploads/B17F3YzO1x.png) https://www.dcode.fr/vigenere-cipher ![image](https://hackmd.io/_uploads/B1As3Ff_yg.png) ## la cifra de ![image](https://hackmd.io/_uploads/BJtei55pJl.png) Hints: 1. There are tools that make this easy. 2. Perhaps looking at history will help 完全不知道這是什麼 有一個好用的線上工具https://www.dcode.fr/cipher-identifier ![image](https://hackmd.io/_uploads/SJJ8jc5a1g.png) 選過Jefferson了,沒什麼鳥用 所以才要選Vigenere Cipher ![image](https://hackmd.io/_uploads/Skeus5qpkx.png) ![image](https://hackmd.io/_uploads/Sy6Z2qca1e.png) ## john_pollard ![image](https://hackmd.io/_uploads/ByzIuj5Tyx.png) 題目是要我們求出 `p` 和 `q` 這會顯示憑證內的RSA模數 `N(Modulud)` 、指數 `e(Exponent)` 等資訊 ``` openssl x509 -in cert -noout -text ``` ![image](https://hackmd.io/_uploads/SyI-Fi9aJe.png) N = p * q online tool https://www.alpertron.com.ar/ECM.HTM ![image](https://hackmd.io/_uploads/Hk4TFj5pyx.png) ## Tapping ![image](https://hackmd.io/_uploads/HkLWO2oTkl.png) 很明顯這就是flag,可是不知道是用什麼轉的 ![image](https://hackmd.io/_uploads/rk5S_2jayg.png) 老樣子用線上工具https://www.dcode.fr/cipher-identifier ![image](https://hackmd.io/_uploads/B1nt_hjp1l.png) ![image](https://hackmd.io/_uploads/ryicdhipke.png) ## Flags ![image](https://hackmd.io/_uploads/BkBsWaja1x.png) 真的不知道這是什麼 ![image](https://hackmd.io/_uploads/r1n3Z6jpJx.png) 但好像是什麼International maritime signal flags https://en.wikipedia.org/wiki/International_maritime_signal_flags 對應的flag的內容得下來是picoCTF{F1AG5AND5TUFF} ## Pixelated ![image](https://hackmd.io/_uploads/SyFN1AiTJx.png) Hint:https://en.wikipedia.org/wiki/Visual_cryptography 第一個hint蠻有用的,直接跟我們說兩張圖片合在一起就會得出答案了 但我不知道則麼寫script 就看了別人的script 參考script https://medium.com/@alireza.ghorbani/pixelated-picoctf-write-up-0b767d322256 方便看flag ```python= import cv2 import numpy as np # 讀取圖片 image = cv2.imread("combined_image.png") # 取得第一個像素的 BGR 顏色 (左上角的像素) reference_color = image[0, 0] # BGR 格式,例如 [255, 255, 255] # 建立遮罩,找出所有顏色與 reference_color **不同** 的像素 mask = np.any(image != reference_color, axis=-1) # 將不同的像素變黑 image[mask] = [0, 0, 0] # 黑色 (BGR 格式) # 顯示結果 cv2.imshow("Modified Image", image) cv2.imwrite("modified_image.png", image) cv2.waitKey(0) cv2.destroyAllWindows() ``` ![image](https://hackmd.io/_uploads/B1m4GAi61l.png) ## No Padding, No Problem ![image](https://hackmd.io/_uploads/r11t3DWRJg.png) 這是RSA,他們給了n、e和密文,然後要求我們給密文 ![image](https://hackmd.io/_uploads/SkheSdWRkx.png) 這題是同態乘法https://blog.csdn.net/weixin_45732058/article/details/134701552 `c = encrypt(m1) * encrypt(m2) = (m1 * m2)**e mod n` ```python= n = 123033154142956375809145321968129110366801132346977429685516857055365915397596831945366373655492805705093442890582623150874354734529231998609747396076661639260509590648708415966479626490250697483239276971780517874543260169762726811017430033268019120839534925004765493087466131706987833562136303083635841505391 e = 65537 c = 113375312785312846498554885116109142235392583719849114629008226030433434049965790829258233844262947846633286824914354955402384367036914126840296848782735806968563472550454519009243161264393670388952321801117132924285348056400610104924336185297866509487150599209416794461334783106289490823038578834478718518630 C = c * pow(2,e,n) print(C) ``` ![image](https://hackmd.io/_uploads/HJ4AUuWRyg.png) ![image](https://hackmd.io/_uploads/B1m1vuWCJg.png) ```python= m = 580550060391700078946913236734911770139931497702556153513487440893406629034802718534645538074938502890769138695361576199930 // 2 print(bytearray.fromhex(format(m,'x')).decode()) ``` ![image](https://hackmd.io/_uploads/B1xfwuZCke.png) ### 參考資料 https://github.com/Dvd848/CTFs/blob/master/2021_picoCTF/No_Padding_No_Problem.md ## caesar ![image](https://hackmd.io/_uploads/Hycqj8fRyg.png) ![image](https://hackmd.io/_uploads/Hk1t38G0Jg.png) ![image](https://hackmd.io/_uploads/BJLYC8MRJx.png) 隨便找了一個就種了 ## Dachshund Attacks (給e,n,c,沒給d) ![image](https://hackmd.io/_uploads/S1IhRc70Je.png) 給你 `e` , `n` , `c` 找出 `d` 求原始 `m` 訊息,然後題目還說 d 很小 ![image](https://hackmd.io/_uploads/HkAaR97A1g.png) Wiener's attack 剛好很符合這種情境[Link](https://en.wikipedia.org/wiki/Wiener%27s_attack) 這是這次會用的工具[Link](https://github.com/orisano/owiener) ```python= import owiener e = 24070585963676396836339119266074703631185325935901189976168439494148908568883163639040881970864431071510706853330983669428476562226661829372537697061459642062617336502737377038994047110849464357038658515902223404277927962245162588048036291814862109832747007143611417263619840106713518659058284264465041722951 n = 95246584314953397407160275991257531467183830580341253761818147315002203507825362017580084590210871948611599502817077874354664828546692250382900296034897690562884298340554582412454992941152823190796153149129497355855115547660543312021536216041346041303448157290972055701372662074181708365081208553211022882613 c = 67167396016728997746500326256589576553572112836662193935563088920677217504276174652365331741926389277431344437388449368796787899498526394747629741042218209607396252911411090413367230889577269436192931791260875486687824664397137843532884404551172386541834991123990618786334183009849587435237181262215694200634 d = owiener.attack(e,n) if d is None: print("Failed") else: print("Hacked d={}".format(d)) m = pow(c,d,n) print(f"m : {bytearray.fromhex(format(m,'x')).decode()}") ``` ![image](https://hackmd.io/_uploads/S1lIliQRyl.png) ## Mini RSA (給n,e,c,但e很小) ![image](https://hackmd.io/_uploads/S1QXYJERkg.png) ![image](https://hackmd.io/_uploads/SkdvakNCkg.png) 這題就是RSA `e` 太小的話,會發生什麼問題?要則麼破解 RSA encrypt公式: ![image](https://hackmd.io/_uploads/Bk8-qk4Rkx.png) ![image](https://hackmd.io/_uploads/SylAckVCkl.png) 所以只要找到一個整數x,讓C+N*x == M**e,然後就可以開e次根求出M 所以x可以從0~100xx來猜 ```python= from sympy import integer_nthroot N = 1615765684321463054078226051959887884233678317734892901740763321135213636796075462401950274602405095138589898087428337758445013281488966866073355710771864671726991918706558071231266976427184673800225254531695928541272546385146495736420261815693810544589811104967829354461491178200126099661909654163542661541699404839644035177445092988952614918424317082380174383819025585076206641993479326576180793544321194357018916215113009742654408597083724508169216182008449693917227497813165444372201517541788989925461711067825681947947471001390843774746442699739386923285801022685451221261010798837646928092277556198145662924691803032880040492762442561497760689933601781401617086600593482127465655390841361154025890679757514060456103104199255917164678161972735858939464790960448345988941481499050248673128656508055285037090026439683847266536283160142071643015434813473463469733112182328678706702116054036618277506997666534567846763938692335069955755244438415377933440029498378955355877502743215305768814857864433151287 c = 1220012318588871886132524757898884422174534558055593713309088304910273991073554732659977133980685370899257850121970812405700793710546674062154237544840177616746805668666317481140872605653768484867292138139949076102907399831998827567645230986345455915692863094364797526497302082734955903755050638155202890599808147130204332030239454609548193370732857240300019596815816006860639254992255194738107991811397196500685989396810773222940007523267032630601449381770324467476670441511297695830038371195786166055669921467988355155696963689199852044947912413082022187178952733134865103084455914904057821890898745653261258346107276390058792338949223415878232277034434046142510780902482500716765933896331360282637705554071922268580430157241598567522324772752885039646885713317810775113741411461898837845999905524246804112266440620557624165618470709586812253893125417659761396612984740891016230905299327084673080946823376058367658665796414168107502482827882764000030048859751949099453053128663379477059252309685864790106 e = 3 for x in range(10000): candidate = c + x * N m, exact = integer_nthroot(candidate, e) if exact: print(f"Found! M = {m}, x = {x}") break print(f"m : {bytearray.fromhex(format(m,'x')).decode()}") ``` ![image](https://hackmd.io/_uploads/HyJ42k4R1g.png) ## basic-mod2 ![image](https://hackmd.io/_uploads/ByfsVeVCJl.png) message.txt ``` 268 413 438 313 426 337 272 188 392 338 77 332 139 113 92 239 247 120 419 72 295 190 131 ``` ### modular inverse ![image](https://hackmd.io/_uploads/rkRxBeECke.png) ![image](https://hackmd.io/_uploads/BJRbBlN0ye.png) ### 怎麼求 inverse modulo? ```python= x = pow(a,-1,m) # 求 a 在 mod m 下的模反元素 ``` ----- ```cpp= path = 'message.txt' with open(path) as f: content = f.read() number_list = [int(num) for num in content.strip().split()] print(number_list) alpha = '0abcdefghijklmnopqrstuvwxyz0123456789_' for i in range(len(number_list)): # print(i) mod_inverse = pow(int(number_list[i]),-1,41) print(alpha[mod_inverse],end="") # print(alpha[number_list[i]%41],end='') ``` ![image](https://hackmd.io/_uploads/Syv8BlEAkx.png) ## rail-fence ![image](https://hackmd.io/_uploads/ByyCdIrA1g.png) Rail fence cipher [Link](https://en.wikipedia.org/wiki/Rail_fence_cipher) ![image](https://hackmd.io/_uploads/HkjeY8rCyx.png) online decode[Link](https://www.boxentriq.com/code-breaking/rail-fence-cipher) ![image](https://hackmd.io/_uploads/SytMK8B0Jl.png) # Hard ## miniRSA(e很小) ![image](https://hackmd.io/_uploads/ry3Edq8kel.png) ```python= from sympy import integer_nthroot N = 29331922499794985782735976045591164936683059380558950386560160105740343201513369939006307531165922708949619162698623675349030430859547825708994708321803705309459438099340427770580064400911431856656901982789948285309956111848686906152664473350940486507451771223435835260168971210087470894448460745593956840586530527915802541450092946574694809584880896601317519794442862977471129319781313161842056501715040555964011899589002863730868679527184420789010551475067862907739054966183120621407246398518098981106431219207697870293412176440482900183550467375190239898455201170831410460483829448603477361305838743852756938687673 c = 2205316413931134031074603746928247799030155221252519872650073010782049179856976080512716237308882294226369300412719995904064931819531456392957957122459640736424089744772221933500860936331459280832211445548332429338572369823704784625368933 e = 3 for x in range(10000): candidate = c + x * N m, exact = integer_nthroot(candidate, e) if exact: print(f"Found! M = {m}, x = {x}") break print(f"m : {bytearray.fromhex(format(m,'x')).decode()}") ``` ![image](https://hackmd.io/_uploads/rk2vOcIkle.png)