{
  "path": "/blog/hackinghub-writeup-naughty-or-nice",
  "site": "at://did:plc:5fyfskntvw6jltxmdu2we7nw/site.standard.publication/3mdro5atvvd2o",
  "tags": [
    ""
  ],
  "$type": "site.standard.document",
  "title": "Hackinghub Writeup - Naughty Or Nice",
  "publishedAt": "2026-01-24T00:00:00.000Z",
  "textContent": "https://app.hackinghub.io/hubs/naughty-or-nice-mission\n> Oh no… NahamSec has somehow ended up on Santa’s Naughty List.\n\nThis CTF is for a web-page that checks if you're on the naughty or nice list. \nUnfortunately, I'm on the naughty list. That doesn't sound right, thankfully I can create a support ticket!\nEven better, sending this support ticket revealed some interesting API endpoints! Maybe I can fix this myself.\nRecon\n-  The site has an API with many available endpoints. Viewing /js/assets/app-CZsgTrKP.js reveals many of them.\n\t- /api/teams - all teams\n\t- /api/teams/{uuid} - information about teams, including users\n\t- /api/user - info about current user, need to be logged in\n\t- /api/user/{uuid} - returns uuid, username, and online status.\n\t\t- all of the endpoints listed so far are used by /submit-ticket to choose the teams and team member to send your ticket to.\n\t- /api/user/{uuid}/workstation - user workstation names\n\t- /api/audit-log/\n\t- It also had a link to a github page: https://github.com/xmas-tools-llc/audit-logger/blob/main/log.php\n\t\t- We can assume this tool is being used by the site, and it appears to be vulnerable to SQL injection.\n- Discovered via fuzzing (although they're also in robots.txt)\n\t- /backups\n\t- /audit\nI found it interesting that there's a /api/audit-log endpoints, as well as an audit endpoint, so I checked that out first. \n- /api/audit-log - returns \"error\" : \"API endpoint not found\"\n\t- strange, since its called in the js file. other invalid endpoints return the same generic error.\n\t- I later realized visiting /api/audit-log/ (with the trailing slash) did work. \n- /audit returns a page, but wants you to be logged in. I'll come back to this.\n- /backup returned a directory listing that contained our first flag and an SQL DB dump\n\t- The dump only contained users I'd already enumerated, but it gave me info on the DB structure. \nBypassing local authentication check\nFrom having quickly scanned over the earlier JS file, I recognized that the audit page seemed to be doing authentication locally. In particular, I noticed this line:\n\nI visited this with breakpoints enabled and captured the response from /api/user, modifying it to match the output given by /api/user/{uuid} with a real user, but removed the status value and added an admin value. \n\nAfter letting this modified response through, I gained access to the page, which gave me a second flag. This page was related to the vulnerable code from the Github repo I found earlier, and I could see the values was using to create execute SQL statements.\n![[Pasted image 20260109232758.png]]\nSQL Injection\nThis is the vulnerable logging code:\n\nThese values are being unsafely inserted in the database, and one of them can be controlled by attackers. From the above screenshot, we can see that an event is logged everytime a ticket is created. By modifying the POST request to /api/ticket and adding X-Forwarded-For: 127.0.0.1, I could see a new event appear that included this IP.\n> Ticket Created -- 2026-01-10 04:33 -- 127.0.0.1, 10.18.1.6\n\nIf I added a ' to the end of this value, no new event appears, meaning the SQL injection was likely successful and caused an error. I used the following payload to get the table names: audit and users.\n\nWe already know that audit contains these logs, so I started enumerating the users table. \n\nAfter getting all these user and team UUIDs, I went back to the earlier API endpoints to and ran fuzzers with the values to see if there's was anything interesting. \n- /api/user/{uuid} output was uninteresting, just providing their UUID, name, and online status. \n- /api/teams/{uuid} interestingly only responded with the two teams I could already view from the support-ticket page. The DB dump contained 5 different team UUIDs. Maybe I need some sort of authentication to view the other three.\n- /api/user/{uuid}/workstation - One of the newly found UUIDs responded with my a flag! Surprisingly, this is the fourth flag, meaning I missed something I was expected to find between the last one and now...\n\t- This user also had the only workstation with a DEV hostname: ELF-DEV-TWINKLE-33, which I assume will be useful.\nBack to the basics\nAt this point, I got pretty stuck. I was kinda just banging my head into the wall trying random things. Eventually, I realized I need to go back to the start. I went back to enumeration, looking for directories in way I hadn't tried previously. Eventually I tried using ffuf to search the API directory with the flags -mc all -ac.\n- -mc all - Match all response codes\n- -ac - Automatically calibrate filtering\nThis will often give you a decent amount of false positives, as it's basically returning anything that has a different response than most of the other requests.\n![[Pasted image 20260127212310.png]]\nIn this case, there were a few php endpoints which gave a different error code. This is likely just caused by the nginx configuration, as it gave a generic nginx 404, instead of the custom webserver 404. \n\nProxy was the interesting new find. Although it returned a 415 (Unsupported Media Type), the response was {\"error\":\"Method not allowed\"}. Not sure why it didn't return 405, but either way it responded differently to a POST request: {\"error\":\"JSON Payload Invalid\"}.\n\nAbusing an open proxy\nAfter param mining with arjun, I found 4 parameters: headers, method, body, url.  Using these, you can make requests through the proxy. My first thought was to see if I could access the workstation I found earlier.\n![[Pasted image 20260128203625.png]]\nUnfortunately, we don't get any error message when a request fails, so we'll just have to look for one that succeeds. I decided to keep testing this host, so I wrote a simple script that makes a request to this endpoint with the top 1000 ports, then I filtered the response to find one that contained a body. With this method, I found this response from port 5000:\n![[Pasted image 20260128204001.png]]\nAfter trying some random tokens, I get this helpful error:\n\nWith some research, I found that this points to a python pickle deserialization attack, which is very simple to exploit. I generated a reverse shell payload and quickly had a reverse shell.\nWith this shell I found a .env file with a hidden API endpoint and an authorization token:\n\nBy making a request to that endpoint with the Authorization header set, we get a list of names and their IDs, one of which was NahamSec. With some further experimentation, I found I could make a request to /api/sup3r-s3cr3t-admin/{id} to get more info about an entry.\n\nI sent a simple PUT request to update verdict to Nice, and there was the final flag!",
  "canonicalUrl": "https://quasigod.xyz/blog/hackinghub-writeup-naughty-or-nice"
}