• Checking whether files exist outside open_basedir

    PHP’s open_basedir setting limits the files that can be accessed by PHP to the specified directory. It should not be possible to access files outside of the directory set as open_basedir. However, it is still possible to check whether files exist because the file used as client certificate in an SSL connection is not checked against open_basedir.

  • Downloading an exposed Mercurial .hg directory

    Version control systems sometimes create a hidden directory in the repository. Git creates a .git directory, and Mercurial creates a .hg directory. If the contents of a web site are managed with Git or Mercurial, this directory is sometimes exposed on the web. In this post we look at a way to download these directories.

  • vBulletin random number function

    VBulletin is a message board web application written in PHP. Before PHP 7 came with random_int and random_bytes it was pretty hard to create a secure random number, and vBulletin uses a pretty bad way to solve that problem. In this post we look at the code and how it can fail to create a random number that is hard to guess.

  • Don't use base_convert on random tokens

    The PHP function base_convert can convert numbers to a different numeric system. This can be used for example to convert a number to a sequence of letters and numbers. However, because it has limited precision it is not suitable for random tokens such as those used for session tokens or CSRF tokens.

  • Bypass IP blocks with the X-Forwarded-For header

    Sometimes the IP address is used for access control or rate limiting. If the client is behind a proxy, the proxy forwards the IP address of the client to the server in a specific header, X-Forwarded-For. In some cases, a client can use this header to spoof his IP address.

  • Securing cookies with cookie prefixes

    Cookies can be overwritten by a man-in-the-middle attacker, even when using HTTPS. Using special cookie prefixes makes cookies more secure.

  • Checking passwords against a dictionary in ASP.NET MVC

    When using passwords for authentication, users may choose passwords that are too easily guessed. A method to prevent this is to have a list of known passwords and deny any password that is present in the list. This post will describe how to implement this in ASP.NET MVC Core. When registering, the user will get an error if he tries to use a password that is present in the dictionary.

  • Book review: Bulletproof SSL and TLS

    Recently I read the book Bulletproof SSL and TLS. I think it is a great book and I would recommend reading it. In this post I describe what you can expect from this book.

  • Check CRSF token by default in ASP.NET MVC

    ASP.NET MVC protects against CSRF by using a secret token, and checking it if an attribute is present. In this post we will show how to check the CSRF token for all POST requests.

  • Strengthening password hashes by brute-forcing random data

    Password hashes should be slow to prevent offline brute-force attacks. One way to make them slow is to include some unstored random data in the hash, which has to be brute-forced whenever a password is verified against a hash.

  • Adding a HTTP header to Nikto requests

    Nikto is a tool to scan websites for misconfigurations and vulnerabilities. It does a lot of requests to the target server. Sometimes you want to add a custom HTTP header to these requests. This article explains some ways to do that.

  • HTTPS does not provide privacy

    If you visit a web site over HTTPS, all traffic between the client and the server is encrypted. This does not mean that somebody that intercepts the connection can’t see which pages you are visiting. This post describes what is visible over an HTTPS connection and why.

  • The economics of certificate transparency

    Traffic to any web site that uses HTTPS is encrypted, and the server’s identity is verified. For this the web server needs a certificate. The certificate proves that the client is really talking to the domain it expects, and not to some man in the middle attacker. This security is broken if an attacker can obtain a certificate for a domain he wants to attack. To prevent this, we need certificate transparency.

  • The current state of the BREACH attack

    In August 2013 the BREACH attack was presented at the Black Hat conference in Las Vegas. With this attack it is possible in some cases to read parts of HTTPS traffic. A serious attack, but to this day there is no good fix for it. How come?

  • The password guessing bug in Tenex

    In 1974, BBN computer scientist Alan Bell discovered a security flaw in the operating system Tenex. The password checking procedure would access certain memory pages during checking. By looking at which pages were accessed during checking of the password, user passwords could be guessed one character at a time.

  • SSRF in LiveAgent

    The helpdesk software LiveAgent makes it possible to configure a SMTP server. Since it does not validate the SMTP server parameter and returns the response of the TCP connection, it is vulnerable to server side request forgery.

  • Attacking JWT authentication

    JSON Web Tokens or JWTs are used by some web applications instead of traditional session cookies. Because of their statelessness and the signature implementation there are some security issues that are specific to JWTs. This post describes some ways you can verify that a JWT implementation is secure.

  • Uploading webshells using .NET MoxieManager

    MoxieManager is a file manager for web applications. By using the built-in unzip functionality we can bypass the file extension filter in the .NET version of MoxieManager.

  • XSS in Kayako helpdesk software

    In the Kayako helpdesk software, customers can submit tickets which staff can then view and answer. In this feature there is a XSS vulnerability in the ticket title. This post describes how I found that vulnerability.

  • Compression side channel attacks

    Compression side-channel attacks can be used to read some data by knowing only the size of the compressed data. Recently compression side-channel attacks have been published on compressed HTTPS connections: the CRIME, TIME, BREACH and HEIST vulnerabilities. This post describes how compression side-channel attacks work in general and what these attacks do in particular.

  • Interesting recent web application hacks

    This post looks at some interesting web application hacks that were recently published.

  • Intercepting smartphone HTTP requests on MacOS

    If you are testing a mobile app on a smartphone, you want to intercept all HTTP requests with Burp Suite. However, not all mobile apps respect the proxy settings, making it necessary to have another way to intercept all traffic. This post describes a solution using Internet Sharing on MacOS, and using PF to forward all traffic to Burp.

  • Fuzzing SAML with SAMLReQuest

    SAML is a single sign-on solution. It uses XML, but this is sometimes encoded in such a way to it hard to deal with in Burp Suite. Luckily, there are some extensions that can decode these request.

  • Headers to block iframe loading

    A typical clickjacking attack loads a site in a transparent iframe and asks the user to click an underlying element. The user thinks it is interacting with the attacker’s page, while the input actually goes to the transparent iframe. To avoid this, the X-Frame-Options header and frame-ancestors option in the content security policy are available to instruct browsers to not load the site in an iframe. This post explains more about these headers.

  • Insecure token generation in Kayako

    The helpdesk software Kayako uses an insecure method of generating tokens used for sessions and CSRF protection. It is possible to seed the random number generator with the current time and then crack that seed, making it possible to predict a large part of any following tokens generated by Kayako.

  • How PHP's uniqid works

    PHP has a uniqid function, that creates a unique identifier. This function is sometimes used in a security context, such as for creating tokens for sessions or CSRF protection. This makes it interesting to know how it works exactly and whether we can predict its output.

  • Clearing memory in Python

    The post “Clearing secrets from memory” discussed that it might be beneficial to clear secrets from memory after using them. This post discusses how to do this in Python.

  • Requirements for iterative password hashing

    To securely store passwords they should be hashed with a slow hashing function, such as PBKDF2. PBKDF2 is slow because it calls a fast hash function many times. This blog post explores some properties that the iterations must have to be secure.

  • Clearing secrets from memory

    When handling a secret such as an encryption key or a password, it is important not to leak it in any way. If the secret ends up in a log file, core dump or error message this could result in showing the secret to people who are not meant to see it. It may even be a good idea to remove the secret from memory after it is has been used. This blog post will look into whether that is good practice and how you can clear things from memory.

  • XSS in user-agent header in Bolt CMS

    Recently I tried to find vulnerabilities in Bolt CMS 2.2. Like many content management systems, Bolt has a publicly accessible web site, and a back end for administrators to modify the web site. I was looking for a way to get into the back end without valid credentials.

  • Combining CSRF and timing attacks

    In a CSRF attack it is typically not possible for the attacker to retrieve the result of the forged requests. In this post we show that by measuring the time that a forged requests take we can extract some information, for example whether a specific resource exists.

  • Preventing CSRF with the same-site cookie attribute

    Cookies are typically sent to third parties in cross origin requests. This can be abused to do CSRF attacks. Recently a new cookie attribute was proposed to disable third-party usage for some cookies, to prevent CSRF attacks. This post will describe the same-site cookie attribute and how it helps against CSRF.

  • Django's reset password mechanism

    Django enables users to reset their password with a token that is emailed to the user. This mechanism contains some smart features, so let’s look at how it works.

  • Datatypes for pycrypto in Python 3

    Say you want to encode some things in Python 3 using pycrypto, and you want full control over what is encrypted or decrypted. In that case you should use the bytes and bytearray types, not strings.

  • Opentape authorization vulnerability

    Opentape is a web application to create a playlist of MP3 files that users can play on a web page. It was first released in 2008, just after the music service Muxtape stopped its services.

  • Polymorphic Javascript malware

    Recently I received two similar e-mails with attached trojans, both using encoded Javascript. In this post we look into how the Javascript is encoded and what it does when it is run.

  • Cracking PHP rand()

    Webapps occasionally need to create tokens that are hard to guess. For example for session tokens or CSRF tokens, or in forgot password functionality where you get a token mailed to reset your password. These tokens should be cryptographically secure, but are often made by calling rand() multiple times and transforming the output to a string. This post will explore how hard it is to predict a token made with rand().

  • Circumventing authentication of a webshell

    When a website is hacked, the attacker often leaves a backdoor or webshell to be able to easily access the website in the future. These are often obfuscated to avoid detection, and need authentication so only the attacker can gain access to the site. In this post I am going to deobfuscate a webshell and show how the authentication can be bypassed when you have the source code but not the password.

  • Circumventing XSS filters

    XSS or cross site scripting is an attack where an hacker injects Javascript in a page that is then run by another visitor. To prevent this, some software tries to remove any Javascript from the input. This is pretty hard to implement correctly. In this article I will show some code that tries to remove Javascript code from the input, and show several ways to circumvent this.