Before starting any penetration test, the most important part is to correctly scope it – this will ensure that both the client’s expectations are fulfilled and that enough time is allocated to make sure that the penetration test is correctly performed.

In this diary I will not dive into particular activities that need to be performed as part of a penetration test – for a high-level (hey, it’s management speak) overview please check one of my older diaries at Getting (proper) value out of security assessments

This diary should (I hope) be interesting no matter on which side you are: a client purchasing penetration tests or a penetration tester.

Web applications

Now that we got differences between a vulnerability scan and a penetration test out of our way, let’s talk a bit about penetration testing web applications (and web services). Since the main difference between a vulnerability scan and a penetration test is the human factor, penetration test engagements should normally be scoped according to complexity of the target application. This will directly influence amount of time that needs to be invested into properly verifying a web application.

When I’m scoping web application penetration tests, the following two questions are most important for me:

  1. The total number of pages/screens, as well as the percent (or number) of the total number of web forms (pages) which require user interaction.
    This is probably the most important parameter – when penetration testing a web application what we are interested in are all dynamic parts, generally those that result in an HTTP request, which will allow us to change something.
    This makes sense – if our web server is hosting 10 million images and static HTML web pages there is not much we can do (we’ll still check infrastructure etc).
    However, if our web application consists of hundreds of dynamic web pages/screens then in theory we should check all of them. And remember, we are talking about a penetration test – while we will (and should) use tools, a lot of activity will be inevitably manual, since there is no other way to find logic flaws – tools will not find such vulnerabilities, which are often the most devastating ones.
  2. Number and type of user roles.
    Depending on our application, there could be multiple user roles with various permissions assigned. Again, if possible, every role should be tested – we need to confirm that the application correctly implements “horizontal” security (meaning: I cannot retrieve another user’s data) and “vertical” security (meaning: I cannot escalate my privileges or access something that a higher privileged role should only access).

Both of these factors will directly influence how many hours or man-days we need to spend when penetration testing a web application (or any application really). Of course, we need some realistic expectations set here as well – when we need to assess a huge application, typically we will want to enumerate endpoints since it is quite possible that numerous web pages/screens consume a single endpoint. If that is not the case we will need to identify those components which are priority.

If you are on a client’s side – this should help you assess offers as well: if you receive an offer that does not have enough time budgeted then really you are not getting a penetration test but at best a web application security scan with a little bit of manual work.

This might be OK too – as long as you know what you are getting – but keep in mind that no tool will identify logic flaws. If you want to see a few cool logic flaws check my SANS@MIC Talk “Arcane web and mobile application vulnerabilities” that was recorded at

Another good thing to check here is what tools are being used to perform such a penetration test. Besides a web application vulnerability scanner, in order to manually modify requests an interception proxy will be needed so it is mandatory for your penetration tester to use a tool such as Burp Suite or OWASP ZAP (and we cover both in SEC542!).

Below you can see me bashing the SANS ISC web site (/me waves to Johannes).

Web services

Testing web services is actually not too different from testing web applications, but the main challenge is in the workflow of how the target web services are consumed.

With web services there will typically be one account that is used (although it’s possible to have different roles, of course), so the main parameter for assessment of required engagement will be the number of endpoints, specifically methods and (if possible) number of parameters per method.

Once we receive this information it will be easier to assess how many hours or man-days need to be invested in testing the target web services. So how do we approach this? 

In the best scenario, the client will provide us with a Swagger file or Postman collection. These files will contain description of all endpoints and parameters they accept so testing will be easier. Besides this, always (and I mean always) ask for documentation about the web service workflows. What do I mean by this: it could be possible that certain endpoints must be consumed in a certain order – if you do not do this, you simply get back errors. Which also means that if you just blindly run a scanner against the list of API’s you really won’t get much (and this is why we are talking about penetration tests here).

Once you have this information the rest is basically very similar to a web application penetration test. What the majority of penetration testers will do is run Postman (which is also a free tool) and configure it to send requests through an interception proxy (Burp Suite or OWASP ZAP as mentioned above). Postman will then be used to “seed” the requests so our interception proxy can see them and we can use the interception proxy now to continue testing the target web service.

The figure below shows Postman configured with the PSD2 collection that contains all requests needed to consume PSD2 web services (if you are in the banking sector you are certainly familiar with PSD2, if not and you want to read more here is a starter).

Notice how all parameters are nicely defined in Postman – all that is needed now is to properly fill them in, send the required requests to our intercepting proxy and we are good to go.

We talk about all of this in SEC542: Web App Penetration Testing and Ethical Hacking and if you found the topic interesting let us know here.


(c) SANS Internet Storm Center. Creative Commons Attribution-Noncommercial 3.0 United States License.
(c) SANS Internet Storm Center. Creative Commons Attribution-Noncommercial 3.0 United States License.

There are many interesting solutions to my "Small Challenge: A Simple Word Maldoc" diary entry: static analysis solutions, dynamic analysis and even a combination of both. You can find them in the comments and on Twitter.

When you look at the code above, I'm sure you will notice the long string of numbers (separated by % characters) and think: this must be the encoded command/url.

Sequences of numbers like these have appeared in malicious documents for many, many years. That's why I have my own tool to help me with decoding these numbers: is a tool that takes text as input, and searches for lines with 3 numbers at least (default). For each such line, it will extract all the numbers, convert them to characters, and output the result. Like this:

The output above doesn't help us much. numbers-to-string converted each number to its corresponding ASCII character, but it looks like the numbers have also been encoded, because we see many unprintable characters.

If you look at the VBA source code, you might notice an expression with Xor 111. This is a strong indication that the numbers have been xor-encoded, using single-byte key 111.

This can be easily tested with numbers-to-string: my tool also takes a Python expression as argument, to be applied for each number. Python expression "n ^ 111" will perform an Xor operation with value 111 on each number, before converting it to characters.

This does indeed reveal the command:

In an upcoming diary entry, I will show how you can also try to decode the obfuscated command, if you don't use the VBA source code to guide you (hint: it involves my tool xorsearch).


Didier Stevens
Senior handler
Microsoft MVP

(c) SANS Internet Storm Center. Creative Commons Attribution-Noncommercial 3.0 United States License.
Internet Storm Center Infocon Status