This video demonstrates how to exploit Server-Side Template Injection (SSTI) vulnerabilities in Flask web applications to achieve Remote Code Execution (RCE), and subsequently gain SSH access to compromised systems by extracting user SSH keys and adding public keys to authorized_keys files. The instructor emphasizes that while AI tools can assist, learners should actively troubleshoot and research solutions independently to develop deeper understanding and long-term learning skills.
Deep Dive
Prerequisite Knowledge
- No data available.
Where to go next
- No data available.
Deep Dive
Odyssey - Part 2 - (Hack Smarter Labs!)Added:
Hello, and welcome back. This is part two of working through the Odyssey multi-chain lab on the Hack the planet platform. You may also notice that there is chat all over the screen. Guys, I make these videos while I live stream.
There are over 110 people right now in the live studio audience, but you're missing out cuz you're not here. So, I just hit my microphone. Make sure you subscribe and hit the bell notification so you're notified the next time I am live, and then you too can be in the live studio audience. But, we're going to continue right where we left off at the end of part one. And remember at the end of part one, we discovered server-side template injection in a web server, and I gave you a challenge. I wanted you to try to get RCE on your own, and in this video, we're going to stumble through it together and see, "Hey, can we get RCE together?" So, if you're able to do it on your own, honestly, can kudos.
What did [laughter] the I'm making up words. Kudos and congratulations. If not, that's totally fine as well, but make sure as you are watching me, you're not just watching me, you have hands on keyboard, and you are hacking alongside of me. So, let's go ahead and dive in and pick up where we left off on our enumeration. I'm also uh totally going to do some production.
Nope, nope, not that. Do production live.
I don't need to be this large as we're hacking stuff. I don't want to cover the screen. There. I'll make myself smaller in the corner. Now, as we go through our documentation here, we were on hacktricks. And remember, we use config in order to dump all the configured environment variables. What we want to do is figure out a way, preferably, to get remote code execution. I'm going to skip all this stuff. I just want RCE.
Just give me RCE.
Okay.
RCE escaping. Having recovered that and called subclasses, we can now use those classes read and write files. The call to subclasses gives us the opportunity to So, I might have to enumerate subclasses.
I'm not sure. This is yellow. Can we read Etsy password and just like script kiddie our way through this? Let's find out.
>> [laughter] >> You cannot. Cannot create list reverse iterator instances. Most recent call last. We do see what what honestly might be helpful is we do have a full stack trace here.
So, we do see the full file path. We're in opt Odyssey virtual environment lib Python blah blah. We're running as a Flask app, which you already knew.
But, uh I bugged out. So, let's continue reading.
See what we're able to do. Calling OS popping. I don't think these are going to work.
>> [clears throat] >> Just going to glance through this page.
We might have to figure out classes. We might have not have to. Let's continue reading. Let's check out this blog.
Now, guys, I will say I know the temptation is to use AI at this point.
There's There's something that helps when you do the old way of just like looking through random blogs and learning that way. I feel like it helps it stick better when you're learning.
So, shout out to Red Bucket, I think is the name of this author.
All right. So, they are trying this.
Using get_flash_messages.
Let's try to yellow that instead of doing classes.
Ah, okay. We have RCE now.
We have discovered RCE. Let's go and add that to our notes.
We'll just I'm going to delete this, and I'm just going to call this getting RCE like a real hacker.
There we go. That's how That's how you do a pen test report. You You write it in leetspeak cuz then they really know that you're a real hacker.
AI, is this machine that difficult? Uh so far, it's not, but I think the machine's going to get much more difficult. Now, what I'm saying is people who are learning something new nowadays, it's so easy to become overly reliant on AI that the moment something does not work, the moment you have an error, the moment you have a bug, you immediately copy and paste it into AI instead of trying to troubleshoot it on your own and doing a little bit of research. And although you might get the answer, I feel like it short circuits your learning, and it it will make the long-term memory and long-term learning for you more difficult. I I think studies have shown that. It's not just me saying that, but Anyway, so we're using the get_flash_messages global built-ins open, and then we can read any file that we want. We're opening the file, and then we're reading the file. That's what's going on here, and we'll discover a screenshot showing that we were able to do this.
We'll just grab a little bit of it. We don't need the full thing.
>> [clears throat] >> Overgrown carrot said, "For your pen test report, just write you got pwned, yo." And give them that exactly.
That's how the real pen testers do it.
That's how the real red teamers like Ryan do it, I'm sure. He just says, "Get Get wrecked, noob."
That's how his pen test report says.
Just get wrecked, noob.
Where did you find the command? Again, yeah, just a random article. I can drop it in chat. Shout out to Red Bucket, whoever that is.
>> [clears throat] >> Just Googling around.
That's how the hackers making the real money, too. It's exactly.
Now, real quick, we could see if we look at our uh Etsy password file, we actually see some interesting information. We have this gil_sa. So, something of a service account here.
I'm assuming that's going to be the person we end up compromising.
Now, at this point in time, there's multiple things we can do, but what we want to move towards is trying to get a full shell.
Okay. So, we do possibly have to find the class here for Jinja in order to get full RCE. Says, "Now that we have identified it in the posting functionality, it's time to help ourselves and escalate it. Our goal is to get code execution, and to do so, we mean we may not need code execution.
It depends what permissions are Flask user has. I'm I have a few ideas in my mind. I doubt they will work, but we know that there's this gil_sa user. It's always worth an easy win. So, what if I'm going to copy this right here.
Okay. What if we can read gil_sa's private SSH key, knowing that key-based auth is enabled, and then we can just authenticate with their key?
It's It's an easy win if it works. If it doesn't work, that's fine.
But, I always suggest, especially on an exam like the OSCP, keep it simple. Do the simple things first.
So, what if we do this?
SSH id_rsa. Can we read his private key?
It would appear that we cannot. No such file or directory, and I'm guessing it's because we don't have permissions to read it.
We could try just like can we even read inside their folder?
No, we cannot.
Okay.
It was worth an easy win.
I did the right path, right?
Yeah, okay.
It was worth trying an easy win, but let's jump back over to this.
>> [clears throat] >> We won't be able to read Etsy shadow.
Etsy shadow is going to be reserved for the root user. I'm assuming that this is not running as root. I mean, I guess keep it simple. We can always try it.
Yeah, I know I didn't think it would.
Make sure my command syntax is working, though. Let's make sure we can still read Etsy password. We can. So, my syntax is correct. We just don't have access to things like Etsy shadow or gil's private SSH key as a quick win.
All right. Let's jump back over to this.
>> [clears throat] >> Okay. I don't Our goal is to get code execution. We need to enumerate all items in the Flask configuration object.
To find the right item to call. The config items are usually stored in the form of a global dictionary. The class that provides command execution attributes is in the OS module subprocess.Popen class. Finding the class is a bit tricky in the Flask framework and needs some digging to get to it. By default, when injecting the vulnerable application with config items, it would return only the global attributes that exist in the current Python environment, such as the app environment, sensitive information about the database, secret keys. I mean, we already checked config items, didn't we? Or config or something? Let's just do that. We'll follow along with the blog.
Yeah, we already did that.
Any other attributes needed from other libraries must first be loaded to the global config object to be callable.
To call the subprocess.Popen class, we need to load the OS module before using it. We can do that with the from object.
Okay.
When inserting config items again, you will see the OS method like y with continued exit status.
Uh interesting.
So, he's walking through. Next, we search for the subprocess class in the config object with the MRO method research order. MRO's an algorithmic way of defining the class search blah blah.
We start at the object's root index one and list all available classes.
All right. Let me just see if this works.
>> [clears throat and cough] >> Okay.
Seems to work, but you know what I'm going to do? Just so we can keep this a little bit cleaner. Let's capture this with Kaito, so we can see the output a little bit easier here.
Okay. That doesn't show the output a lot easier, but we can at least see the classes and things of that nature. Let's continue with our blog.
So, we have callable classes, and I think I saw that.
Well, that looks very bad.
Raw isn't going to look much better.
Uh but we have class type. Yeah, so class type class async generator bit array editor byte array bytes iterator blah blah blah.
There are 784 inherited classes. So to select the subprocess P open class, we need to get the index number of the class. We can do that with the index method in which we pass the class name and its position in the array.
What?
That's Where's he passing that?
We need to get the index number of the class. We can do that with the index method in which we pass the class name and return its position in the array.
Guys, for some reason I think we are overcomplicating this.
I have gotten RCE in Jinja without having to like enumerate classes. Am I making this up, guys? Are we overcomplicating this? You guys tell me. I'm going to literally reference my own course in just a moment cuz I think it's Jinja that we do on there.
All right, I'm going to reference my own course.
Oh, but I don't think I showed it in the course.
Let's find out.
I'm going to stop sharing my screen for just a moment while I log into the back end real quick and we're going to reference my own my own foundations of web app pen testing course because I don't recall ever having to like find classes like this for getting RCE. And so I think we are in a rabbit hole right now and we're making this significantly more complicated than it needs to or at least these blogs are making it significantly more complicated than it needs to.
So, in my foundations web app pen testing course, I talk about SSTI at some point in time.
Okay.
I have an SSTI lab here.
Yep, so Jinja 2 researching the payload we need to break out the template sandbox by doing that exploitation RCE.
Yes.
Thank you, Tyler. Let's see if I'm right.
You guys see that? I'm telling you my foundations of web app pen testing class even helps me.
So, if you had access to my course, you could think, "Hey, I discovered server-side template injection.
How did Tyler teach me how to exploit that again?" And I I literally like what's cool about my course is I have a video, detailed video, but then also text underneath each video so you can quickly scroll through and figure out what we need to do.
So, we were able to get RCE thanks to thanks to my foundations of web app pen testing course. So, now that we I I don't know what this was doing. I I feel like there must be a reason for this very much longer complex way, but I don't know what the reasoning is.
So, I will drop this in chat if you guys want to do it as well, but this is directly from my foundations of web app pen testing course and you can see that we do interesting we do have RCE as the gill essay user.
And I'm guessing we could enumerate the file paths here or we could try to get RCE like a reverse shell. I'm curious about this gill essay user whether or not they have SSH set up. Now that we have full command execution, we should be able to do something like LS home.
Let's just see the output of that. So, we have gill essay Ubuntu.
So, LS home gill essay.
I'll do LS LA.
Oh, hey, we got a membership for 1 month super membership. Thank you. I use LLMs all the time, Tyler. I don't know whether my research things is lower. I just needed to. No, I use LLMs all the time as well.
I would just say when you're troubleshooting try not to be overly reliant on LLMs.
>> [clears throat] >> Anyways, we have a few files.
We have bash history.
And do we have I don't see SSH here, but we could just set up our own SSH. Let's see if there's anything in bash history.
Whoops.
We cat that out.
Okay.
Cat authorized keys authorized keys.
Ah.
So, do we have He should have an SSH folder then, right?
Not cat, let's LS that.
Authorized keys.
Ah, here's our private key.
It's not ID RSA, it's ED255, but that should be our private key. Now, if we back out one more time, we should be able to cat out that private key.
Boom.
We just got the private key for our user. So, you could have done, you know, your typical reverse shell, but if we can get SSH access, it's going to be make our life a lot easier. And you know what I need to do is add this to our notes. So, let's jump back over to our notes and we'll say retrieving the SSH key for gill essay, I think is their name.
We're doing the Odyssey machine rewired.
This is part two of us working through Odyssey. We don't yet fully have initial access, but I think we just likely got initial access. So, we have our ID ED255 private key. We just have to fix the formatting slightly.
We'll render it here and I'll just grab the output.
And I think all you have to do to fix the formatting is just add those and I'm going to copy this now.
Control C.
And I'm going to do a nano um Oh, actually no, that's not going to be the correct formatting. Here's where AI is going to be helpful.
Uh cuz I don't remember the exact formatting for this type of key type.
I'm going to stop sharing my screen just while I log in real quick.
And we'll just use a completely free version of Gemini. I think it's free.
It's hooked up to my personal Google account.
Fix the formatting of this key.
Things like this are super helpful for uh LLMs.
And maybe the formatting is right. Maybe I'm just throwing myself off here.
So, this is a Linux machine running it.
So, this is actually multi-machine lab.
If we jump over to the lab itself, this lab actually has three machines interconnected together. We're just beginning. So, we're working on compromising the web server and then I'm guessing we'll pivot to the workstation and then the DC. The web server is Linux. These two machines are Windows.
So, it's a multi-machine lab.
Okay.
Let's see if this actually works. Oh, hey, we just got Jairo Thindra gifting the five memberships. I appreciate you.
You were awesome. Thank you so much for your generosity.
Thank you. Thank you. Thank you.
Oh, I already had that file.
I'll just call it gill SSH.
Like so, change mod What is it? 400, I think.
And now if we SSH as gill essay at whatever our IP is for our web server.
I want to specify our key with a dash I flag.
Oh, no, public denied? Or permission denied?
But this is his key, is it not?
All right, something odd is going on here, but let's I don't know if it's not the format of the key because we would have gotten a different error.
Dash I should specify using this key.
Uh that my grep command didn't work, but dash I is our identity file and we're passing it our identity file.
All right.
There's always multiple ways. What if I cat out home Tyler SSH?
I'm going to grab my public key here.
And what I'm going to do, there's always multiple different ways to solve something like this. If we go back here, okay, what I'm going to do first is actually open this up in notepad just so I can get the syntax correct here.
I'm going to grab my public key.
Oh, is it 600? My bad.
>> [clears throat] >> Was that my problem?
Let me change my permissions.
Although usually it throws a different error if that's the issue.
No, okay.
What we are going to do is echo >> [clears throat] >> my key into authorized keys for gill essay.
Now, boom.
When one way bugs out, my friends, there's always multiple different ways to do it. So, I think it was a formatting issue. We could have spent time troubleshooting, but remember the KISS principle, keep it simple, stupid.
If If we don't want to deal with formatting, we have full RCE. Just echo your own public key into the authorized keys folder, and then you can SSH into the machine as the GillSA user, and we have full SSH access now as GillSA. And we can go ahead and I suppose add that to our notes.
So, I'll go here and jump over to our notes.
All right, add that information there, and now we have full access to the GillSA user. We can show all of that information there, so I'll grab a screenshot showing that yes, we were able to get full SSH access to this first machine. So, I'm going to go ahead and paste that in. That is a massive massive window. We definitely don't need to be that large, so I'm going to make it a little bit smaller, and we'll go ahead and left align it. But looking over the time, we are at the 21-minute mark, very good natural stopping point because I just showed you how to get initial access to the first machine.
Now, before you watch part three, as usual, I have some homework for you. I want you to try the next part on your own. We have compromised the web server.
What you need to do is work, I'm assuming, on privilege escalation or lateral movement into one of those Windows machines. So, enumerate, see what you're able to find, and then join me in part three, and we will continue working through this together. So, thank you for being here until next time. Hack smarter, not harder.
Related Videos
Agentforce NOW AMA: Build with React and Salesforce Multi-Framework
SalesforceDevs
490 views•2026-05-28
How agent o11y differs from traditional o11y — Phil Hetzel, Braintrust
aiDotEngineer
450 views•2026-05-28
WEB TECHNOLOGIES UNIT-2 | Degree 4th sem BCOM Computers web technologies unit-2 full explanation💯✅
LearnwithSahera
1K views•2026-05-29
More tests are always better? How to use AI to identify tests that bring little value
Alliance4Qualification
335 views•2026-05-29
Search Algorithms Explained in 60 Seconds! 🤖💨
samarthtuliofficial
218 views•2026-06-01
People of Game of Thrones using JavaScript DOM
AltCampus
296 views•2026-05-30
Introduction to Problem Solving Part - 1 | Lecture 1 | Intermediate DSA
ascensionix
107 views•2026-05-29
🚀 BCS613C Compiler Design | Module 1 to 5 Schema Evaluation 🔥 | VTU 6th Sem 💯 #VTU #bcs613c #exam
Pranavaa-y4y
104 views•2026-06-02











