This is why you don't trust filenames of uploaded files. Instead you should generate your own local filename when storing to disk - a string of random characters or at least a guid/uuid. Then you can store the local filename and the uploader's filename (without path) to a database to tie them together, and just use the uploader's filename for display purposes and in the Content-Disposition header when allowing the user to download the file again. This is basics. It's just like how there are particular file formats which you never store on the server as the same file which was uploaded, such as image files and PDFs - you load/parse them and then resave them in order to sanitize them.
This works until you consider something like image backup software, where conserving the file names and the actual folder structure is more important. If the user wants to download all of the images in the exact same way they uploaded them, you don't need to take a round-trip to the database to fetch the original file name for potentially 10s of thousands of images - you just send the images as-is.
Hey man, I'm an automation engineer and I mainly work with PLC's and other industrial hardware. Just wanted to share videos like these motivate me to practice more on the real software wide. Thx my guy, have a good one
@@Slangsget a computer, open a terminal & start typing. if you don't understand something, google it with a "what/why". almost all commands have manuals so do "man " in the terminal. this way you can read the manual for that command. that's it.
@@SlangsI'd recommend just googling what certain code languages are capable of doing. Search projects other people have done, and see what languages they've used. If you're interested in making diy robots/machines, then I'd recommend Python (or ROS) for the raspberry pi and C++/C for the Arduino. I've studied automation for 5 years, and Python is my daily driver. Python is a good and easy starting point for automation type tasks.
Dude! Such a cool attack. Also, pretty amazing that SNYK finds the -debug mode enabled vuln AND command injection vuln (I guess they are linked, but still... cool). I also loved the panic that set in when dosbox was blasting your screen, hahaha (meaning it's nice to know I'm not the only one who panics :)
This is a great example why security can have many levels. You can still use this code "securely" if you host it on ephemeral environment where access like this isn't a dealbreaker. If this would be hosted on AWS Lambda (or Lambda+S3) with proper timeouts then attackers are wasting their time. I'm not a cloud advocate, I don't even like AWS. You can use whatever function/lambda/serverless platform that you want to. But for a web application like this, where file access from public internet is possible, it's a good practice to keep it contained in a safe sandbox. If you would want, you can even set it up so that each session is handled by different docker container with a lifespan of 1 minute or something similar. It's a bit more advanced setup but still doable with mostly opensource tools and without "serverless" bs
To be fair, this is a pretty blatant vulnerability, even the most basic code review should catch it. Even LLM based code reviews. That said, nice video, well done.
Also this should be running on ephemeral environment where access like this isn't a dealbreaker. If this would be hosted on AWS Lambda (or Lambda+S3) with proper timeouts then attackers are wasting their time.
When using sudo -l command, you list the possible things that you can run (along with info such as if you need to put the password of the user, etc). In this case, you could only use sudo to execute /usr/bin/dosbox, so you can't do "sudo cat". That's why you have to find a way of escalating your privileges within the context of using dosbox, since it maintains the root privileges while the program is running.
@25:49 I don't get how it goes to writing files, shouldn't the output filename become the '/app/app.py' value so it reads the source from bad_app and writes that to the app's source code file? Am I missing something?
@@Halorocker101 So I watched it again and I missed at 5:55 the function that saves the file. So he only uses the output.txt file to get to the right path but actually the source file gets already saved when you upload it. At 8:46 he points out that the sanitized filename (filename var) is never used, that's where the vulnerability starts. Guess I should be less tired when watching John's video haha
@@Euronautswait so by uploading a file named "/temp/test.txt" with the content "hello" will create a file in "/temp/" called "test.txt" with content "hello"? if not then i understand everything except the write_file function
Not sure if that was just an accident but you don't have to declare global variables with "global" to read them in a function in Python and I'd say it's pretty bad style to do it. You only need to do that to write to them since Python will assume you're trying to declare a new local variable otherwise.
Great Video 🎉 I‘m a little bit confused about the ordering of the entries in files list within the write_file function. I thought first Parameter after the -n -f flags is input file, thus I would have swapped the ordering of entries in files list. But maybe I overlook something😅
Could you add a timestamp ? Cause the order is correct from my quick glimpse. First input, then output parameters The file list looks correct in ~ 17:00
The upload doesn't have anything to do with dos2unix, it's just the functionality of the app. You upload a file before it's passed to dos2unix. It's definitely pretty confusing in the video, you don't need the -f or -n or anything like that for uploading.
Moral of the story, don't run shell commands with user provided data. And is it really needed to use that command to convert the file? Like you could done that with simple replace all or even don't use uploading and just convert this files in place using js in users browser
@@WolfrostWasTaken Great! Please share your javascript code that has no problem running any linux binary. I have so many of this converting web applications that it would save me a lot of hassle with ffmpeg and all sorts of custom c++ binaries
I'm sorry Orange flavoured John but all that amazing information went right through me because I couldn't stop noticing how you're gripping the mic while it is on a very nice armature. 👀
I am a bit confused, shouldn't the script write the input to the output and that's how you read /etc/passwd? how did you replace /etc/passwd and it just wrote to it?
in app,py it tries to save each file to upload_folder/filename. i think that when doing read_file("/etc/passwd"), app,py fails to save to /etc/passwd, then ends up doing dos2unix -f -n /etc/passwd output.txt, which writes to output.txt the unchanged passwd file. when write_file("/app/app,py, ...") happens, app,py overwrites itself when it saves all the files to upload_folder/filename. app,py can write to app,py because the crlf user (who is currently running app,py) has owns app,py, but can't write to /etc/passwd since that needs sudo/root
Excellent teaching video. Btw I'm speaking with over 3 decades being in the field the - in the ASCII world is dash; ; . Tack is a military used term. Basically used for the same thing but as people left the military in the field it was taught to others and that's how it got introduced into the field but never entered into the ASCII table description. Look up an ASCII table. It will by hyphen-minus.
If you're in a position to know you need a CRLF convertor, aren't you probably in a position to know either how to do it or how to look up how to do it with whatever editor you're using?
In the first min I was thinking. Wait.. how did you copy and paste a file from your host to your virtual machine and how did you zoom in with the terminal?
Great challenge! I can understand why it's your favorite, these 'HackTheBox like' challenges with multiple steps are always so satisfying to solve. A perfect challenge to develop an efficient post-exploitation workflow while sharpenning your observation skills!
Hello, I think that Flask debug mode is not known for being secured, is this exploit working on a production env? Do you have recommandations to prevent those backdoors or Flask is simply dangerous? Thanks for this great video.
Sudoers allows you to control both which commands a user/group can run and with what level of authentication. In this case the app's user had access to run dosbox as root without a password, and no sort of access to any other command
What advantage do people find in this challenge to use python? I use it when i need to manipulate the response and do something with it like some decoding, reencoding and send it again but here i dont see any advantage at all.
You got something wrong, "you typically see on Linux or Mac based operating systems", the default for these is that is not the case, Mac uses or ' ' Linux uses or ' ', windows uses ' '. so please don't lie to people to seem like windows is the one in the wrong they are all different.
Mac Classic used , but it's been over 20 years since OSX released, and that uses the POSIX line ending. So he's only incorrect if you're looking at extremely old files. Windows more accurately represents a typewriter (and possibly some old terminals), but I don't believe he called it incorrect, just different. Although in the case of a typewriter, the order of carriage return and line feed doesn't really matter.
I don't think you get the point of penetration testing. Pentesters like John are employed by companies to test their systems against common bugs and exploits such as these here. After that, they report a full description how they achieved access and the company can fix their loopholes. It is necessary for big companies to have people constantly testing against their systems so hackers cannot compromise them. This video shows you a potential way of exploiting dos_to_unix and how wrong it can go, so pentesters can look for these kind of things when testing. It is never a good way to just "not test your system and close source everything", because hackers will try to get in, no matter what. Better be prepared and have obvious loopholes closed by pentesters. Big companies such as google even give out prices for bugs others find, and they can go into the 100k reaches depending on how bad the compromise gets.
It's not someone elses work? He literally mentioned that this is a challenge he himself created for a CTF event. It's literally code that is meant to be hackable if you know what you're doing, that's part of the challenge...
What are you talking about. He created the website for part of a fun hacking challenge. You are literally the one shitting on other people's hard work, ironically.
This is why you don't trust filenames of uploaded files. Instead you should generate your own local filename when storing to disk - a string of random characters or at least a guid/uuid. Then you can store the local filename and the uploader's filename (without path) to a database to tie them together, and just use the uploader's filename for display purposes and in the Content-Disposition header when allowing the user to download the file again. This is basics. It's just like how there are particular file formats which you never store on the server as the same file which was uploaded, such as image files and PDFs - you load/parse them and then resave them in order to sanitize them.
You don't even need to write them to the disk, you can just open a pipe to the stdin/stdout of dos2unix and read it that way.
@@foxbeans1509 In this case you don't even have to make a trip to the server. This could totally be done client side.
This works until you consider something like image backup software, where conserving the file names and the actual folder structure is more important. If the user wants to download all of the images in the exact same way they uploaded them, you don't need to take a round-trip to the database to fetch the original file name for potentially 10s of thousands of images - you just send the images as-is.
Then they can just use SQL injection instead assuming there's still no sanitation or escaping.
@@twirreHow do you want to run Linux binary on the browser?
*stands out of chair and throws roses at computer screen*
BRAVISSIMO SIGNORE
Hey man, I'm an automation engineer and I mainly work with PLC's and other industrial hardware. Just wanted to share videos like these motivate me to practice more on the real software wide. Thx my guy, have a good one
I am the exact opposite lol, any idea where to start if I don't have engineering background?
@@Slangsget a computer, open a terminal & start typing. if you don't understand something, google it with a "what/why". almost all commands have manuals so do "man " in the terminal. this way you can read the manual for that command. that's it.
@@SlangsI'd recommend just googling what certain code languages are capable of doing. Search projects other people have done, and see what languages they've used.
If you're interested in making diy robots/machines, then I'd recommend Python (or ROS) for the raspberry pi and C++/C for the Arduino.
I've studied automation for 5 years, and Python is my daily driver. Python is a good and easy starting point for automation type tasks.
@@Slangs I'm not entirely sure. Most hardware lies behind very expensive licenses, so it's a bit harsh to get into on your own
This is so out of my abilities but I kinda understood what he did. Amazing teacher.
It is simple command injection, he just used python to make the job and that make it totally unclear for beginners.
Dude! Such a cool attack. Also, pretty amazing that SNYK finds the -debug mode enabled vuln AND command injection vuln (I guess they are linked, but still... cool). I also loved the panic that set in when dosbox was blasting your screen, hahaha (meaning it's nice to know I'm not the only one who panics :)
7:49 filenames with spaces can add arbitrary shell commands, and filenames can contain dots so they may be written to outside the upload folder.
yes, i was thinking you just set filename to " || "
This is a great example why security can have many levels. You can still use this code "securely" if you host it on ephemeral environment where access like this isn't a dealbreaker. If this would be hosted on AWS Lambda (or Lambda+S3) with proper timeouts then attackers are wasting their time. I'm not a cloud advocate, I don't even like AWS. You can use whatever function/lambda/serverless platform that you want to. But for a web application like this, where file access from public internet is possible, it's a good practice to keep it contained in a safe sandbox. If you would want, you can even set it up so that each session is handled by different docker container with a lifespan of 1 minute or something similar. It's a bit more advanced setup but still doable with mostly opensource tools and without "serverless" bs
Congrats on 1 Million 🍾
16:03 brain buffer overflow
To be fair, this is a pretty blatant vulnerability, even the most basic code review should catch it. Even LLM based code reviews. That said, nice video, well done.
Also this should be running on ephemeral environment where access like this isn't a dealbreaker. If this would be hosted on AWS Lambda (or Lambda+S3) with proper timeouts then attackers are wasting their time.
This is a completely crazy vulnerability. 🤣
I challenge you to do the same on a Django environment !
Once you got into the reverse shell, and that you had sudo access, wouldn't you be able to do the "sudo cat /root/flag.txt"?
When using sudo -l command, you list the possible things that you can run (along with info such as if you need to put the password of the user, etc). In this case, you could only use sudo to execute /usr/bin/dosbox, so you can't do "sudo cat". That's why you have to find a way of escalating your privileges within the context of using dosbox, since it maintains the root privileges while the program is running.
@25:49 I don't get how it goes to writing files, shouldn't the output filename become the '/app/app.py' value so it reads the source from bad_app and writes that to the app's source code file? Am I missing something?
Yea I don't understand why it didn't just write bad_app to output.txt.
@@Halorocker101 So I watched it again and I missed at 5:55 the function that saves the file. So he only uses the output.txt file to get to the right path but actually the source file gets already saved when you upload it. At 8:46 he points out that the sanitized filename (filename var) is never used, that's where the vulnerability starts. Guess I should be less tired when watching John's video haha
@@Euronautswait so by uploading a file named "/temp/test.txt" with the content "hello" will create a file in "/temp/" called "test.txt" with content "hello"?
if not then i understand everything except the write_file function
yes indeed. Just by uploading a file you can escape the upload directory because the function never sanitizes the filename,@@MP3Martin
@@Euronauts thanks
Not sure if that was just an accident but you don't have to declare global variables with "global" to read them in a function in Python and I'd say it's pretty bad style to do it. You only need to do that to write to them since Python will assume you're trying to declare a new local variable otherwise.
amazing content as ever love your little python exploits
gr8 content, slight note i dont think ive ever heard someone pronounce /etc other than 'et-see'
0:22 so thats why all my text files end in an empty line that I cannot figure out how to rid of
Great Video 🎉 I‘m a little bit confused about the ordering of the entries in files list within the write_file function. I thought first Parameter after the -n -f flags is input file, thus I would have swapped the ordering of entries in files list. But maybe I overlook something😅
me too, I am still very confused about this, no idea what happened there
Could you add a timestamp ?
Cause the order is correct from my quick glimpse.
First input, then output parameters
The file list looks correct in ~ 17:00
@@EbikoYeah sure! I meant the files list at 25:00 The list at 17:00 looks also good to me 😊
The upload doesn't have anything to do with dos2unix, it's just the functionality of the app. You upload a file before it's passed to dos2unix. It's definitely pretty confusing in the video, you don't need the -f or -n or anything like that for uploading.
Same. Will watch that section a third time now after reading these comments to understand what I’m missing.
Moral of the story, don't run shell commands with user provided data. And is it really needed to use that command to convert the file? Like you could done that with simple replace all or even don't use uploading and just convert this files in place using js in users browser
JS in place is underrated. No need to call any server, the app will even work offline and it will be faster.
@@WolfrostWasTakenit is not underrated, it is actually overrated but for the wrong reasons lol
@@WolfrostWasTaken Great! Please share your javascript code that has no problem running any linux binary. I have so many of this converting web applications that it would save me a lot of hassle with ffmpeg and all sorts of custom c++ binaries
Best explanation on the internet!
I'm sorry Orange flavoured John but all that amazing information went right through me because I couldn't stop noticing how you're gripping the mic while it is on a very nice armature. 👀
even before you asked I thought about unsanitized filename inputs. path traversal attacks maybe. maybe reverse shell with a really funny spoofed POST
we need a full course on Udemy :)
I am a bit confused, shouldn't the script write the input to the output and that's how you read /etc/passwd? how did you replace /etc/passwd and it just wrote to it?
in app,py it tries to save each file to upload_folder/filename. i think that when doing read_file("/etc/passwd"), app,py fails to save to /etc/passwd, then ends up doing dos2unix -f -n /etc/passwd output.txt, which writes to output.txt the unchanged passwd file. when write_file("/app/app,py, ...") happens, app,py overwrites itself when it saves all the files to upload_folder/filename. app,py can write to app,py because the crlf user (who is currently running app,py) has owns app,py, but can't write to /etc/passwd since that needs sudo/root
Why did you have to do global url in the function wouldn't it be automatically global scope being declared already above?
Yeah, there was no reason he had to do that, I think he just got a bit confused.
CR is just called carriage return, not carriage return, line feed (CRLF)
Excellent teaching video. Btw I'm speaking with over 3 decades being in the field the - in the ASCII world is dash; ; . Tack is a military used term. Basically used for the same thing but as people left the military in the field it was taught to others and that's how it got introduced into the field but never entered into the ASCII table description. Look up an ASCII table. It will by hyphen-minus.
Damn 1m subs congrats mate.
Man will never move the webcam view.
If you're in a position to know you need a CRLF convertor, aren't you probably in a position to know either how to do it or how to look up how to do it with whatever editor you're using?
Good point lol. I assume he just used that site for demonstration purposes because it's simple.
thanks
with love from:
PCA - Philippines
This man needs a raise!
In the first min I was thinking.
Wait.. how did you copy and paste a file from your host to your virtual machine and how did you zoom in with the terminal?
If you have the vm guest extensions set up properly you can actually copypaste between host and vm.
And Ctrl+"+" for zooming in
Ctrl + scroll down to zoom
My guess is the vuln is in the filename parsing.
I love when you try to get privilege escalation you accidentally open a portal into the 5th dimension
Why would a website like that even need a backend haha , should just do all of the transformation locally
So you can keep people's data 🤫
Great video but the grabbing of an already mounted mic gives me a weird anxiety. 😅
Someone’s got to stop him
The standard voice is back!!!! ALRIGHT :)
Great challenge! I can understand why it's your favorite, these 'HackTheBox like' challenges with multiple steps are always so satisfying to solve.
A perfect challenge to develop an efficient post-exploitation workflow while sharpenning your observation skills!
you should stop the lizard overlords
help the resistance
Hello, I think that Flask debug mode is not known for being secured, is this exploit working on a production env? Do you have recommandations to prevent those backdoors or Flask is simply dangerous? Thanks for this great video.
flask is fine, he created a scenario that left out a vulnerability, it wasnt flask's fault.
@@sorenkirksdjfk7310
flask: 😢
3:57 IANAH... is this going to be as simple as piping in another command? :D
12:12 Instead of the list of tuples, why don't you use a dict?
"werkzeug" is pronounced "verk-zoig" by the way
TIL debug mode is dangerous :o
If you had access to sudo, why couldn't you just do sudo cat /root/flag.txt? Or am I misunderstanding something about the challenge?
Sudoers allows you to control both which commands a user/group can run and with what level of authentication. In this case the app's user had access to run dosbox as root without a password, and no sort of access to any other command
what is he using for the terminal autocomplete or predictive text or whatever it is?
tab key
1:58 yea welll u know 'Encoding' 👀 I mean we had the same job until it was illegal 😎
A great explainer . ❤❤❤
Tac? Tach? Tak? What ? Are you serious? You cant even use the right word for a "-".
paused at 8ish minutes. As a frontend dev who didn't do much python stuff, I did not see anything wrong
I'd never implement it this way.
you need `global` modifier to overwrite variable, not to access it
Could you add chapters to this video
Stop hacking kids high school projects! I'm serious, those were 'made to be hacked'...
2:30 in... I know where this is going...
Edit: And it also looks like there's an XSS vulnerability ;-;
Damn I just got unskipable ads😭
really awsm... love the way you explained
Great video! My question is, why doesn’t the server need to be restarted after the bad app code is injected?
He explained in the video that flask reloads automatically upon file changes
hello bro, Can you make a channel with Russian voiceover? For example, a neural network
oh shit i thought it was gonna be put a cmd inside of the filename but this is genius this way u can grab the ssh key
and leave yourself a backdoor for later too
He thrungs it ☹️
oh... another ctf video, thanks for the misleading title
Why the hell are people using Kali Linux
Using dosbox to privesc is new to me ...
What advantage do people find in this challenge to use python? I use it when i need to manipulate the response and do something with it like some decoding, reencoding and send it again but here i dont see any advantage at all.
He just happens to know Python its a fairly easy language to pick up especially for red team.
yup command injection
No wonder anonfiles gone you probably took down
Love his channel
filename
Hackers respect him.
Webmasters fear him.
lol
Beautiful 💓
oh yeah. Finally again some seth rogen hacking vid :)
nice t-shirt :)
nwm kurwa o czym to jest a jestem na 22:34
very enjoyable.
crazy...
Que malas vibras me da el chaval. 🤓☝🏻
nice gpt flask app 😂
desu desu desu
wow
that's awesome
Non ho capito un cazzo
11th comment
first
Cool!
You got something wrong, "you typically see on Linux or Mac based operating systems", the default for these is that is not the case, Mac uses or '
' Linux uses or '
', windows uses '
'. so please don't lie to people to seem like windows is the one in the wrong they are all different.
Mac Classic used
, but it's been over 20 years since OSX released, and that uses the POSIX line ending. So he's only incorrect if you're looking at extremely old files.
Windows more accurately represents a typewriter (and possibly some old terminals), but I don't believe he called it incorrect, just different. Although in the case of a typewriter, the order of carriage return and line feed doesn't really matter.
Nice
Is it your real voice or you are using some sort of converter to make it deep? Its not good at all..
Why are you shouting?
nice
😂❤❤❤❤🎉💀💤 Cool ⚡🧃
Shit on other people's hard work. Congratulations what a good thing to do. You are now a FBI agent.
I don't think you get the point of penetration testing. Pentesters like John are employed by companies to test their systems against common bugs and exploits such as these here. After that, they report a full description how they achieved access and the company can fix their loopholes. It is necessary for big companies to have people constantly testing against their systems so hackers cannot compromise them. This video shows you a potential way of exploiting dos_to_unix and how wrong it can go, so pentesters can look for these kind of things when testing.
It is never a good way to just "not test your system and close source everything", because hackers will try to get in, no matter what. Better be prepared and have obvious loopholes closed by pentesters. Big companies such as google even give out prices for bugs others find, and they can go into the 100k reaches depending on how bad the compromise gets.
It's not someone elses work? He literally mentioned that this is a challenge he himself created for a CTF event. It's literally code that is meant to be hackable if you know what you're doing, that's part of the challenge...
What are you talking about. He created the website for part of a fun hacking challenge. You are literally the one shitting on other people's hard work, ironically.
thanks for the efforts you put in to deliver awesome knowledge and we hit 1M subs. 2M next --------->>---->>
Thank You @ JohnHammond
Hi man thank u for directions i was able to hack facebook and read my gfs messages
Ultimate 🥏