[{"content":"This time I couldn\u0026rsquo;t invest a lot of time, but I still solved some easy challenges.\n1753CTF 2025 was different from those I participated in the past, in a way that the interaction with the platform (submitting flags, registering, etc.) was handled through a Discord AI bot, and it was refreshing and fun.\nChallenges Escatlate (flag #1) Escatlate (flag #2) Entropyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy The first two challenges use the same source code.\nEscatlate (flag #1) - Web The challenge provided a URL and the source code of index.js.\nAfter I opened index.js, I immediately searched for the keyword flag to get an idea of what I should do.\nIt looks like there are two separate flags for the two different challenges.\nIf the user role is admin, the server will send the admin flag when accessing the /api/message endpoint. If the user role is moderator, it will send the moderator flag.\nI searched for the keyword moderator and there were no other places with this keyword.\nI continued reading the code, specifically the /api/register endpoint.\nWe can see that this function checks if the user already exists (line 85-86), validates that the role parameter in the request body is not the admin role (88-89), and then creates the user.\nSo it might be simple - all we have to do is register with the moderator role.\nAnd we can access the flag.\nEscatlate (flag #2) - Web Let\u0026rsquo;s move on to retrieving the admin\u0026rsquo;s flag. We know that we need an admin role, but the registration functionality checks if we register with the administrative role:\nif(req.body.role?.toLowerCase() == \u0026#39;admin\u0026#39;) As we previously saw, the flag will be exposed only if the output of role.toUpperCase() would be ADMIN:\nif(req.user.role.toUpperCase() === \u0026#39;ADMIN\u0026#39;) return res.json({ message: `Hi Admin! Your flag is ${process.env.ADMIN_FLAG}` }); It means that we need to find an input for the role value which will behave like this:\nrole.toLowerCase() == \u0026#39;admin\u0026#39; //false role.toUpperCase() === \u0026#39;ADMIN\u0026#39; //true And the solution for this is to use a character that looks like i instead of the i in admin (Unicode normalization), for example Latin Small Letter Dotless I:\nWe can see that it should work:\nAnd here\u0026rsquo;s the PoC:\nEntropyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy - Web/Crypto Description: It\u0026rsquo;s finally here. Something everyone\u0026rsquo;s been waiting for. A service that solves the biggest problem of humanity. People passwords. They are tooooooooooo short.\nWe got a PHP app. By looking at the code (specifically the long entropy and the use of Bcrypt), I knew the solution right away.\nWe can see that the password is hashed using bcrypt and is generated by the combination of username, entropy and password.\nA few months ago, I read an article about a potential issue with bcrypt, which was discovered in Okta (but of course relevant to other applications too).\nBcrypt only uses the first 72 characters for the hash.\nAs we said, the hash is derived from the username, entropy and password:\n$hash = password_hash($usernameAdmin . $entropy . $passwordAdmin, PASSWORD_BCRYPT); The username is Admin which is 5 chars and the entropy length is 66 chars. Both of them are 71 chars long. The 72nd character is the first character of the password, which means it ignores all the rest of the password. So we only need to guess the first character of the password.\nHappy Hacking,\nOrel 🌏\n","date":"2025-04-14T14:08:14Z","image":"/post/1753ctf-2025/cover.jpg","permalink":"/post/1753ctf-2025/","title":"1753CTF 2025"},{"content":"A personal mini blog about infosec and life\nIt\u0026rsquo;s been a while since I posted. Here\u0026rsquo;s what I\u0026rsquo;ve been up to.\nThoughts and Experiences (🐞) My bug bounty plans have been changed. Inspired by Ciarán, I made myself a challenge (60 hours challenge). I chose a target site and I\u0026rsquo;ll see how things progress. My expectations are not very high because the scope of the program is quite small, but let\u0026rsquo;s see how it goes! Oh, and actually this mini blog series is also inspired by his blog.\nI\u0026rsquo;m already 5 hours in and mainly used it to set automations for this website. Specifically, monitoring changes in JS files. I\u0026rsquo;m not done with it and wonder if it\u0026rsquo;s worth my time, since the JS files are very obfuscated, large (1-2 MB), and the obfuscation changes about every day. One thing I could do, is to monitor for changes, prettify the files, check for new or removed lines (while ignoring lines that were modified, as it modifies the obfuscated variable names - I take into account the possibility of missing stuff), and keep only the new lines.\nThis program isn\u0026rsquo;t new to me and there are things I\u0026rsquo;ve already done. So here are the recent highlights including other stuff.\n(🗒️🗒️🗒️) Organized and gathered my notes and leads. I exported the relevant things from Burp Suite to Caido. (🪲) I found a bug in my target site that exposes PII, but it was a duplicate. (🔍) I started using Caido. Although it lacks some of the features Burp Suite provides, it has other nice features, like workflows, findings, files and other interesting sections. They make it better frequently. I also really like the UI and the fact that it works very fast. I\u0026rsquo;m really afraid it would be emotionally hard for me to get back to Burp Suite if I have to. (🪲) I tested a certain feature in a website I use, for personal reasons and it led to a bug. I reported it and it was considered informative. This will probably be my next target site for my next challenge, after I finish this one. (👩🏻‍💻👩🏾‍💻👨‍💻👨🏻‍💻👨🏾‍💻) Critical Thinking had another hackalong event which was fun and beneficial. I continued testing this target with the leads I gathered during the event. (👩🏻‍💻👩🏾‍💻👨‍💻👨🏻‍💻👨🏾‍💻) Critical Thinking also had a bug escalation event where people shared some unbaked bugs and we tried to exploit them together. It was funny and informative. (📱) There\u0026rsquo;s a certain mobile app I use on a daily basis, and it motivated me to do some Android mobile hacking, so in my spare time I focus on this. I think this is one of the reasons I commonly encounter the advice of doing bug bounty of apps you already use, or apps that interest you. Personally, I have more motivation there. (📝🎫) A while ago, I spent a lot of time in doing threat modeling on the application I test, organizing everything and reading the documentation. Although it took a lot of time, it was beneficial and important. It made me understand the application much better and the testing much more efficient. Specifically, reading the documentation resulted in the discovery of new attack surfaces and ideas and also valid coupon/invitation codes, email addresses and usernames I can use for testing. It was kind of funny that they accidentally exposed an invitation link in a video when hovering over a link. (⚙️) I used gau for the target site, and it revealed a lot of useful URLs - some of them contain credentials and even valid coupons or invitation links. This is a very powerful tool. (🐞) Found a bug in BMW that got accepted: https://app.intigriti.com/profile/orelg Interesting Resources: https://regexper.com/ - website that shows regex using a diagram. https://portswigger.net/research/top-10-web-hacking-techniques-of-2024-nominations-open - all the 2024 nominations for the top 10 web hacking techniques. https://medium.com/@illoyscizceneghposter/exposed-credentials-guide-not-just-in-client-javascripts-101-case-studies-131b765e07a2 - niche areas for exposed credentials. https://medium.com/@maxpasqua/type-confusion-dos-in-fb4a-747837d3a8e3 - Type Confusion in Facebook. ","date":"2025-04-07T01:41:58.635Z","image":"/post/small-winds-no-07/cover.jpg","permalink":"/post/small-winds-no-07/","title":"Small Winds - No. 07"},{"content":"A personal mini blog about infosec and life\nOne day, about two weeks ago, my partner was talking to me, and I felt the urge to pay closer attention as he spoke. I focused on his body language, facial expressions, and other nonverbal cues, knowing that by doing so, I could better understand his feelings, what he really tried to tell me, and connect with him on a deeper level. I\u0026rsquo;m not sure what made me do this, but I believe that many times people speak to me (and I\u0026rsquo;m sure I\u0026rsquo;m not the only one), and although I\u0026rsquo;m usually attentive to their words and emotions, placing even more focus on the person I\u0026rsquo;m communicating with can yield much more from the conversation. A while ago I started reading a certain book (maybe I\u0026rsquo;ll review it once I\u0026rsquo;ve finished reading it) that touches on this topic in one way or another. Years ago, I got familiar with the concept of active listening, so this subject wasn\u0026rsquo;t new to me. Still, I want to be more conscious of it as it truly enrich relationships, and I really encourage others to get familiar with it as it can enrich yours as well.\nRecent Thoughts and Experiences (🤩) My last CTF writeup was shared in two different blogs, wow! That really surprised me.\nhttps://baozongwi.xyz/2024/12/04/WorldWideCTF2024/ https://blog.regularofvanilla.com/posts/wwctf#World%20Wide%20Email I also won the \u0026lsquo;Most Detailed Writeup\u0026rsquo; competition for the World Wide CTF! It was for this writeup. I didn\u0026rsquo;t even know about this competition when I wrote it.\n(🔬) Someone (I believe it was James Kettle) mentioned in the past something about how a person could start research. More specifically, he mentioned an article that I want to find. He talked about people sometimes asking which subject they should research and whether their research ideas are good enough. I remember him saying that if you have an idea for research, just go for it, there are no bad ideas for research (I hope I\u0026rsquo;m not misquoting him 😬). Either way, I believe in that approach, and I\u0026rsquo;ve been waiting for interesting ideas for things I\u0026rsquo;d like to research. Recently, in one of my tests, I encountered two strange behaviors related to servers or reverse proxies. One of them involves a discrepancy related to encoding, and the other is related to a certain malformed HTTP request structure and the behavior of servers and reverse proxies to that.\n(🚩) Last weekend I participated in a certain CTF and tried a certain challenge that taught me a few things but in overall it was a guessy challenge. A guessy challenge refers to one that lacks clear direction, includes red herrings, and requires guessing unrelated to logical reasoning.\nGenerally, I believe these kinds of challenges are considered less favorable because they waste the solvers\u0026rsquo; time on parts that might be irrelevant to their solving attempts.\nFor example, you can see the following comments from people about such challenges:\nHere are a few points that can be problematic in challenges:\nParticipants have to guess things unrelated to logic (for example, a username, or even worse - one that isn\u0026rsquo;t found in common wordlists). No source code is provided, the web application has many functionalities, and nothing appears suspicious or everything returns 500 errors. A challenge that provides source code, which is not the real source code, with parts of it removed. Suspicious behaviors or even vulnerabilities in the web application that are unrelated to the solution. There are more aspects that can decrease the quality of a challenge, such as copied challenges from other CTFs, wrong flags, etc., but this section is about something else.\n(🔎🐛) I haven\u0026rsquo;t invested enough time in bug bounty lately because of the many tasks I have, and since I sometimes feel very tired after work, I\u0026rsquo;ll try to lower my weekly goals to 5 hours a week and see how it goes from there. I\u0026rsquo;ll update each time on how my goal progresses, and I\u0026rsquo;ll start with one month.\nI haven\u0026rsquo;t mentioned it, but my main goal in bug bounty is to get better at application security. Sometimes, I encounter the belief that after a certain amount of time—let\u0026rsquo;s say one to three years—there\u0026rsquo;s a feeling that a person has reached a level beyond which there isn\u0026rsquo;t much more to learn. However, when I encounter bugs, ideas, exploitation methods, a deep understanding of certain technologies, programming skills, and more, I see how much more room there is for improvement and learning.\nMy second goal is to hopefully earn money from this.\n(🚩) This year, I\u0026rsquo;ve reached the goal I set for myself two and a half years ago regarding CTFs. I find CTFs to be another way for improvement. If previously I focused on getting the highest score, currently I invest a certain amount of hours each weekend on a specific challenge or challenges, and focus on learning and research. This means that I still try to solve the challenge, but I delve deeper into things like documentation, deeply understanding the source code, researching topics, and trying to comprehend and learn, even if it comes at the cost of not solving the challenge in time. Actually, a lot of times the opposite is true - focusing and investing time on understanding the system and researching helps with solving the challenge.\n(🤖) XBOW - In the past months, there have been talks about XBOW, which is supposed to be an AI-based tool that helps with penetration testing and bug bounty. The company claims that the tool\u0026rsquo;s capabilities are very powerful, for example, you can see some of them here. Since September, they\u0026rsquo;ve reached the #11 place in the USA on HackerOne and found 20 critical bugs. Although some of the programs may have been VDPs, it still raises questions such as: How will this tool or other ones in the future affect bug bounty hunters and programs? How will it affect penetration testers\u0026rsquo; job positions? Is it really as good as they claim? Which bug types can it find?\nPeople say various things, and I agree with some of them. If it\u0026rsquo;s as good as they claim, it may be beneficial to the security research field as it will give penetration testers and bug bounty hunters more time for research instead of investing time in finding basic vulnerabilities.\nIt may also drive people to get even better and search for even more complex bugs.\nTime will tell.\n(📄) As time passes, my belief that Mirantis will help me with the voucher problem for the DCA exam disappears. I believe I\u0026rsquo;ve studied enough to pass it, but I\u0026rsquo;m not planning on paying another ~$200 for a voucher :)\nI\u0026rsquo;ll try contacting them a few more times, but maybe I\u0026rsquo;ll leave it in the near future. I\u0026rsquo;ve gained the knowledge and experience I wanted.\nNow I\u0026rsquo;m thinking about my next certification, and it will probably be one of the AWS ones as I want to study cloud security.\nRegarding my studies for the DCA exam, in the last few months I\u0026rsquo;ve noticed how my control and understanding of Docker have increased. I\u0026rsquo;ve used Docker for creating images that helped me with tasks at work and when docker files were provided in CTFs. Now I\u0026rsquo;ve also started using it for personal labs and mini-projects or poc\u0026rsquo;s I need.\n(🐛🐛🐛) This week I participated in an online Hack-Along event for a certain bug bounty program. I partially participated but my main goal is to also see how others hack, while Rhynorater was streaming. Although there were some similarities of things I do, I learned a few things and got some new ideas. I need to strengthen my client-side hacking and I might give Caido a try in the future. Two people even found vulnerabilities, one of them found a few critical ones.\nInteresting Resources https://github.com/assetnote/nowafpls - Documented WAF limitations that can help with bypassing WAFs. https://blittle.github.io/chrome-dev-tools/ - Dev Tools tips. I haven\u0026rsquo;t tried it yet, but checked it out and I totally plan to. https://xsinator.com/testing.html# - XS leak tests for browsers. ","date":"2024-12-20T17:45:17.991Z","image":"/post/small-winds-no-06/cover.jpg","permalink":"/post/small-winds-no-06/","title":"Small Winds - No. 06"},{"content":"A personal mini blog about infosec and life\nRecently, I took the chance to better get to know the city I live in and went for a long walk (also for exercise). I got familiar with other parts of the city I hadn\u0026rsquo;t known. I realized there was a large area with many stores but almost no people or cars. It felt like an abandoned city, especially because it was maintained and clean. It was very strange to experience that, it was almost like a dream. Also, in another area there was a disproportionately huge residential building (its proportions could hardly be grasped from this image). It actually reminded me of the buildings and atmosphere from Little Nightmares II.\nMonthly Thoughts and Experiences (📗) I finished reading the book \u0026ldquo;Real-World Bug Hunting: A Field Guide to Web Hacking\u0026rdquo;. It was published in 2019. The book is structured so that in the beginning there is a brief explanation of web concepts and the HTTP protocol. Later it goes through different vulnerability types. There\u0026rsquo;s an explanation for each type, and then the author shows different bug reports and explains each of them from the easiest to the most difficult while providing takeaways for each one (I really liked the takeaways).\nIt also provides some tips related to bug bounty in general.\nI was already familiar with a great part of the book but I learned some good tips and new techniques I wasn\u0026rsquo;t familiar with. It was also nice to refresh my knowledge. Throughout the book I took notes (created some kind of checklist) of interesting techniques I want to check in the future.\nThe book was written very clear and was structured in a thoughtful and smart way. I would suggest it to beginners and also to intermediate-advanced level bug hunters, researchers and penetration testers who want to refresh their knowledge and maybe learn some new things. I\u0026rsquo;d give it ⭐⭐⭐⭐⭐ (out of five).\n(🐛) I still haven\u0026rsquo;t heard from the vendor who has a high/critical vulnerability in their software. I also haven\u0026rsquo;t yet received a CVE number or reply from MITRE and I\u0026rsquo;m not sure if there is a technical issue that causes that. I\u0026rsquo;ll try getting help from CERT, and hopefully it will bear fruit.\nI found a company that has a bug bounty program that is vulnerable to this, so meanwhile I reported this issue to them.\nI was also added to the Israeli VDP reporters table for reporting an LFD vulnerability I previously mentioned.\n(🔎🐛) Although I tried in the past, I have started investing time in doing bug bounty. Currently, I aim to invest about 7-8 hours per week (although it doesn\u0026rsquo;t feel enough, especially when there are open leads and everyone can report potential bugs instead of you). I already found some things that look like potential bugs.\nI also joined the \u0026lsquo;Critical Thinking\u0026rsquo; Discord server (actually, I joined it long ago but just started to be more active). It\u0026rsquo;s the Discord server of the \u0026lsquo;Critical Thinking\u0026rsquo; podcast. There are interesting discussions about web app vulnerabilities and bug hunting.\n(🦫) I learned a bit about Go when trying to solve a CTF challenge. I focused on learning while solving this challenge, so I invested time in understanding different things I encountered in the web application source code and in things related to the Go templating engine. I also noticed again that by writing a writeup, because I have to explain my solution, some questions arise that I don\u0026rsquo;t have answers to right away so I have to learn and understand more, which makes me study it more deeply.\n(🏟) I went to the INTENT conference, mainly for participating in the CTF (although I could probably do that remotely). There were two web challenges. I tried one that was written in Ruby. I haven\u0026rsquo;t solved it, but the challenge was about accessing an administrative page only accessible using a session that includes the admin\u0026rsquo;s email address. I believed that the vulnerability was the discrepancy between the login process and the registration process which used the Mail gem. I wanted to find a way that I could register with one email address and when I log in, it would be parsed as another email address. Since it was the last minutes of the CTF, I didn\u0026rsquo;t find a way to do that. However, a few days ago I read this article https://portswigger.net/research/splitting-the-email-atom and I knew it had something to do with it, but when I read this part, I was even more confident about it.\nMaybe I\u0026rsquo;ll later run the challenge in Docker and write a writeup about it. Either way it was worth it since I made some new friends after going to the conference.\n(🐋) I wanted to take the DCA exam but because of an issue on the website of the company that manages the exams, the voucher I purchased was canceled. I tried to contact Examity and Mirantis but it seems that both companies don\u0026rsquo;t want to help with this issue. I\u0026rsquo;ll try contacting Mirantis a few more times, and hopefully I\u0026rsquo;ll receive an answer.\n(🎄) The annual THM Advent of Cyber 2024 has started and I\u0026rsquo;ll give it a shot, it has nice prizes.\nCool Articles Identify technology by 404 page Cross-Site POST Requests Without a Content-Type Header Bypassing restrictions using OPTIONS methods allows RCE ","date":"2024-12-02T21:28:42.256Z","image":"/post/small-winds-no-05/cover.jpg","permalink":"/post/small-winds-no-05/","title":"Small Winds - No. 05"},{"content":"I think this was the first time I was part of one of the first teams to solve a hard challenge in a big CTF. We were the third team to solve it (it ended with 7 solves out of ~580 teams). Sagiv and I worked together on this challenge and it was enriching and fun, especially because I tried a lot of different things along the way and learned new things.\nThe solution to this challenge might seem a bit straightforward or easy but I think what made it a hard challenge were the subtle hints and limited suspicious behaviors, which affected the leads.\nSo instead of writing a concise writeup, I\u0026rsquo;ll explain how we got there.\nIf you want a TL;DR, click here =\u0026gt; teleport me\nAfter entering the URL we see that we can enter an email address and could probably retrieve the results for that email address.\nI wanted to understand what technology is in use, but didn\u0026rsquo;t see any indications of that, so I used the 404 error message to understand what the technology might be.\nAccording to this useful article, the web app is probably written in Python, using Flask.\nBack to the main functionality. Searching for a certain email address results in these messages.\nTwo different messages - interesting. Maybe it indicates something?\nAn invalid email format results in this error and it doesn\u0026rsquo;t reflect the input. Also, interesting - why wouldn\u0026rsquo;t it reflect the input?\nWe tried to understand the web application\u0026rsquo;s behavior, fuzzed a little bit, and tried different injections, which didn\u0026rsquo;t work.\nThe web application removed the following characters from the input:\n' \u0026quot; \\ some whitespace characters At this point we had a few ideas:\nSSTI using the reflection of the email address. Although it reflected inputs like {{7*7}}@gmail.com without evaluating them, we wondered if we needed to enter an input that would be both a valid template and a valid email format from start to end. We wondered if we should find the correct email address to retrieve the flag. If so, maybe NoSQL injection or blind SQL injection could help with that. Some of the email addresses were reflected in the server\u0026rsquo;s response while others were decoded: Maybe there\u0026rsquo;s a system command on the backend that is used and we can exploit it to perform command injection? Right before continuing, one of the first things that came to my mind was a research article by Gareth that I had wanted to read for some time now, and I thought it might be related (I** highly** recommend reading it). Most of it talks about how various valid unpopular email formats can be valid email addresses, while they might cause security issues.\nWe thought about whether we could enter an input that would be considered a valid email format but would later be parsed as something different which could help us with our leads. Unfortunately nothing worked. HOWEVER, one of the things that Gareth mentioned was Unicode overflows.\nI tried that and it didn\u0026rsquo;t work. I\u0026rsquo;m not sure if it\u0026rsquo;s because it works differently in Python or because of another reason. But I tried to copy the weird \u0026rsquo;l\u0026rsquo; characters (I tried the other ones as well) and it turned it to a normal \u0026rsquo;l'.\nI know this Python\u0026rsquo;s behavior. It\u0026rsquo;s Unicode normalization. Sometimes it can be used to bypass blacklists when trying to bypass sandboxes or maybe with when trying to exploit SSTI too.\nWe tried a few things and then we\u0026rsquo;ve thought - \u0026ldquo;wait, if we can turn characters to other ones like к to k, can we do that for other characters? For example for a single quote?\nWe got some ideas from perplexity:\nNote that the first character is not a backtick which didn\u0026rsquo;t work for this challenge.\nEventually, we had a lead! The left single quotation mark was reflected as a single quote in the first message and resulted in a syntax error in the second message.\nPerplexity, do your magic.\nSo it\u0026rsquo;s SQLite. From here, the solution might be pretty straightforward.\nJust to make sure.\nTable structure (we replaced spaces with /**/).\nAnd here\u0026rsquo;s the flag.\nTL;DR:\nThe user enters an email address. The web application only supposedly allows a valid email format, and removes single quotes, double quotes and whitespaces from the input. Python has Unicode normalization, so it turns the left single quotation mark into a single quote. Using that, it\u0026rsquo;s possible to use this and /**/ as a substitute for whitespace to craft an SQL injection payload to retrieve the flag. You can find the payload above. Feel free to message me if you think there are any inaccuracies in the article.\nHappy Hacking,\nOrel 📧\n","date":"2024-12-01T12:15:51.096Z","image":"/post/world-wide-ctf-2024-world-wide-email-search-web/cover.jpg","permalink":"/post/world-wide-ctf-2024-world-wide-email-search-web/","title":"World Wide CTF 2024 - World Wide Email Search (Web)"},{"content":"This CTF challenge was mainly about SSTI in Go. There were various functionalities, and I\u0026rsquo;m not sure if all of them were necessary, so I\u0026rsquo;ll focus only on the ones relevant to this solution. Although there weren\u0026rsquo;t many solves, this challenge wasn\u0026rsquo;t hard and I liked it because it helped me learn more about Go and how SSTI works in Go.\nSource code provided at the end of the article.\nThe web application is some kind of blog that lets us register, view and create blog posts.\nAs we can see, it\u0026rsquo;s a Go application. There are different files for the different functionalities. Here we can see the web application\u0026rsquo;s routes.\nAs always, one of the first things I do is to understand what is probably required for retrieving the flag. So let\u0026rsquo;s see what the \u0026lsquo;flag\u0026rsquo; function does.\nAs we can see (line 45), it checks if we are an admin user. If we are, the server returns the flag.\nI checked a couple of things but then I saw on the CTF Discord server that there was an issue with this challenge and the creator sent the changes made in the code.\nAccording to this, the solution should be related to something in the \u0026lsquo;index.go\u0026rsquo; file.\nIn the old (and secure) code they rendered the template using {{.User.Username}} as the username of the logged in user. The username in this case will be safely displayed without evaluating the value within it (when the username value is an SSTI payload).\nThe new and insecure version takes the username itself, appends it to the random sentence (to one of the sentences in lines 13-16) and then renders the template.\nLet\u0026rsquo;s say the username is {{html \u0026ldquo;Orel\u0026rdquo;}}, it will look like this in secure code vs. insecure code:\nSecure code before rendering:\nHey, {{.User.Username}}; there are {{.NbPosts}} posts right now ! Secure code after rendering:\nHey, {{html \u0026#34;Orel\u0026#34;}}; there are 1 posts right now ! Insecure code before rendering:\nHey, {{html \u0026#34;Orel\u0026#34;}}; there are 1 posts right now ! Insecure code after rendering:\nHey, Orel; there are 1 posts right now ! In Go, as far as I understand, SSTI is restricted in a way that we can only access exported (public) struct fields and methods passed to the template. Line 35 tells us that \u0026rsquo;s\u0026rsquo; is passed to it, which is the Session struct (line 20).\nSo let\u0026rsquo;s see what fields we can access in the Session struct. Remember that our goal is to access \u0026lsquo;/flag\u0026rsquo; using an admin account.\n\u0026lsquo;User\u0026rsquo; refers to our account, nothing interesting there. But let\u0026rsquo;s see what\u0026rsquo;s in the \u0026lsquo;Post\u0026rsquo; struct.\n\u0026lsquo;Author\u0026rsquo; looks interesting, it\u0026rsquo;s a pointer to the \u0026lsquo;User\u0026rsquo; struct.\nEvery user has access to a post that has the admin user as the \u0026lsquo;Author\u0026rsquo; field.\nOur payload would begin with {{ (index .Posts 0).Author }} which is the admin\u0026rsquo;s User object.\nCurrently the payload is combined from Session \u0026gt; Posts (Post struct) \u0026gt; Author (User struct) \u0026gt; ?.\nLet\u0026rsquo;s see what fields or methods we can access in the \u0026lsquo;User\u0026rsquo; struct. The \u0026lsquo;ChangePassword\u0026rsquo; method looks interesting.\nLet\u0026rsquo;s form our payload and try it:\n{{ ((index .Posts 0).Author).ChangePassword \u0026#34;NewPass\u0026#34; }} Registration with the SSTI payload as the username:\nLog in so the web application will render the template with the username. Note that it evaluated the template action (expression) and shows \u0026rsquo;true\u0026rsquo; as the rendered value.\nWe can log in with the new admin credentials and access the flag.\nSource code: https://gitlab.com/4ts/ctf-2024/web/sky-blog/-/tree/main/src?ref_type=heads\nHappy Hacking,\nOrel 🌧\n","date":"2024-11-10T18:00:44.745Z","image":"/post/4t-ctf-2024-my-sky-blog/cover.jpg","permalink":"/post/4t-ctf-2024-my-sky-blog/","title":"4T$ CTF 2024 - My Sky Blog"},{"content":"A personal mini blog about infosec and life\nRecently, YouTube reminded me of a piece I used to listen to: https://www.youtube.com/watch?v=2zcTKhohtJg.\nThis video includes the Minuet and Badinerie movements of Bach\u0026rsquo;s Suite No. 2 in B minor. I became familiar with these pieces, specifically the Badinerie from the old 1993 \u0026ldquo;Bonus\u0026rdquo; PC game I played when I was younger. It turns out that my partner knows this game as well, so it was nostalgic and fun.\n(🎮) I also play Little Nightmares II. It\u0026rsquo;s a game where the character is small (young?) and weak, in a world full of nightmares and finds another little companion along the journey. I\u0026rsquo;ve never encountered a game in this genre with graphics, puzzles, and surroundings as creative and unique as this one (or maybe I just don\u0026rsquo;t play a lot 🙃). They have surely succeeded in delivering the feeling of being weak and vulnerable in a world full of threats and surprises, along with self-belief and the feeling of being able to survive.\n(🎥) Additionally, randomly chosen, I watched the South Korean sci-fi TV series The Silent Sea which is one of the best TV series I\u0026rsquo;ve ever watched.\n**New Things I learned ** (🔬) EJS is a templating engine usually used with Node.js. When used with Express, EJS can be susceptible to SSTI vulnerability when we can control the template rendering process. Since Express.js enables extended query string parsing by default (e.g. filter[status]=active\u0026amp;filter[age][gte]=30), it allows us to control the options passed to EJS render() function.\n(🔬) A cool blog post about a vulnerability chain involving Clickjacking that led to $4133.7 from Google. It was nice to see the process of exploitation and the persistence when things didn\u0026rsquo;t work as expected: https://x.com/rebane2001/status/1836653696639271329\n(🔬🐍) In Python, if we can send a string that will be formatted or control the format template, we can execute arbitrary code and read internal data. Two examples:\n(🔬💉🛢️) If there is a nosql injection in MongoDB and it uses aggregation, we can interact with data from other collections. We can use \u0026lsquo;$lookup\u0026rsquo; and \u0026lsquo;$unionWith\u0026rsquo;. How can we know there is aggregation when there is no source code? As mentioned in the article in the references: \u0026ldquo;In MongoDB, the aggregate method always expects an array of aggregation stages as its first argument. Therefore, look for JSON arrays as a parameter. The \u0026ldquo;$match\u0026rdquo; and \u0026ldquo;$lookup\u0026rdquo; operators in a JSON request can also indicate the use of the aggregate method\u0026rdquo;. References:\n(📗) I didn\u0026rsquo;t think about it before, but I learned from the book \u0026ldquo;Real-World Bug Hunting\u0026rdquo; that even if HttpOnly attribute is set, in situations where there is XSS and also misconfiguration such as /phpinfo.php (which reflects the cookies) we can steal them anyway.\nWeekly Thoughts and Updates (📄) My first CVE was published 🎉 https://www.cve.org/CVERecord?id=CVE-2024-44807 (📄) Handling the CVE process because of this CVE publication (and because of another one I really wish to publish), made me think about going through various random CVEs. Since they usually have public references (as part of the requirement for CVE publication), I can read, learn from them and gain inspiration for vulnerabilities. (🐛) A week ago I contacted the vendor of the product I found a high-critical vulnerability in, but still no reply from them, I\u0026rsquo;ll wait another week and contact them again. Meanwhile I\u0026rsquo;m trying to see if any of the vulnerable companies using this product has VDP or BPP. (🐋) I\u0026rsquo;ve finished the Docker course and now I\u0026rsquo;m preparing for the certification test. (🔨) Got an idea for a tool that identifies the framework/programming language/etc. of web apps using different methods. I put it in my To Do/backlog list, and I will later check this idea.. ","date":"2024-10-14T21:23:22.293Z","image":"/post/small-winds-no-03-1/cover.webp","permalink":"/post/small-winds-no-03-1/","title":"Small Winds - No. 04"},{"content":"Unfortunately, I did not have much time to try more challenges so this will be a short one.\nThe challenge provided the URL for the web app and its source code (can be downloaded at the end of this article).\nWhen I accessed the URL, the web app displayed this message:\nThe source code contained these files:\nAfter searching for the flag\u0026rsquo;s location, I noticed it is the 8th quote in the \u0026lsquo;quotes\u0026rsquo; file.\nLet\u0026rsquo;s check the \u0026lsquo;app.js\u0026rsquo; file to understand how to retrieve it.\nBy sending a GET request to \u0026lsquo;/register\u0026rsquo; we can generate a JWT:\nThe web app reads the contents of the \u0026lsquo;quotes\u0026rsquo; file, and splits it into an array of strings, where each element represents a single quote:\nThere are some other functionalities in the web app, but after reviewing the code and thinking they might be irrelevant, I focused on this part:\nBy sending a GET request to \u0026lsquo;/quote\u0026rsquo; with the \u0026lsquo;id\u0026rsquo; parameter which is the quote id, we might somehow retrieve the flag.\nLet\u0026rsquo;s break this code:\nline 66: Number() converts \u0026lsquo;id\u0026rsquo; to a number (i).\nline 68-72: checks if \u0026lsquo;i\u0026rsquo; is equal to or greater than FREE_TIER_QUOTE_LIMIT (which is 5. I did not add this code section).\nIt means that it prevents us from retrieving the flag which is the 8th quote (index \u0026lsquo;7\u0026rsquo;). line 74-78: checks if \u0026lsquo;i\u0026rsquo; is in the array bounds.\nline 80-85: applies parseInt() on \u0026lsquo;i\u0026rsquo;, and will display the corresponding quote depending on the result (for example, 5 will show the quote in index \u0026lsquo;5\u0026rsquo;).\nI knew that parseInt() has certain behaviors that might be related to the vulnerability. It reminded me of a challenge I had solved before, but this time it was a bit different: https://www.thesecuritywind.com/post/uoftctf-2024-writeups#viewer-qdfm150837 In summary:\nWe provide an \u0026lsquo;id\u0026rsquo; value. The \u0026lsquo;id\u0026rsquo; is converted to a number (\u0026lsquo;i\u0026rsquo;). parseInt(i) parses the input until it encounters a non-digit character. For example \u0026lsquo;1b2\u0026rsquo; will be parsed as \u0026lsquo;1\u0026rsquo;. So I searched for a value that is considered a number, remains unchanged after the Number() function, but will be parsed as \u0026lsquo;7\u0026rsquo; after the parseInt() function.\nNote: In retrospect, I realized that there are valid values which can change when passed to the Number() function. I tried some values and fuzzed a little bit. All of my attempts resulted in quotes I was permitted to read, \u0026rsquo;null\u0026rsquo; or errors.\nThen I found a certain number representation that could work for our conditions (different representations can be found here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number).\nNumber(\u0026ldquo;7e-310\u0026rdquo;) is converted to 7e-310.\n7e-310 is between 0 and 7 (7*10^-310 is a positive number close to 0).\nparseInt(7e-310) is 7.\nIt works because JavaScript represents very small numbers using scientific notation. For example, while \u0026lsquo;0.000007\u0026rsquo; is represented as \u0026lsquo;0.000007\u0026rsquo;, \u0026lsquo;0.0000007\u0026rsquo; is represented as \u0026lsquo;7e-7\u0026rsquo;.\nSo even if we send an id of \u0026lsquo;0.0000007\u0026rsquo;, it should work as well since Number(\u0026ldquo;0.0000007\u0026rdquo;) will convert it to \u0026lsquo;7e-7\u0026rsquo; and parseInt() will parse it as \u0026lsquo;7\u0026rsquo;.\nSource code:\nHappy Hacking,\nOrel 🐠\n","date":"2024-09-30T05:19:04.953Z","image":"/post/buckeyectf-2024-quotes-web/cover.png","permalink":"/post/buckeyectf-2024-quotes-web/","title":"BuckeyeCTF 2024 - quotes (Web)"},{"content":"\nThe challenge provided two files - server.py and admin.js, and a link to a web application that lets us enter a URL path that the bot will visit, which means this challenge is probably XSS or SSRF-related.\nLet\u0026rsquo;s dive into the source code and see where the flag is mentioned, so we can think about the next steps.\nUnfortunately, I did not find any mentions of a flag, but we can see in \u0026lsquo;server.py\u0026rsquo; that a secret value is read from \u0026lsquo;secret.txt\u0026rsquo;.\nLater in the code, we can see that this secret value needs to be set in the cookies for the \u0026lsquo;/api/cal\u0026rsquo; API endpoint. We can also see that it is probably possible to exploit a command injection vulnerability, using the \u0026lsquo;modifier\u0026rsquo; parameter. It would look something like:\n?modifier=;ls Maybe we can tell the bot to visit this API endpoint if the bot has the secret in its cookies, and somehow send us the command injection results.\nLooking at the \u0026lsquo;admin.js\u0026rsquo; file, we can see that the bot has the secret in its cookies, but we cannot tell it to visit any URLs that include \u0026lsquo;cal\u0026rsquo; or \u0026lsquo;%\u0026rsquo;.\nSo we need to find another way to make the bot access the API endpoint vulnerable to the command injection.\nWe can add a high score in the system by sending \u0026lsquo;username\u0026rsquo; and \u0026lsquo;high_score\u0026rsquo; parameters and we will receive a UUID.\nAnd this API endpoint returns the high score UUID data.\nThis is the main functionality of the web app. We need to retrieve the secret value to be able to exploit the command injection, or to make the bot access it.\nWe can try to inject a script as the \u0026lsquo;username\u0026rsquo; parameter\u0026rsquo;s value in the \u0026lsquo;/api/stats\u0026rsquo; endpoint and then, tell the bot to visit the UUID that contains the XSS payload.\nInjecting a script in the \u0026lsquo;username\u0026rsquo; parameter\u0026rsquo;s value:\nThe script tells the bot to access \u0026lsquo;/api/cal/?modifier=;cat secret.txt\u0026rsquo; (the endpoint vulnerable to command injection), and to read the content of the \u0026lsquo;secret.txt\u0026rsquo; file. Then it will create a new Image object with the source of our server, and appends the response of the \u0026lsquo;/api/cal\u0026rsquo; request a parameter\u0026rsquo;s value.\nAn image object was used instead of XHR or fetch() requests to bypass the same-origin policy requirements which are not applied to images (I\u0026rsquo;m actually not sure why it blocked the requests in my initial attempts using fetch(), as they were GET requests without any special headers, but I didn\u0026rsquo;t delve into this, and I just replaced it with an Image object).\nThis is how the bot probably see it:\nTelling to bot to visit this UUID:\nThe bot request to our server which includes the contents of \u0026lsquo;secret.txt\u0026rsquo; file:\nUsing the secret to find the flag file and read it:\nHappy Hacking,\nOrel 🍊\n","date":"2024-09-23T17:10:51.627Z","image":"/post/patriotctf-2024-open-seasame-web/cover.jpg","permalink":"/post/patriotctf-2024-open-seasame-web/","title":"PatriotCTF 2024 - Open Seasame (Web)"},{"content":"A personal mini blog about infosec and life\nPreviously, I mentioned my interest in improving my knowledge of browser internals and application security.\nAlthough I am working on this in the background (and probably should invest more time in it), I also know it is crucial for me to strengthen my skills in cloud-native technologies and cloud platform security. So I have started studying for the Docker Certified Associate certification (https://github.com/Evalle/DCA). I will probably finish it by the start of next month.\nWeekly Thoughts and Updates Comparing Link Finder Tools I compared the results of \u0026lsquo;JS Link Finder\u0026rsquo;, \u0026lsquo;LinkFinder\u0026rsquo;, and \u0026lsquo;JS Miner\u0026rsquo;. Personally, when full coverage isn\u0026rsquo;t very important, I would prefer using \u0026lsquo;JS Link Finder\u0026rsquo; and \u0026lsquo;JS Miner\u0026rsquo;, as almost all the time the first two tools found the same things, while \u0026lsquo;JS Link Finder\u0026rsquo; performed a bit better. Comparing Tools to Potentially Finding a CVE While doing this comparison, I found an interesting URL path that led to some kind of administrative feature that potentially allows me to add and remove servers, view IPs, ports, names, and maybe other things as well. Related CTF Challenge As a coincidence, last weekend I tried a certain CTF challenge (SnakeCTF - Affekot) that was related to this topic. The web application used Next.js, and one of the URL paths was a page for developers to register an admin user. After that, it was easy to get the flag. Web Timing Attacks I\u0026rsquo;ve finished James Kettle\u0026rsquo;s article about timing attacks, and it was super interesting. This issue or type of attack is probably relevant to a huge amount of web applications, much like how SQL injection was very common years ago. Link: https://portswigger.net/research/listen-to-the-whispers-web-timing-attacks-that-actually-work\nA Few Other Notes I had the chance to gain some experience with a Java Spring environment, so I learned a few new things about it, which was pretty fun. I received a CVE number for the vulnerability I mentioned in the past. The next step is to contact the vendor. I haven\u0026rsquo;t heard anything new about the LFD vulnerability I found and sent through the VDP. I\u0026rsquo;ll wait a week or two and see if there\u0026rsquo;s any update. ","date":"2024-09-10T18:37:05.577Z","image":"/post/small-winds-no-03/cover.png","permalink":"/post/small-winds-no-03/","title":"Small Winds - No. 03"},{"content":"A personal mini blog about infosec and life\nThe past week and a half was not very productive since I was unwell most of the time.\nIt was probably a mistake, but last weekend my partner and I decided to buy an XL pizza from the best pizzeria in town according to us.\nWe realized that by ordering directly from the pizzeria\u0026rsquo;s website, we pay the same for an XL pizza as we would for a family-size pizza using Wolt food delivery app.\nAnyway, this size was probably too much for me.\nWeekly Activities and Notes I submitted my first CVE request. Let\u0026rsquo;s wait and see if it is approved. I sent my first VDP to the Israel National Cyber Directorate. It detailed a local file inclusion vulnerability in a very large Israeli company. By reading the environment variables (/proc/self/environ), it was possible to retrieve sensitive information such as a secret used for authentication for one of their services. Although I don\u0026rsquo;t use them much, I was thinking about comparing the results of BuiltWith and Wappalyzer. I added this to my To-Do list. About two weeks ago, Trail of Bits hosted a webinar with James Kettle (Director of Research at PortSwigger). They discussed several tips regarding Burp Suite, introduced the new Intercept tool, and talked about a few other topics. Some of James\u0026rsquo; and Trail of Bits\u0026rsquo; suggestions were: PortSwigger has created a new Discord server. It might be a good place to have discussions with other researchers. Invitation link: https://discord.com/invite/portswigger James Kettle has published new research about timing attacks and their major impact on web applications. He published an article a year ago, but it was more theoretical. This time, it\u0026rsquo;s not theoretical anymore. He has found a way to perform this attack on many web applications and shows how to do it. I haven\u0026rsquo;t finished reading the article yet, but I surely plan to do it. Link: https://portswigger.net/research/listen-to-the-whispers-web-timing-attacks-that-actually-work CTF Last weekend I participated in LIT CTF. I did not plan to publish an independent post with writeups because it wasn\u0026rsquo;t very challenging, so I will write the solutions of two of the challenges here:\nweb/jwt-2: The Express web application uses JWT for authorization to access the flag. There are 4 conditions: This means that all we need is for our signature to match the expected signature. What do we need to generate the expected token?\nAccording to section #3 in the image, we need:\nTo create an HMAC object using the jwtSecret, which we have: The header and payload JWT sections. So nothing prevents us from generating this signature and using it in our modified JWT where the \u0026lsquo;admin\u0026rsquo; property is set to \u0026rsquo;true\u0026rsquo;: web/kirbytime - In this challenge we should essentially guess the password using a timing attack. For each correct character, the system waits 1 second. This way, we can try all of the characters and determine the correct next character. We can do this using a script or manually. ","date":"2024-08-16T20:53:25.174Z","image":"/post/small-winds-no-02/cover.jpg","permalink":"/post/small-winds-no-02/","title":"Small Winds - No. 02"},{"content":"A personal mini blog about infosec and life\nRecently, I encountered a blog that inspired me to create a more personal mini blog as part of The Security Wind. I plan to post on a weekly or biweekly basis, and it will probably include more personal stuff and thoughts, combined with other things related to information security - likely interesting things I\u0026rsquo;ve learned, plans, tips and whatever else comes to my mind :)\nI will probably know better later on.\nA while ago, I had some kind of emotional buying urge (is there such a thing? Probably). It started with the revelation (🙄) that I am not where I want to be professionally regarding application security. More specifically, I wanted to get better with browser internals, beyond the basics. I wanted to buy a physical book because I often read a lot on my computer and was looking for a different option (as well as the fact that I enjoy reading from physical book and they\u0026rsquo;re easier for me to read while commuting).\nI did some research and found two books that met my needs: The Browser Hacker\u0026rsquo;s Handbook (2014) and The Tangled Web (2011). They are a bit old but a lot of the content is still relevant.\nSo it started with the idea of buying one book and I found myself ending up with seven.\nMy reasoning behind buying each book:\nThe Browser Hacker\u0026rsquo;s Handbook (2014), The Tangled Web (2011) - They teach about browser internals. I wasn\u0026rsquo;t entirely sure if one book offered more information on certain subject so I bought both to have both perspectives. Attacking and Exploiting Modern Web Applications (2023) - Some modern attacks, technologies and perspectives that I would like to read about. Web Security for Developers (2020) - To better understand security from the development point of view. Real-World Bug Hunting (2019) - To learn tricks that I\u0026rsquo;m not aware of. **Bug Bounty Bootcamp (2021), **JavaScript for hackers (2022) - Don\u0026rsquo;t ask. Aside from my buying urge, these books were recommended and they probably offer more tips and tricks. Weekly Thoughts A few weeks ago I started reading \u0026lsquo;The Browser Hacker\u0026rsquo;s Handbook\u0026rsquo; but because of an issue, I temporarily stopped and switched to \u0026lsquo;Real-World Bug Hunting\u0026rsquo;. I began creating some kind of checklist of things I want to test in penetration tests. Some of them are specific (for example methods I use to cause detailed error messages) and others are more general. I use this book to add ideas and attack types to this checklist.\nI\u0026rsquo;ve finished about half of the book so far, and it\u0026rsquo;s well written. It explains several attack types, provides examples of interesting bug bounty reports that have been disclosed, and a takeaway for each example. Although I\u0026rsquo;m already familiar with a major part of this book, there are some techniques that are new to me or perspectives that I find beneficial.\nOne bug bounty report mentioned in the book is this one: https://hackerone.com/reports/127703/ In scenarios where the CSRF token is correctly implemented, we might find the CSRF token in certain JS files. Since loading JavaScript files from another origin does not violate the Same Origin Policy, when the victim enters the attacker\u0026rsquo;s website, it can load the script which contains the victim\u0026rsquo;s CSRF token and send a request with the CSRF token included.\nFor some reason it reminded me of the Same Origin Method Execution (SOME) attack: It probably reminded me of this attack because both methods rely on loading a script to bypass the SOP restrictions and perform an attack. This made me more aware of the possibility of abusing this behavior in loading scripts when needed.\nI\u0026rsquo;ve started creating a tool for bypassing WAFs or CDNs by trying to find the actual server\u0026rsquo;s IP address hidden behind the CDN IP address, using three different methods. I hope to have updates next week. I created a new page in my Notion account for new tools or things I want to do before or during future tests. Some of them are: ","date":"2024-08-07T16:24:53.225Z","image":"/post/copy-of-small-winds-no-01/cover.jpg","permalink":"/post/copy-of-small-winds-no-01/","title":"Small Winds - No. 01"},{"content":"This year I participated with Flag Fortress 2, and we reached the 2nd place (which is well above my goals I set for myself two years ago).\nHere are writeups of two of the challenges:\nWeb - Call the Manager pliz!\nRadio Frequency - Covert Signal\nWeb - Call the Manager pliz! After accessing the challenge link, we are redirected to /fetcher. We\u0026rsquo;ll get back to it later. We can also notice that the source code ZIP is commented in the HTML.\nAfter downloading it we can view the following routes and controllers:\nLet\u0026rsquo;s start with the \u0026lsquo;flag\u0026rsquo; route (this is what we eventually want, right?).\nAccording to the code, when accessing /flag, before the execution of \u0026lsquo;FlagController.getFlagFinaleFlag\u0026rsquo; method there are two middleware (Middleware are functions that process requests and responses, sitting between the server receiving a request and the controller). One of them is for token authentication and the other is for validating that the user role is \u0026lsquo;admin\u0026rsquo;.\nInside this controller we can see that the mentioned method probably reads the actual flag. But we can see that there is another method (getFlags) that was not mentioned in the /flags route or anywhere else in the code, and it is vulnerable to SQL Injection.\nAlthough it is not implemented in the code, let\u0026rsquo;s try accessing it anyway using the /flag route, and the parameter mentioned in the code (id). It seems we need an access token.\nSearching the code for this error, brings us to the \u0026lsquo;authenticateToken\u0026rsquo; middleware.\nSo we probably need an account. The \u0026lsquo;users\u0026rsquo; route mention a creation process but there is a middleware that checks that the request originates from localhost.\nThe method requires username and password, and we cannot control the user\u0026rsquo;s role which is set to \u0026lsquo;user\u0026rsquo;.\nBack to the /fetch path, we can exploit an SSRF vulnerability (can also be identified in the code). Using that, we can set the domain as \u0026rsquo;localhost\u0026rsquo; and bypass the localhost middleware. We can see that we are able to create a new user, login with its credentials and receive an access token (the login functionality can also be understood from the code).\nUsing the access token, we can exploit the SQLI I have mentioned earlier. In a normal behavior it should return \u0026lsquo;id\u0026rsquo; and \u0026lsquo;flag\u0026rsquo; which are integer and string so we should keep this structure so there will be no errors.\nI guessed that the first user probably has an \u0026lsquo;admin\u0026rsquo; role, so searched for the first user. It makes sense since the challenge author\u0026rsquo;s name is Liav (it is also possible to replace \u0026lsquo;username\u0026rsquo; with \u0026lsquo;role\u0026rsquo; in the payload just to make sure).\nSame for password:\nI logged in with these credentials, retrieved the access token and accessed /flags/flag.\nRadio Frequency - Covert Signal The challenge provided a WAV file that sounded very similar to an SSTV transmission (https://www.youtube.com/watch?v=SffT9U8scBc), so I said to myself, \u0026lsquo;Oh, this should be easy,\u0026rsquo; and opened the SSTV software I usually use (RX-SSTV). After trying different modes, I realized there was more to it.\nI had a hunch from the start that it would not be straightforward and that the challenge description probably contained hints. Some of the keywords would likely be Olivia, 4:00, and 125.\nAfter searching a bit, I discovered that Olivia is the name of an MFSK mode, which is a method of delivering data (usually text) using radio frequencies, compared to SSTV, which is used to deliver image data.\nI downloaded some software and struggled a bit in the beginning.\nBut then I downloaded one that seemed pretty simple to use.\nAfter choosing the correct mode (Olivia OL 4-125) and loaded the WAV file, the flag was written letter by letter.\nHappy Hacking,\nOrel 🥥\n","date":"2024-06-27T17:00:10.536Z","image":"/post/bsidestlv-2024-ctf/cover.png","permalink":"/post/bsidestlv-2024-ctf/","title":"BSidesTLV 2024 CTF"},{"content":"Challenges:\nRnd For Data Science\nButterfly Rnd For Data Science Vulnerability: Injection in Pandas library query allows to bypass filtering restriction\nThis challenge included two files whose general purpose was to retrieve column names and a delimiter from the user and to create a CSV file from them.\nThe server uses the column names as headers for the table and fills the table with random numbers.\nAfter that, it adds another row (the 11th row) that inserts the flag into the second column place.\ndef index(): delimiter = request.form[\u0026#39;delimiter\u0026#39;] if len(delimiter) \u0026gt; 1: return \u0026#39;ERROR\u0026#39; num_columns = int(request.form[\u0026#39;numColumns\u0026#39;]) if num_columns \u0026gt; 10: return \u0026#39;ERROR\u0026#39; ** headers = [\u0026#39;id\u0026#39;] + [request.form[\u0026#34;columnName\u0026#34; + str(i)] for i in range(num_columns)]** forb_list = [\u0026#39;and\u0026#39;, \u0026#39;or\u0026#39;, \u0026#39;not\u0026#39;] for header in headers: if len(header) \u0026gt; 120: return \u0026#39;ERROR\u0026#39; for c in \u0026#39;\\\u0026#39;\\\u0026#34;!@\u0026#39;: if c in header: return \u0026#39;ERROR\u0026#39; for forb_word in forb_list: if forb_word in header: return \u0026#39;ERROR\u0026#39; csv_file = delimiter.join(headers) for i in range(10): row = [str(i)] + [str(rnd.randint(0, 100)) for _ in range(num_columns)] csv_file += \u0026#39;\\n\u0026#39; + delimiter.join(row) **row = [str(\u0026#39;NaN\u0026#39;)] + [\u0026#39;FLAG\u0026#39;] + [flag] + [str(0) for _ in range(num_columns)]** csv_file += \u0026#39;\\n\u0026#39; + delimiter.join(row[:len(headers)]) return csv_file Then it sends this table to the main app to create a CSV file.\n@app.route(\u0026#34;/generate\u0026#34;, methods=[\u0026#39;POST\u0026#39;]) def generate(): data = request.form delimiter_const = \u0026#39;delimiter\u0026#39; r = requests.post(\u0026#39;http://127.0.0.1:5001\u0026#39;, data=data) if r.text == \u0026#39;ERROR\u0026#39;: return \u0026#39;ERROR\u0026#39; csv = StringIO(r.text) df = pd.read_csv(csv) # Filter out secrets **first = list(df.columns.values)[1]** **df = df.query(f\u0026#39;{first} != \u0026#34;FLAG\u0026#34;\u0026#39;)** string_df = StringIO(df.to_csv(index=False, sep=data[delimiter_const])) bytes_df = BytesIO() bytes_df.write(string_df.getvalue().encode()) bytes_df.seek(0) We can see that the server takes the second column name: first = list(df.columns.values)[1]\nAnd here it performs a query to retrieve all rows where the value in the second column does not equal \u0026lsquo;FLAG\u0026rsquo;:\ndf = df.query(f\u0026rsquo;{first} != \u0026ldquo;FLAG\u0026rdquo;\u0026rsquo;)\nLet\u0026rsquo;s debug it and run it locally.\nAfter entering two columns named \u0026ldquo;col1\u0026rdquo; and \u0026ldquo;col2\u0026rdquo;, we receive this table. As we can see, the flag was not included in this table.\nBy debugging the code, we can see that before the filter, the table includes the flag (SecretFlag), and after the filter it is not included.\nSo we need to find a way to alter the the table structure or alter the query, using one of our inputs.\nJust like SQL Injection, we can inject to the pandas query a comment and it will ignore everything that comes after it.\nBy entering a number in the query it returns the corresponding row.\nSo assuming our first column is named \u0026ldquo;10#\u0026rdquo;, the query will look like this:\ndf = df.query(f'10# != \u0026ldquo;FLAG\u0026rdquo;\u0026rsquo;)\nand be interpreted as **df.query(\u0026lsquo;10\u0026rsquo;) **which contains the flag.\nAfter filtering the query returned a table that lists the columns and values of row number 10.\nAnd the CSV file will contain the flag:\nButterfly We have access to a web app:\nI did not see any functionalities or interesting requests, so I checked the source code and the browser\u0026rsquo;s storage.\nThe LocalStorage and SessionStorage contained a key and this string: {\u0026ldquo;code\u0026rdquo;:\u0026ldquo;CryptoJS.AES.decrypt(CIPHERTEXT, KEY).toString(CryptoJS.enc.Utf8)\u0026rdquo;}\nI assumed that the key should be in the KEY position, but where is the ciphertext?\nLooking in the source code I saw a big obfuscated JavaScript code. I used online deobfuscator and beautifier and this was part of the deobfuscated code:\nI tried to understand what may be the ciphertext. Maybe part of the \u0026rsquo;enc\u0026rsquo; array or the full string after joining them together.\nHowever, after checking online what the ciphertext should look like, it was less likely that this was the ciphertext because of its length, structure and different characters.\nKnowing that the ciphertext had been altered, I continued to explore other interesting parts in the obfuscated code.\nSome of them were \u0026ldquo;transaction\u0026rdquo; \u0026ldquo;readwrite\u0026rdquo; \u0026ldquo;target.result\u0026rdquo;. I googled them together to understand what are they related to and understood they are related to IndexedDB.\nIndexedDB is a NoSQL database provided by modern browsers. It saved the data on the client-side, in the user\u0026rsquo;s local system. In order to retrieve the data from it, the user need to use JavaScript.\nI asked one of the LLMs how to retrieve data from IndexedDB, it gave me a script that needed a small modification and updating the database name and the store object that were \u0026ldquo;strangeStorage\u0026rdquo; and \u0026ldquo;FLAG\u0026rdquo;.\nI retrieved the ciphertext from the DB, and decrypted it.\nThanks for reading,\nOrel 🌑\n","date":"2024-05-14T00:13:15.132Z","image":"/post/tbtl-ctf-web-writeups/cover.png","permalink":"/post/tbtl-ctf-web-writeups/","title":"TBTL CTF Web Writeups"},{"content":"I really like using Large Language Models (LLMs). One of my uses for them is solving CTFs.\nRecently I started comparing a couple of them, especially since there have been some major updates lately.\nI was curious and wanted to create a table that would compare their capabilities in solving CTFs. My significant other then asked me why not write an article about it, so here we are😉.\nI read some opposing views towards using LLMs for CTFs. However, for me, using them is the same as googling and searching the web for learning, and trying to find answers to challenges or tasks we have. If we had the option to use google much more efficiently and find the results we want right away, I believe most of us would do that.\nSome people may say that LLMs solve the challenges for us, unlike searching the web, and some of that is true, but not always.\nI would divide it into two situations:\nWhen we are focusing on getting points or solving tasks: In this case, I see no problem with using all the tools we have in order to be the most efficient and do what we want in the fastest way possible. When we want to learn and understand how to do things: From my experience, often (or even the vast majority of times), the answer is not presented right away and I think that: By getting the LLM output and the results, we also learn by reading the solution. We still think and learn because a lot of times the LLM gives us only leads and we have to test them and continue using the hints and leads we have received. So we will still try to solve the challenges on our own. Sometimes we simply request the model to explain a code snippet, a certain technology, etc., and not really ask it to solve the challenge. The Models I Used Some of the top and most interesting LLMs that I was familiar with include:\nOpenAI GPT 4.0 Claude 3 Opus Google Gemini Pro 1.5 Pi - Inflection-2.5 There are some additional LLMs that I did not test or partially tested. For example:\nMicrosoft Copilot, since it uses GPT 4.0 and this model is already part of the comparison, so I assumed there should be no major differences. Some LLMs that were just not good enough. Google Gemini Ultra 1.0 which should be Google\u0026rsquo;s best model and requires a monthly payment. It is impossible to work with because the security mechanism stops conversations or deletes links many times. It is a bummer since I believe Gemini could help a lot. Here are some of its behaviors: The Comparison The following table shows which LLMs succeeded in solving the different challenges.\nA couple of notes:\nThe results combine which LLMs succeeded in solving the challenges and how many prompts (hits) it took. The main goal was to understand which model is the best for CTF competitions. I usually sent the same prompt to all the LLMs, including the CTF description, any provided files or code, and my request. Also, I gave each of them a similar number of attempts before considering the result as failed. The challenges I used for comparison came from different CTFs, which I had already solved or had solutions for. They were mainly Web and Forensics challenges, because these are the categories I usually focus on, but I know it is possible to solve or get help for other categories as well. I will provide a general description and notes for each challenge in the section following the table. GPT 4.0 Claude Opus Gemini Pro 1.5 Pi 2.5 .git Challenge 1 hit (.git and Directory Brute Forcing) Directory Brute Forcing Directory Brute Forcing Directory Brute Forcing Secret PNG in PDF 3 hits 3 hits 3 hits -instructed to extract only JPEG Zip Slip Symlink 1 hit 1 hit 1 hit JS/LocalStorage Manipulation 1 hit 1 hit 1 hit 1 hit Prototype Pollution Only identified 5 hits - almost exploited Only identified Only identified Parameter Pollution 2 hits 1 hit Message in RGB Values 3 hits LLM Token IDs Suggested other models Hidden Data in ShellBags 1 hit Prompt Injection #1 5 hits 2 hits 5 hits Prompt Injection #2 7 hits 5 hits Challenges Descriptions for Reference (skip to conclusions if desired) .git challenge - There is only access to a simple website. The solution is downloading the .git folder and searching for the flag in previous commits.\nSecret PNG in PDF - A PDF file contains a secret PNG with the flag but does not display it.\nZip Slip Symlink - A website with the functionality of uploading a ZIP file, extracting it and reading the extracted files. The solution is to upload a ZIP file of a Symbolic link, pointing to the flag\u0026rsquo;s location.\nSimple JS/LocalStorage Manipulation - A button that needs to be pressed a many times to reveal the flag and the clicks are stored in the LocalStorage. Everything is on the client side.\nPrototype Pollution - A website containing two main functionalities. Claude Solution (the correct solution is without \u0026ldquo;secret\u0026rdquo;):\nParameter Pollution - A website that allows registering, login, and donating money. As a user, you start with $1000, and can only donate to Jeff Bezos, not other users. The goal is to gain more than a certain amount of money to obtain the flag. The solution was to create a couple of users and send money to one of them using:\nto=lisanalgaib\u0026amp;to=orel\u0026amp;currency=1000 Message in RGB Values - The challenge provided a small square image with random colors in each pixel: The solution is to take each pixel\u0026rsquo;s RGB values, combine them and convert to ascii which will result in a message containing the flag.\nNote: all the tested LLMs mentioned solutions related to RGB values but only ChatGPT suggested to sum them.\nLLM Token IDs - For this challenge we were provided with LLM tokens: [2864, 35, 1182, 37, 90, 28936, 8401, 821, 2957, 5677, 265, 7037, 40933, 29415, 92]. The solution was to find the correct model that translates these tokens to the flag.\nWhile ChatGPT didn\u0026rsquo;t solve it, it suggested trying different models and understood it needs to be translated to words/the flag.\nFor some reason Claude acted like GPT 3.5 and was sure that the flag is UMDCTF{hackerman}\nGemini 1.5 went too far and suggested unrelated solutions.\nAnd Pi was sure the flag is UMDCTF{DontUnderestimateVladimirHarkonnen} 🤦🏻‍♀️\nHidden Data In ShellBags - The challenge provided a VDI file and we had to find some deleted information that still exists in ShellBags (https://www.hackingarticles.in/forensic-investigation-shellbags/). Gemini was the only one that suggested a correct and a quick solution. Claude was pretty close but its solution did not work for me. Prompt Injection - The LLM should not generate any code. Claude Opus did not want to help because of unethical hacking reasons. Prompt Injection - The LLM should not display the password. Claude Opus did not want to help because of unethical hacking reasons. Conclusions and Final Thoughts In conclusion, here are the results (excluding the partial solutions):\nModel Number of Successes Web Challenges Forensics Challenges Misc Challenges GPT 4.0 7 3/4 3/4 1/3 Claude Opus 5 4/4 1/4 0/3 Gemini Pro 1.5 4 1/4 1/4 2/3 Pi 2.5 4 2/4 0/4 2/3 General Impression The top models I have found to be the most intelligent were GPT 4.0 and Claude Opus.\nThere are two main disadvantages of Claude compared to ChatGPT:\nThe fact that sometimes it will not help with prompts it perceives as malicious. Its inability to run code, which limits its capabilities and sometimes leads to nonsense outputs (similar to GPT 3.5). Moreover, it seems to me that GPT 4.0 is slightly better. There are times when it understands the context better and mentions one small additional piece of information that makes a huge difference.\nThere are some tasks that Gemini was really good with (it is also very good with summarizing the results, the leads and next steps), but in general it is not good enough, especially when comparing to GPT and Claude.\nI really wish I could use Gemini Ultra for this for this, but its limitation makes it irrelevant.\nAlthough Pi 2.5 is perceived as less intelligent than the others (by intelligence, I mainly mean understanding and staying in context, having sufficient data, and solving the task), there were times it provided surprisingly helpful outputs, sometimes even more than other models.\nPerformance By Category ChatGPT\u0026rsquo;s results with web and forensics challenges are very good. I believe its poor score in the misc category was due to not trying enough challenges in this category, and because two of the three misc challenges were related to prompt injection, which it seems it is really bad with.\nI actually believe ChatGPT should be good with misc challenges since it has an advantage as it can run and generate pretty good code as I saw in other challenges not mentioned in this article.\nClaude performed VERY well with the web challenges but quite poor with the forensics challenges. One reason for its poor score in the misc category is its refusal to help with prompts considered malicious (the prompt injection challenges).\nGemini and Pi had about the same results across all of categories, so no special comments for them.\nI hope you enjoyed reading.\nFeel free to contact me if you have further insights, different opinions, or anything else.\nOrel 🕵🏻‍♀️\n","date":"2024-05-01T14:54:44.605Z","image":"/post/large-language-models-for-ctfs/cover.webp","permalink":"/post/large-language-models-for-ctfs/","title":"Large Language Models for CTFs"},{"content":"This time we reached the 83rd place out of 1225 teams, which is a really nice score.\nAlthough it wasn\u0026rsquo;t a very hard CTF, I found it fun and some of the challenges were challenging.\nVoice Changer - Web\nThe Varsity - Web\nNo Code - Web\nGuestbook - Web\nHourglass - Forensics\nFlying High - Osint\nVoice Changer - Web This challenge provided a link to a voice changer web application.\nThe request contained parameters that were related to the pitch and the uploaded recording.\nIn the server\u0026rsquo;s response we can see that the web application used ffmpeg command which is a video/audio handling software, in the operating system shell.\nAfter I analyzed the web app behavior, I noticed it used the \u0026lsquo;pitch\u0026rsquo; parameter as ffmpeg command argument, I tried breaking out of the command execution context and running an additional command.\nuoftctf{Y0UR Pitch IS 70O H!9H}\nThe Varsity - Web In this challenge, we got a website that allows the reading of newspapers, but some of the newspapers are for subscribers.\nWe also got the source code.\nWe can see that article 10 is only for subscribers.\nI could not find a way to be a subscriber (bypassing the voucher option in the registration form) so I checked for business logic related bugs.\nIf we enter \u0026lsquo;9\u0026rsquo; (which is actually the 10th issue) as the issue number, the code will enter the second \u0026lsquo;if\u0026rsquo; statement and will return an error.\nHowever, if we enter \u0026lsquo;9;\u0026rsquo; as the issue number, it will not enter the second \u0026lsquo;if\u0026rsquo; statement because\nissue \u0026gt;= 9 returns \u0026lsquo;false\u0026rsquo; as \u0026lsquo;9;\u0026rsquo; cannot be parsed as a number.\nAfter that, the string \u0026lsquo;9;\u0026rsquo; enters:\nissue = parseInt(issue); The \u0026lsquo;issue\u0026rsquo; variable value will be 9 because parseInt() function parses all the input until the first non-numerical character.\nNow, since the \u0026lsquo;issue\u0026rsquo; variable is integer and is in the articles range, it will not enter the next if statement:\nif (Number.isNaN(issue) || issue \u0026gt; articles.length - 1) { And then it retrieves issue number 9 that contains the flag:\nreturn res.json(articles[issue]); uoftctf{w31rd_b3h4v10r_0f_parseInt()!}\nNo Code - Web We received a link and a source code of a web application.\nIt contains the POST /execution route.\nUsing regex, the code checks if the value at the beginning of our string is in the range of the ASCII characters. If the value is within the ASCII range, the program returns an error; otherwise, it executes the code.\nWe can see that by forming a POST request and send our code, it returns an error because the characters are within the ASCII range.\nHowever, by adding a newline (using its URL encoded value) at the beginning of our code, it passes the regex check and runs the code.\nuoftctf{r3g3x_3p1c_f41L_XDDD}\nGuestbook - Web In this challenge we got an HTML File. I opened it in the browser and in VS code. Note that the sheetID is exposed and we can view only the last entries.\nBy Googling/using ChatGPT, I understood that I could try accessing a certain sheet using its sheet ID with the following URL: [https://docs.google.com/spreadsheets/d/sheetID}/edit\nI entered this link using the sheet ID in the code and I retrieved the flag.\nuoftctf{@PP_5cRIP7_!5_s0_coOL}\nHourglass - Forensics This challenge provided an OVA file of Windows 10. According to the description we need to find something suspicious in the system.\nI searched in different areas that might contain interesting or suspicious data.\nI did not find anything until I entered the Task Scheduler and noticed a suspicious task that mention some path (C:\\Windows\\DiagTrack\\Settings\\settings.txt)\nHere we can see the \u0026rsquo;txt\u0026rsquo; file mentioned in the suspicious task, which looks like a Base64 encoded string.\nThis is the decoded string, which is the flag:\nuoftctf{T4sK_Sch3Dul3r_FUN}\nFlying High - Osint So, according to the description, we had to find the airport, airline of the rightmost airplane, and airplane model.\nThis is the image we got:\nBy zooming in we can see that there is some kind of hangar with \u0026lsquo;NOVESPACE\u0026rsquo; written on it.\nGoogling \u0026rsquo;novespace airports\u0026rsquo; result in this web page. It says that this company operates mainly for scientific and technical research programs and it\u0026rsquo;s based in Bordeaux-Merignac Airport.\nAfter searching this airport in Google Maps, we can notice that there is a place called Novespace. By clicking on it, we arrive the the same place as in the image.\nWe can notice that this image if from July 2012.\nRegarding the airline company, it was pretty easy to find it by google searching its logo description.\nFor the aircraft model, I tried all of the current aircrafts they use unsuccessfully, but then I remembered that the photo was taken in 2012 so I searched in the former fleet section. I tried a couple of models that were used in 2012 until I got the correct one.\nThank you for reading. I hope you learned something new.\nOrel 🪷\n","date":"2024-01-24T15:53:03.169Z","image":"/post/uoftctf-2024-writeups/cover.png","permalink":"/post/uoftctf-2024-writeups/","title":"UofTCTF 2024 Writeups"},{"content":"In this CTF we finished in 26th place.\nHere are two writeups of challenges I have solved.\nI didn\u0026rsquo;t put many screenshots since the CTF was down not long after it was ended.\nShuffle - Forensics\nExtracttheflag! - Web\nShuffle - Forensics I was provided with a binary file.\nI tried to identify what this file is using the \u0026lsquo;file\u0026rsquo; command but it could not identify it.\n\u0026lsquo;File\u0026rsquo; command usually checks Magic Numbers and the Magic File to determine the file type.\n\u0026ldquo;Magic bytes\u0026rdquo; are a sequence of bytes that appear at the beginning of a file and are used to identify the type of the file. This sequence of bytes is sometimes called a \u0026ldquo;magic number\u0026rdquo; or \u0026ldquo;file signature\u0026rdquo;.\nFor example, these are the magic bytes of a PNG file (left: Hex, right: ASCII)\n(Here\u0026rsquo;s a large list of different magic bytes: https://www.garykessler.net/library/file_sigs.html))\nI opened it in Notepad++:\nIt looks like a PNG file. We can understand it from the beginning of the file, which looks like the Magic Bytes of a PNG file type (as shown before), but something is broken. From my experience, I know that the \u0026ldquo;PNG\u0026rdquo; ASCII characters should be on the same line.\nAfter trying to change it manually without success I opened the file in \u0026lsquo;010 Editor\u0026rsquo; (a great hex editor):\nLet\u0026rsquo;s examine the hexadecimal sequence for the beginning of a PNG file and identify any discrepancies.\nThe sequence of a PNG file type should always start with the following hexadecimal sequence:\n89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52.\nThis sequence is the magic bytes and the beginning of the IHDR chunk.\nWait, what is IHDR chunk? What are chunks?\n\u0026ldquo;Chunks\u0026rdquo; are the building blocks of the file format. A PNG file is made up of multiple chunks, each of which conveys certain information about the image or the data it contains.\nFor example, some of the chunks for PNG file are IHDR, PLTE, IDAT, sRGB and many more.\nThis is the chunks structure for PNG file:\nLength: A 4-byte integer that specifies the length of the **data field **of the chunk (number of bytes dedicated to it. Type: A 4-byte chunk type code. For example, \u0026ldquo;IHDR\u0026rdquo;. Data: The actual data bytes of the chunk. CRC: A 4-byte code to check if chunk data has changed. For example, these are the length and type section of the IHDR chunk which always stay the same (0x08-0x0B, 0x0C-0x0F respectively):\nSo\u0026hellip; back to the challenge, the initial sequence (first 16 bytes - file type signature and some sections of the IHDR chunk) always remains the same.\nHowever, in this case, it appears to be shuffled:\nInitially, I attempted to manually correct the sequence, but the image remained corrupted.\nI realized I might have to correct the entire hexadecimal sequence. But I can\u0026rsquo;t determine the original sequence unless there\u0026rsquo;s a pattern. Maybe some of the hexadecimal values were swapped with each other. Let\u0026rsquo;s manually fix the sequences that I already know (those that are always the same), and see if there\u0026rsquo;s a clear pattern in the shuffling:\nThe orange text marks the hex that I manually fixed.\nIt seems that the shuffle goes in this pattern:\nKeep the first 2 bytes as they are. Replace the 3rd byte with the 5th. Replace the 4th byte with the 6th. Continue this pattern for the entire file. I asked ChatGPT to create a script for me to reshuffle the bytes using the pattern I provided:\nI opened the new file, and I got the original file:\nExtracttheflag! - Web I\u0026rsquo;ve got the source code of a PHP page. Here are the interesting parts:\nA session is started, and the admin session variable is set to false.\nI checked what the extract() function is.\nNote that it\u0026rsquo;s insecure to use untrusted data for this function from user input.\nIn PHP, the extract($_POST) function is used to convert POST request data into corresponding internal variables.\nWhen PHP runs the extract() function on the $_POST array, it creates variables that mirror the array\u0026rsquo;s contents. This can pose a security risk if extract() ends up overwriting pre-existing variables, which, in our scenario, is exactly what happens.\nAccording to this code part, my session\u0026rsquo;s admin variable should be true in order to see the flag.\nSending a POST request with _SESSION[\u0026lsquo;admin\u0026rsquo;] set as \u0026rsquo;true\u0026rsquo;, would cause the session admin variable to be rewritten and the flag would be exposed:\ncurl \u0026#39;https://extracttheflag.ctf.cert.unlp.edu.ar\u0026#39; -X POST -d _SESSION[\u0026#39;admin\u0026#39;]=true Happy Hacking,\nOrel 🧩\n","date":"2023-10-28T01:32:55.8Z","image":"/post/metared-ctf-argentina/cover.png","permalink":"/post/metared-ctf-argentina/","title":"MetaRed CTF Argentina"},{"content":"The theme of this CTF was an evil hacker group called \u0026ldquo;DEADFACE\u0026rdquo;.\nAdditionally, there were some other groups and companies that were part of the storyline.\nThe CTF contained many challenges, many of which I would define as beginner-intermediate level.\nWe reached 70th place out of 1100 teams.\nshout out to the admins on being very friendly\nThis blog post will contain 3 forensics/steganography challenges that I solved:\nSyncopated Beat - Steganography\nTin Balloon - Forensics\nElectric Steel - Steganography\nSyncopated Beat - Steganography I downloaded a zip that contained two audio files:\nI played the first audio file and in the middle of it, there was a part that was sound like a reversed audio,\nI opened Audacity, reversed that part and it said that I have to use the steganography software from Mr. Robot and the password for the file is the new CEO of Evil Corp, I googled both things, and found that there\u0026rsquo;s a software called DeepSound.\nI opened the second audio using this software.\nI used the password and extracted the hidden file.\nTin Balloon - Forensics After downloading the zip file, there are two files - an audio and a doc file.\nThe doc file was encrypted with a password and once again, part of the audio sounded strange.\nI opened the audio with Audacity, trimmed the part I wanted, used the spectrogram option, and found the doc\u0026rsquo;s password which contained the flag.\nElectric Steel - Steganography I downloaded the image:\nI used binwalk tool to search for hidden files:\nOne of the hidden files was tar file:\nHappy Hacking,\nOrel 🍵\n","date":"2023-10-24T00:09:15.112Z","image":"/post/deadface-ctf-2023/cover.png","permalink":"/post/deadface-ctf-2023/","title":"DEADFACE CTF 2023"},{"content":"Together with members of the Hallios community and CyberSecMaverick, I participated in UMDCTF 2023.\nThe CTF theme was Pokémon and I really liked its design and style of the website and challenges themselves.\nWe reached 86th place which is a respectable position for this CTF.\nI\u0026rsquo;ll mainly share writeups of challenges I solved that I found interesting.\nWeb - pop calc Web - notsogeo Misc - ChungusBot v3 WEB - pop calc The challenge provided a link to a web application:\nTrying to make valid operations resulted in this HTTP request/response (I deleted some of the request headers only for the writeup):\nPerforming invalid calculation resulted in an error and reflects the input:\nI tried to understand the system behavior, tried various injections (sqli, ssti, etc.), sent fuzzed inputs and tried many different kinds of attacks unsuccessfully.\nTrying SSTI:\nAn SSTI (Server-Side Template Injection) vulnerability is a type of security weakness found in web applications. When a web application uses templates to generate dynamic content, it may allow user input to be included in the template without proper validation or sanitization. This could potentially allow an attacker to inject malicious code into the template, which is then executed on the server-side when the page is rendered.\nI didn\u0026rsquo;t find anything interesting (except the internal server error.\nI had fallen asleep and I dreamt about sending some input which caused the server returning information about a service called \u0026lsquo;pop\u0026rsquo; 🤷🏻‍♀️.\nI woke up and thought a little bit. I looked at my SSTI payload and noticed that my payload\u0026rsquo;s syntax might be incorrect.\nI sent a different payload:\nNow I am 100% sure it\u0026rsquo;s an SSTI issue.\nI checked Hacktricks for payloads and tips and used an RCE payload to read the flag.\nWEB - notsogeo This challenge generally asks us to cheat on GeoGuessr games.\nGeoGuessr is an online geography game that uses Google Street View to place players in random locations worldwide. Players must guess their location by examining the environment for clues and then placing a pin on a world map.\nThe challenge provides a source code of a version of this game.\nUsing the source code, we can try to identify a way to guess our coordinates and guess our correct location on the world map.\nI entered into the game.\nThe game source code:\nFrom the challs.json file and other files, it can be understood that those are the locations that will be part of the game.\nWe have to guess the correct coordinates to get the flag.\nThe locations consist of \u0026lsquo;pano\u0026rsquo; (id of the location) and coordinates. However, we don\u0026rsquo;t have access to the files.\nGoing through the HTTP requests, I could not find the coordinates. However, I kept seeing something called \u0026ldquo;panoid\u0026rdquo; which sounded like the location ID.\nSearching Google \u0026ldquo;Find coordinates by panoid\u0026rdquo; results in this Google Street View documentation:\nSo we got the \u0026lsquo;panoid\u0026rsquo; and have to find the Google Maps key. Searching for the term \u0026ldquo;key=\u0026rdquo; results in this:\nConstructing the URL we found in the Google Street View documentation by adding the \u0026lsquo;panoid\u0026rsquo; and \u0026lsquo;key\u0026rsquo; values, gives us the coordinates.\nUsing the coordinates, we select to correct location on the map and get the key :)\nMISC - ChungusBot v3 We can find the Discord bot source code in Github.\nReading the source code we can understand that the flag is divided to four parts.\nThe first part asks to send the URL in the code (which translates to a gif).\nThe second part of the flag will be revealed after we guess the correct coin random flips.\nThird part will be revealed after we send four numbers that will answer the following sentence.\nThe fourth part will be revealed after sending a file that will contain the text \u0026ldquo;You like jazz?\u0026rdquo; and will be 100 or more characters long.\nNow we have obtained all the flag parts :)\nHappy Hacking,\nOrel 👒\n","date":"2023-05-02T15:25:44.197Z","image":"/post/umdctf-2023/cover.png","permalink":"/post/umdctf-2023/","title":"UMDCTF 2023"},{"content":"Playing with Cyber R0nin team,\nHere are several writeups of some of the challenges:\nattack-strategies - WEB\nBank-of-Knowhere - WEB\nBynary Encoding - Crypto\nTime Leap - Forensics\nattack-strategies - WEB Entering the link, we can see that we can choose a folder and a file. Also, we see that there is a \u0026lsquo;show_hidden\u0026rsquo; cookie set to \u0026lsquo;false\u0026rsquo;.\nAfter changing the cookie\u0026rsquo;s value to \u0026rsquo;true\u0026rsquo; we can see the updated \u0026lsquo;folder\u0026rsquo; list, and that flag.txt exists there.\nChoosing flag.txt returns an internal server error\nPressing \u0026lsquo;View\u0026rsquo; returns a general error that indicates that the file/folder does not exist.\nI assume it\u0026rsquo;s because of the fact that flag.txt is not a folder but a file.\nSo I\u0026rsquo;ll try to use LFI to retrieve this file.\nLFI (Local File Inclusion) is a security issue where attackers include local server files in a web application\u0026rsquo;s output, exposing sensitive info. \u0026ldquo;../\u0026rdquo; is used to move up one level in the directories structure, helping them access unintended files.\nBank-of-Knowhere - WEB As the challenge description says, only those with at least $2000 are in the inner circle and can get the secret information.\nWe can see that we have $850.\nI had two ideas - trying to gain more money or trying to retrieve other users\u0026rsquo; information.\nThis is the money transfer request. I tried to send myself money from other usernames, tried to play with the amount, SQL injection, and various attacks but they didn\u0026rsquo;t work.\nTrying to send money to myself (Groot) from another username (Rocket) caused an error.\nThe solution to this challenge is Parameter Pollution.\nParameter Pollution is a security flaw where attackers manipulate web app inputs by injecting extra parameters, causing unexpected behavior and potentially gaining unauthorized access.\nIn the context of this challenge, sending two of the same \u0026lsquo;receiver\u0026rsquo; parameter bypasses the server\u0026rsquo;s restriction. Probably because the check is for the first \u0026lsquo;receiver\u0026rsquo; parameter and it sends money to the last \u0026lsquo;receiver\u0026rsquo; parameter.\nNow we have more than $2000.\nI still didn\u0026rsquo;t see the flag, and I tried to enter different directories like \u0026lsquo;/flag\u0026rsquo;, \u0026lsquo;circle\u0026rsquo;, etc. but didn\u0026rsquo;t find anything. After brute-forcing different directories, I saw that the robots.txt file exists and contains the directory /admin.php\nBynary Encoding - Crypto After downloading the file, it looks empty with a lot of spaces, but trying to delve a little deeper we can notice that the text is tabs and spaces. Combining it with the challenge name and description, we can assume that it\u0026rsquo;s related to binary (base 2).\nReplacing spaces with 0 and tabs with 1 results in this:\nConverting it to text:\nTime Leap - Forensics After downloading the file and decompressing it, we got an .img file which we can\u0026rsquo;t load normally (at least I couldn\u0026rsquo;t when I tried). I opened it with Autopsy and saw the flag as a deleted gif file:\nI hope you enjoyed,\nOrel 🎍\n","date":"2023-04-24T15:24:55.923Z","image":"/post/space-heroes-ctf/cover.png","permalink":"/post/space-heroes-ctf/","title":"Space Heroes CTF"},{"content":"I will share my way of thinking and how I solved two challenges.\nDominoes (Cryptography - 50)\nKnight Squad Shop (web - 100 points)\nDominoes (Cryptography - 50 points) We got the encrypted flag:\nAnd we got the python code which encrypted the flag.\nRed mark: reads the flag and then sends it to the encryption function (y).\nGreen mark: (I replaced an obfuscated character with \u0026ldquo;clearText\u0026rdquo; for readability). For each character in the flag, it makes an XOR operation (^ - I will use it interchangeably) with the XORed value of it (more precisely, with the integer representation of it - A=65).\nFor example, if the flag is \u0026ldquo;BDSEC\u0026rdquo;, the integer representation of \u0026ldquo;B\u0026rdquo; (66) will be XORed with \u0026ldquo;9\u0026rdquo; (57) which is \u0026ldquo;{\u0026rdquo;. Then \u0026ldquo;9\u0026rdquo; XORed with \u0026ldquo;D\u0026rdquo; is \u0026ldquo;{\u0026rdquo; as so on, as can be seen in the encrypted flag.\nIt\u0026rsquo;s possible to make a reverse operation for XOR:\nThe encrypted flag is: 9{?l)j\u0011O;dQa\u0026gt;[oZ#|\u0014A)\u0016I}N}\n9 ^ original_character = {\n{ ^ original_character = ?\nSo I wrote a python code that checks if 9 ^ original_character = {* *and so on.\nEach character of the encrypted message was tested with different characters in order to guess the correct one.\nKnight Squad Shop (web - 100 points) The source code of the web application was provided:\nhttps://drive.google.com/file/d/1cHCasWHdfl21q2XrATET_jy0fDQ2gfMK/view\nAlso access to the web application:\nIt seemed that there is a \u0026lsquo;products\u0026rsquo; object and one of its instances is \u0026lsquo;flags\u0026rsquo; which contains the flag.\nThis is what I wanted.\nHow do I get it? Let\u0026rsquo;s look further into the code.\nThere are two endpoints: /sell and /buy that are responsible for the buying and selling operations.\nSince there was a bug or misconfiguration, I could only try to buy \u0026lsquo;digispark\u0026rsquo;. However, I did not have enough money for it.\nI tried to sell products by manually crafting a request to the* /sell* endpoint and tested some things but I did not see any changes.\nHow can I get more money?\nLooking further into the code, I saw there is another endpoint (/money), that checks if I have an admin session, and if so, it adds the money amount I request in the \u0026lsquo;money\u0026rsquo; parameter.\nAs I thought and as the code says, I\u0026rsquo;m not an admin.\nHow do I get an admin session?\nLooking at the code again seems like the request IP should be originated from \u0026lsquo;127.0.0.1\u0026rsquo; in order to get an admin session.\nBefore continuing a bit of information about \u0026lsquo;X-Forwarded-For\u0026rsquo; header:\nBasically, front-end servers such as proxies and load balancers use that in order to tell the back-end (web application) server from which IP the request originated.\nLet\u0026rsquo;s try it :)\nIt did not work and I have to find another way.\nMaybe if I will cause an error, it will expose interesting information.\nI do not know if it is correct but knowing that asynchronous functions are sometimes vulnerable to race condition + I read that \u0026lsquo;req.ip\u0026rsquo; could be affected by \u0026lsquo;X-Forwarded-For:\u0026rsquo; header, I tried to cause some kind of race condition by adding \u0026lsquo;X-Forwarded-For: 127.0.0.1\u0026rsquo; to the request, and changing the \u0026lsquo;Origin\u0026rsquo; and \u0026lsquo;Referrer\u0026rsquo; headers to this IP address, just in case.\nAnd it worked.\n\u0026ldquo;Money added\u0026rdquo;.\nUsing the same session I added **a lot **of money.\nBut still, I do not have enough money. How is it that my session does not have enough money?\nIs there a chance that the money is added to the session in the \u0026lsquo;Set-Cookie\u0026rsquo; response header?\nI tried to buy the flag by replacing my session with the session in the \u0026lsquo;Set-Cookie\u0026rsquo; header and it worked.\nI tried it again and only sometimes it works for me so I am not sure exactly if all of these steps were necessary.\nAlso, before trying that, I uploaded the source code to Snyk for vulnerability scanning and it found a Prototype Pollution vulnerability, and as far as I understood, it may be another solution for this challenge.\nPlease let me know if there were inaccuracies or any other insights about this solution.\nOrel 🍉\n","date":"2022-07-21T18:34:48.003Z","image":"/post/bdsec-2022-ctf-writeups/cover.png","permalink":"/post/bdsec-2022-ctf-writeups/","title":"BDSEC 2022 CTF Writeups"},{"content":"\nI tried a pretty easy Crypto challenge.\nAfter using Netcat, the server asks us to guess the correct numbers repeatedly.\nAfter looking at the source code (\u0026ldquo;challenge.py\u0026rdquo;), it seemed that the server generates a random number in the appropriate range each time.\nHowever, there is an interesting function - random.seed().\nAfter reading about this function, I understood that it takes a number (the result of the operation inside it) and this will be the seed for the random functions (rand_range).\nOkay, so it is not actually random. The random seed has a fixed value.\nI checked the result of this operation and got a reasonable value, but it did not work after I tried it.\nI thought it might be quicker if I just ran this program in PyCharm after modifying and printing the results for each iteration, and it worked. After connecting to the server, I just used the numbers and got the flag.\nHappy Hacking,\nOrel 🐇\n","date":"2022-07-01T14:47:39.395Z","image":"/post/bsidestlv-2022-ctf-medium-expectations/cover.png","permalink":"/post/bsidestlv-2022-ctf-medium-expectations/","title":"BSidesTLV 2022 CTF - \"Medium Expectations\""},{"content":"Hi, in this updating blog post, I will post answers and explanations of how I solved them.\nThe difficulty levels are Apprentice, Practitioner, and Expert.\nWhat is Cross-Site Scripting?\nCross-Site Scripting (XSS) is an injection attack that allows an attacker to inject scripts into websites that will affect other user/s.\nThe problem arises because lack of input validation and lack of character encoding.\nThe main XSS types are:\nReflected XSS - User input is returned by the web application in the server\u0026rsquo;s response without encoding it to make it safe to be rendered in the user\u0026rsquo;s browser. Stored XSS - The user\u0026rsquo;s input is stored in the database of the target server (for example, after post creation in forums, private messages, etc.), then the victim is able to retrieve the stored data without encoding, which makes it unsafe to be rendered on the victim\u0026rsquo;s browser. DOM-based XSS - This type of XSS is when all the attack flow stays in the DOM of the browser. The payload will not be sent to the server. 1. Reflected XSS into attribute with angle brackets HTML-encoded\nDifficulty: Apprentice\nFirst, I checked which characters were encoded.\nIn the first reflection, all of them are encoded. In the second reflection \u0026rsquo; and \u0026quot; are not encoded.\nI could not escape the element because \u0026lt;\u0026gt; characters are encoded, but I knew I could add an attribute since all I need is the \u0026quot; character.\nI added the \u0026lsquo;onmouseover\u0026rsquo; attribute, which tells the browser to run a script when the mouse cursor is above this element.\n2. Stored XSS into anchor href attribute with double quotes HTML-encoded\nDifficulty: Apprentice\nThe description says there is a stored XSS in the comment section so let\u0026rsquo;s send a comment and check **all parameters **(sometimes only one parameter is vulnerable).\nAfter entering the comment page, we see that all parameters are HTML-encoded except for some characters of the \u0026lsquo;website\u0026rsquo; parameter from the last request.\nI sent a similar payload as in the previous lab. After initiating the script by moving the mouse cursor above the element, the lab was considered solved.\n3. Reflected XSS into a JavaScript string with angle brackets HTML encoded\nDifficulty: Apprentice\nIn short, XSS inside a script.\nAs in the previous labs, I tested which characters are not encoded. I only used these special characters: ; and /.\nI used // in order to comment out all the remaining characters.\n","date":"2022-06-18T19:37:04.237Z","image":"/post/portswigger-labs-cross-site-scripting-answers/cover.png","permalink":"/post/portswigger-labs-cross-site-scripting-answers/","title":"PortSwigger Labs - Cross-Site Scripting Answers"},{"content":"There was a delivery service that was introduced to the company I work for. They allowed employees to order groceries without a shipping fee, and get them on the same day.\nI was curious and checked a couple of things on the website (security-wise). There were many requests, and I tested some things. After not finding anything interesting, I stopped.\nI got back to it a few weeks or probably months later. I really wanted to find something in there, especially since I did not find anything the last time.\nNow, this platform usually targets companies and after an onboarding session with a representative, they give you some credits. I will get back to it later.\nI registered an account. I wanted to see if there was something interesting on the account\u0026rsquo;s profile page, so I went there.\nLet\u0026rsquo;s see what happens when I press \u0026ldquo;Save\u0026rdquo; for the account\u0026rsquo;s details.\nHmm, the server\u0026rsquo;s response contained parameters that caught my eye (\u0026rsquo;store_credits\u0026rsquo;, \u0026lsquo;onboarded\u0026rsquo; and \u0026lsquo;verified\u0026rsquo;).\n\u0026lsquo;store_credits\u0026rsquo; probably refers to money and the \u0026lsquo;onboarded\u0026rsquo; parameter refers to the onboarding process I mentioned earlier.\nI added the \u0026lsquo;store_credits\u0026rsquo; parameter to the request in order to change my credits. Sending normal values or unexpected values did not change the number of credits.\nLet\u0026rsquo;s try to change the \u0026lsquo;onboarded\u0026rsquo; and \u0026lsquo;verified\u0026rsquo; values to \u0026rsquo;true\u0026rsquo;.\nOkay, it worked and now I am onboarded and verified. Wait for a second, I also gained credits (3000 credits which are equivalent to 30 New Israeli Shekels)!\nLet\u0026rsquo;s try to send it again, maybe I will get even more credits!\nUnfortunately, it did not work.\nSo we have an authorization bypass here. We can onboard and verify our account and get credits for that.\nThen a thought came to my mind and I asked myself - is there a chance there is a race condition here?\nAs per the OWASP testing guide: *\u0026ldquo;A race condition is a flaw that produces an unexpected result when the timing of actions impact other actions\u0026rdquo;. *\nFor example, in this web application, if there is a race condition, the system will process these requests simultaneously while increasing my credits over and over before noticing that my account is already onboarded.\nI created a new account (with 0 credits), prepared the same request, sent it to Burp Suite Intruder (a tool that automates attacks) and sent it many times using a large number of concurrent requests.\nThis is what I got from the server\u0026rsquo;s response. It looks like it did not affect the credits and I only got 20 NIS. **😭 **\nAlso, on the catalog page, it seemed that I only got the 20 NIS discount.\nI probably wanted to test further issues when I entered the cart and was surprised to discover that it worked and I have a discount of much more credits than I should have (I should have 20 NIS discount and got 60 NIS).\nHere I could get only 60 NIS, but I also succeeded to do that with 120 NIS.\nRace condition is fun!\nHappy Hacking,\nOrel\n","date":"2022-06-02T17:04:46.359Z","image":"/post/a-race-against-time/cover.png","permalink":"/post/a-race-against-time/","title":"A Race Against Time"},{"content":"I will probably update this post with new examples and screenshots.\nOne of the features I like to test the most is the \u0026lsquo;forgot password\u0026rsquo; process. Since it may lead to account takeover, or sometimes it is like a riddle that you have to solve by understanding its logic.\nIn my opinion, the probability of \u0026lsquo;forgot password\u0026rsquo; issues in a web application is 6-7/10. So it is not very common, but not that rare.\nSome web applications require entering the target email address or username. Then they send an email with the \u0026lsquo;forgot password\u0026rsquo; link. Usually, there is a form there that asks for a new password. While intercepting the request, sometimes the username is sent next to the \u0026lsquo;forgot password\u0026rsquo; token and the new password. The \u0026lsquo;username\u0026rsquo; parameter tells the server to change the password to this account. Note that this process could be combined from several requests, so the whole process should be understood. Another example is a guessable token. Some tokens or \u0026lsquo;forgot password\u0026rsquo; links are combined from guessable data, such as company IDs, timestamps, iterators, etc. An example of such a link is: Let\u0026rsquo;s say that the \u0026lsquo;c\u0026rsquo; parameter is company ID, \u0026lsquo;i\u0026rsquo; is an iterator, and \u0026rsquo;t\u0026rsquo; is some kind of another iterator, maybe an encrypted timestamp.\nIf we send another reset password request to the same user, we will probably get this link:\nAs we can see, the \u0026lsquo;i\u0026rsquo; parameter\u0026rsquo;s value has been increased by one, and the \u0026rsquo;t\u0026rsquo; parameter\u0026rsquo;s value (in Hexadecimal) also increased. The company ID could also be guessed easily if it is a sequential number or by using other ways.\nNow we can send ourselves a reset password request and very fast after that, send a reset password request to our victim. We use the values in the link that was sent to us in order to guess the parameters\u0026rsquo; values of our victim.\nWe know that the \u0026lsquo;i\u0026rsquo; value was increased by 1, and we probably know or can guess the victim\u0026rsquo;s company ID. An automated tool can be used for this attack (such as Burp Suite\u0026rsquo;s Intruder) and only a few characters should be guessed. It should take a short moment before guessing the correct link.\nOne of the requests in the \u0026lsquo;forgot password\u0026rsquo; process may send the user\u0026rsquo;s credentials in the URL. These credentials may be saved in proxy history, browser history, etc. Malicious users who have access to these areas may try to log in or steal the account.\nTokens that can be brute-forced and are guessable (such as \u0026lsquo;9389913\u0026rsquo;), even if they are random, may lead to account takeovers.\nTokens that are not expired after a limited and short amount of time increase the chances of being discovered. Also, allowing several valid tokens at the same time.\nA very common issue (with a very low impact probability) is \u0026lsquo;forgot password\u0026rsquo; tokens sent to 3rd parties. Usually, after entering the \u0026lsquo;forgot password\u0026rsquo; link sent to our email address, there an analytics and logs requests sent to 3rd parties. These requests usually contain the reset password token in the \u0026lsquo;referer\u0026rsquo; header or one of the GET or POST parameters. Data leakage from this 3rd parties website, or a malicious user who has access to this data, may compromise users using these tokens. The probability of this attack is increased as the token expiration is higher.\nReset password poisoning - sometimes, we can try and send a reset password request with the \u0026lsquo;Host\u0026rsquo; or \u0026lsquo;X-Forwarded-Host\u0026rsquo; headers containing the attacker\u0026rsquo;s server URL. There are cases where an email message will be sent to the victim and contain a link with the attacker server\u0026rsquo;s URL, and the \u0026lsquo;reset password\u0026rsquo; token attached. After the victim enters the link, a request with the \u0026lsquo;reset password\u0026rsquo; token will be sent to the attacker\u0026rsquo;s server. Sending two email addresses - some web applications will also send the victim\u0026rsquo;s token to the attacker in case a similar payload is sent: email=victim@gmail.com\u0026amp;email=attacker@gmail.com In other cases, instead of using \u0026lsquo;\u0026amp;\u0026rsquo; we can try other characters or URL encoding of them.\nEmail flooding - some systems allow sending many \u0026lsquo;forgot password\u0026rsquo; requests without any anti-automation mechanism or other limitations. By sending many requests, we can flood our victim\u0026rsquo;s mailbox. Thank you,\nOrel 🌷\n","date":"2022-05-20T22:46:33.954Z","image":"/post/forgot-password-vulnerabilities/cover.png","permalink":"/post/forgot-password-vulnerabilities/","title":"Forgot Password Vulnerabilities"},{"content":"This is a story about the importance of testing the less popular areas in web applications.\nDuolingo gives experience points for different actions on the website. For example, doing challenges.\nBy increasing the XP points, you go up on the league board.\nSo I joined a league and unfortunately I only have 8 XP.\nIt is essential to understand the flow of the web application\u0026rsquo;s processes and not miss requests and features that seem like edge cases or are not widely used. Because in a lot of cases, they have issues.\nSo back to our example - Duolingo lessons have a different levels (1-5 and \u0026ldquo;Legendary\u0026rdquo;). The \u0026ldquo;Legendary\u0026rdquo; level contains a lot of questions and for that, they \u0026ldquo;promise\u0026rdquo; 20 XP for those who finish just half of the questions.\nSo let\u0026rsquo;s intercept the traffic just before we arrive the middle of the lesson.\nI answered the question (the answer was \u0026ldquo;The bear is beautiful\u0026rdquo;) and quitted the lesson.\nThey asked me if I am sure and I said \u0026ldquo;Yes!\u0026rdquo;. Nothing happened so I clicked \u0026ldquo;Yes\u0026rdquo;.\nThere were many requests and after finding the request I searched for, I went through all of the parameters (and there were many of them).\nThere were some interesting ones, and one of them was \u0026ldquo;xpPromised\u0026rdquo;.\nXP promised?? Only 20? Can you please promise me more?\nI changed it to 1329 and it looks good for now.\nLets check the league chart.\nYay, I have 1337 points! Sorry Dena.\nHappy Hacking,\nOrel\n","date":"2022-05-14T21:20:43.78Z","image":"/post/duolingo-unlimited-xp-points-yes/cover.jpg","permalink":"/post/duolingo-unlimited-xp-points-yes/","title":"Duolingo - Unlimited XP Points"},{"content":"I have a friend who studied in a popular academic institution. I happened to be in his house and I said why not \u0026ldquo;look\u0026rdquo; at their website real quick? They had this new area on the website where all the personal information exists.\nIt really took only a couple of minutes to find a very critical IDOR (authorization bypass) issue. The issue was that it was possible to (probably) retrieve all the grade chart which contains all of the grades and other personal information of all the students.\nFor those unfamiliar with the term IDOR (Insecure Direct Object Reference), it is a vulnerability that allows to refer and access an object that should not be authorized to the user.\nSorry in advance for the massive redaction and lack of evidence, I do not want to cause any problems for my friend.\nAfter asking for the grade chart, a POST request was sent and in its body, there was this suspicious parameter (which I am not sure if it is the grade chart ID, the student ID or something else. I did not delve into this).\nI edited the \u0026ldquo;ptMsl\u0026rdquo; parameter\u0026rsquo;s value, which of course was a sequential value (which is a problem by itself) and sent the request.\nAfter that, there was a request or more that contained some unique identifiers (that originated from the malformed request) and then I saw a grade chart of another person.\nAn attacker could automate it to probably retrieve all of the students\u0026rsquo; grade charts, which is very bad for the institution\u0026rsquo;s reputation (in addition to the fact that students\u0026rsquo; data were exposed).\nI am publishing it after I verified it was fixed, but the fact this absurd issue exited (and for a long time), it is not hard for me to believe there are more issues like this on the website.\nSecure development training is very important for websites that contain sensitive data.\nHappy Hacking,\nOrel\n","date":"2022-05-14T19:10:28.188Z","image":"/post/simple-idor-with-critical-impact/cover.png","permalink":"/post/simple-idor-with-critical-impact/","title":"Simple IDOR With Critical Impact"}]