Back to pentest fumblings!

I’m back, baby! I fell back into the old lines. It took a few months, but I went from “Okay, I’ll go into the blue team for some more calm and a stable work environment” to “Well, since the pentests are already there, mind if I snatch one up?” This is my comfort zone. This is my happy place. After all that happened in the last 3 months, it’s good.

But this is not a life post, this is a post about me fumbling around in a pentest, full of fun and honest hilarity!

What happened

To set the stage, I guess I’ll dedicate a paragraph or two to what actually happened. I started my cushy blue-team job, met some great guys, and after 3 months and 2 weeks, I got told “Well, there’s no place for all you in this company. We got you a fallback plan, so you can either go and collect 3 paychecks, or move to this new part of the group.” This was a shock, but I thought what the hell, my colleagues are moving too, so I might as well. Can’t be that bad, can it?

For my colleagues, it kind of was. They got a lot of bullshit thrown their way the first month, and they went back to the old company. I stayed, because the company I was moved to has tons of pentest requests, literally companies coming to them saying “Hey, you do pentests?” and they had to throw those to a subcontractor. Small money, and dependent on the work of a third party.

Not anymore!

My first pentest - the client

The first pentest I got under the new banner was an application made for a national agency. Custom-made by a company that specializes in that public tender market that I have no clue about. Well, it turns out this was their first pentest ever. That’s scary. They have no idea what that would mean for them, and what I’d output for them. There was a lot on the line; even though this came through a former colleague of mine, it’s still a lot to take in: You’re “breaking in” a company in terms of security testing, and it can either make or break them. I made a promise that I wouldn’t tell them it’s all shit and that they should just scrap it and rebuild… How wrong I was.

The first day

After all the setup and preparation, it was finally time to get stuck in. This was last Monday, and I specifically told them: During testing, you can be there, but I don’t want to see any patches and updates, reboots are not authorized unless I fuck something up, just let me and my buddy cook. I connect to the VPN, and I get a call. It’s the former colleague

“Hey, buddy, I know we said we’d start today, but they’re still pushing some small updates.”
“Okay, how small and how long will it take?”
“Well they’re pushing the September updates now, so it should be ready by Wednesday.”

Are. You. Shitting. Me?! I spent a week getting ready for this, the pentest was supposed to start on Monday, and now I gotta wait 2 more days? Okay, I don’t want to be an asshole to them, so I let it slide (but will bill them, obviously.) I thought it would be a perfect time to get some proper recon done, and I just walked through the app, not touching anything too much, not being noisy, just getting the hang of the application. This was no small feat, as the national agencies make sure the software is as shit as possible and that any company that makes it is absolutely indispensable.

SDLC? That just happens to other people, right?

I started out by putting the application through Burp Suite, starting the app and trying to log in. It did not work. I tried again, and nothing. I tried all the accounts in turn, and nothing worked. I contacted my first point of contact, he told me he’d get back to me right away. In the afternoon (about 4 hours later), he got back to me, saying “No one knows why it’s not working, call this guy.” I called, and found out that the application has several different login types: One is through AD (which I don’t have in Kali), and the other is directly, but that is on a different URL which I couldn’t find (think “mycoolapplication” and “mycoolapplication-direct”).

After that was sorted, I could get in the application and get my first whiff of the underlying libraries. It downloaded a well-known javascript library with the suffix “latest?v=X.Y.Z”. I though it’d be fine, the number sounded vaguely familiar, but I’d look through the source anyway. Boy am I glad I did, because the X.Y.Z was not the version of the library, but the version of their application. The “latest version library” was 11 years old and 2 major versions behind. Jeez, that was horrible! After checking Burp again, I found out that this was not the only instance. There were about five libraries in total, each 10+ years old, all of which had several high-impact vulnerabilities.

Great. I wanted to ease them in, and here I am, staring at something I wouldn’t want to touch with a ten-foot pole.

One finding to start them all

Next, it was time to do something I learned during my stay at the full-blown pentesting company. Bang on every input and see what falls out. Looking at the app, it’s all Javascript, and looking at the HTML of the website, my search result was written to a <td> field. I thought “Okay, let’s just try this for fun, what if I can escape it! It’s probably got filtering, but I can always try.”

I created a </td\> to escape the field in the search bar and attached some basic XSS code, not hoping to see anything…

It fucking popped. There it was, the pop-up telling me these people did not sanitize shit in their application. At that moment, I knew this would be fun. I rate all boxes on HackTheBox difficulties, and now this turned from a medium/hard to an easy box in the blink of an eye. I had no idea that this was even possible, this was using a well-established platform to create the pages and the functionality, did it not do anything?

There was one more finding that I found interesting. I could jump out of the field using td, but when I did, something flashed across the screen really fast. It appeared to be an error log. Was debug on? Was the server telling me something? Nope, it was the frigging SQL function that failed on me. Just by me including a usually harmless closing tag in my search, the server vomited up a torrent of code my way. Most of it was useless, but hey, two findings better than none. Then I thought: Since they’re not filtering on any special symbols, could I just write my own HTML in there? Could I write an iframe to get a ping to my server? It felt too good to be true, this was no longer hunting for misconfigurations, but just walking down a corridor and seeing the mold under the plaster.

I will not prolong this, this one tiny search bar led to RFI, XSS and a DoS (the server really did not like me poking around the insides.) These were all reflected, however, and I couldn’t really send a link to a victim because all of it was in individual iframes. I could steal cookies, but not much beyond that.

Dressing up in LaTeX

The next thing I saw was the “Documents” tab up top, so I thought I’d poke around there. I created files, folders, messed about with XSS again, but no dice. That sidebar was uncrackable. There was one function that caught my eye after a few days (I did not open that specific menu, and it was 4 different clicks deep just to get to what I saw then): Generate report.

This should be fun! I generated a report, got the PDF, and looked on in disappointment as none of my XSS/SQL attacks showed any promise. I downloaded the PDF for future reference, messed about with IDOR for a while, and then I got back to the document. I realized that I had no idea how it converted HTML input into PDF. It looked too clean, too scientific. Sure enough, the library generating it was Tex2Pdf. Well, this is interesting! Government employees using LaTeX? Most I know only knew latex as that weird clothing. Worth a shot!

I checked again what got written into the report. It took folder names, folder changes, and the time. I couldn’t really change the time, but now my injection attempts took on a whole new direction. We were away from home, into unknown territory. I only wrote LaTeX for a few months before moving to markdown, so I had reading to do. Apparently, there is a magic function that makes writing chapters fun! the \input{FILE} tag. If you create a document with \input{chapter1.tex}, it will include the first chapter, so you split your book into more manageable segments. I’m probably preaching to the choir here and you’re shouting that I’m an idiot for not knowing this by heart, but hear me out… LaTeX sucks.

Nevertheless, after trying some LaTeX injections, I went for a hail mary. This was 4 days before the end of the pentest, so quite a long way in, and I thought I’d find nothing more. I put in my payload and hit Generate PDF.

The first line read "root:x:0:0:root:/root:/bin/bash"

I could not believe my eyes. It was really there, the full /etc/passwd file for the server this report was generated on. I got LFI! This app was thoroughly broken. I changed up the payload for /etc/fstab and tried again…

…and I got /etc/passwd again.

What? That shouldn’t be possible. The timestamp of the file said it was generated a second ago, yet it showed me a 10-minute old log! What gives? I tried in a new folder, which seemed to fix it, and then tried to get a reverse shell using \write18{REVERSE SHELL}. That did not work, and no other log PDFs came after that. Just the last one. After a full fucking day of calling my point of contact, I just told them “Please reboot the server.” I tried explaining it to them, but the only answer I got was “Nah, this could not happen, nothing wrong on our end!” Sure enough, after a reboot, it worked off and on. We got LFI, but the process hung up after the first LFI attempt. Call me a coward, but I did not want to waste the last precious days hunting down something I already proved could be done. I was done with that vector, and it was proven beyond a doubt that no filters were in place at all. Using the same log generation process, I managed to store my XSS (and hide the evidence), grab userIDs like it was Black Friday, and my colleague stored the RFI to the extent that when you visited the site, it just downloaded malware to your computer (not real malware, just a reverse shell pointing to localhost.)

What the future holds

Well, the report is almost written, and I don’t want to be the one handing it in, to be quite honest. It’s a broken down application held together with duct tape and string, but it does fulfill a critical function, so I hope they get it in order. As for me, I got an internal network pentest coming next week, so I’ll be busy.

See you in a couple of months again!