Hunting for bounties antihack.me case study


~ 15 minute read
Crafted : 3 weeks ago Updated : 3 weeks ago
Tags:
#infosec #information-security #bug-bounty #websec #code-audit #bug-bounty #writeup #101 #guide

Hello, luvs.

I planned to post this long time ago, but because I was busy building SMFD, so it took me a while. As I mentioned in an earlier post these days, I don't hunt for bounties. I have my reasons, but it doesn't mean you shouldn't shoot for bounties. It can bring you a lot of freedom, money, self-esteem, and it's quite challenging and enjoyable. To make this post more helpful, I tried to find a case study, and I chose a bug bounty (security-aware) platform itself to prove my points.  I'll start with a general background and then jump into our case study. 

Table Of Contents

 

Bug bounty where you should start?

In my opinion it's all about your background period. I believe if you are reading this post, it means you have some excellent background using computers. Some of you maybe come from a network administration background, some from a development background, and some of you are perhaps full-time hunters. The best place to start hunting for bounties is what you are good at or familiar with. Let me give you an example; for example, you been a network administrator for the past few years, and you already know how to sniff packets and understand them. You have a solid background in network protocols. That's where you can find the vulnerabilities! Don't get it wrong, a lot of people understand bug bounties as only web applications and only OWASP top 10 vectors. It's far more significant than that. Any software or even hardware (or even your autonomous car you are driving) is vulnerable, and you can hunt for bugs in it, and you can get paid for it.  There are a lot of vulnerability acquisition and coordination programs out there. I already named some in my previous post. So in simple words, all you have to do is learn the core concept of security vulnerabilities and try to apply it in the area you are good at it. Let's have another example if you are a C/C++ developer, all you have to do is learn the vulnerabilities applies to C/C++ code, most notably memory corruptions, and then instead of writing code, you can read others codes and write fuzzers for others code. But you may ask, I don't have much experience so I can't hunt for candies? Not really for newcomers, I suggest web applications because of a smoother learning curve compared to other areas but don't get me wrong milder doesn't mean lame you can always be creative and even invent your attack vectors in any field. 

Antihack.me case study 
Let's get technical now and jump to a case study. Breaking different software needs different strategies, for instance, targeting a browser or a network application or web application requires different approaches. 
As for web applications, here are some components I like to test separately, and then the relationship between them, not all of these components, necessarily exists in all web apps. 

  •  Front end
    • Javascript
    • Websockets
    • Storages
    • JS frameworks/libraries (angular, vue.js, react, jquery, etc.) 
    • Intercommunication (post messages) 
  •  Backend
    • language-specific, for example, PHP/JAVASCRIPT/JAVA
    • Unauthenticated (guest)
    • Authenticated 
    • Staff/Admin
  • API
  • Backend framework (Rails, Laravel, Django, Flask, etc.)
  • Webserver (Nginx, IIS, Apache, etc.)

 

This list by no means is complete but gives you an idea about what I mean by components and their relationship. Because this approach provides us a perfect chance not to miss any vulnerability in every single part, and later, we should test component relationships of the target app. This whole case study assessment only covers an incomplete list of attacks and vulnerabilities with the least privilege or unauthenticated backend and front end level. 

Pro Tip: different combinations of these components introduce new vulnerabilities. For example, how paths are handle on APACHE + PHP + LINUX is different win IIS + PHP + WINDOWS, so the whole idea is if single components are safe, we can eventually find something platform-specific. 

 

So we read the antihack.me scope, I found out that's pretty limited single domain scope, which is not realistic for a real-world attack simulation, but still, when the target domain hosts a medium size dynamic website, there should be plenty of vulnerabilities to play. 

 

Pro Tip: you have to respect your target scope, never test a target without permission, not that it's only illegal, but it's morally wrong. 

 

I start all my assessments by looking at the previous vulnerabilities in my target, and a lot of times, I can even reproduce an oldest-age vulnerability simply because of an improper bug fix. So here our target is antihack.me let's look at what vulnerabilities others found on it.

 

Pro tip: no matter we are trying to hunt a 0day in "latest chrome" or trying to break into one "not that secure" software previous vulnerabilities combined reverse engineering (it applies to the web too) always brings magical results. 

from those 66 previous issues I summarise these : 

Full Path Disclosure: This means the server, for some reason, is returning errors, so we usually can find some variant again. In our case it disclosure website is using laravel framework 

IDOR: often happens after authentication, so I didn't try it

File upload on the hacker registration page: interesting I still see upload in the registration form 

XSS: okay there is almost no dynamic website out there that don't have one of these little bastards

as the target is single domain we can expect after that amount of resolve a lot of apparent vulnerabilities and those can be obtained using free and commercial scanners should be gone

 

So before anything let's look at target technology stack, the app core functionality coded in laravel so let's look at that : impressive. only four vulnerabilities in the core, and none are critical alone.

 

Pro Tip: we always can chain vulnerabilities which give us ultimate power, for example, most recent laravel bug CVE-2018-15133 combined with another vulnerability like the one found previously found in download.php could result in nothing but RCE As our scope says, we can not search for any other attack surface here, and we have to stick with the main application. But keep it in mind, the bigger the scope, the more vulnerabilities hunt. And in big scope targets, recon plays a critical part in any assessment. If you do recon right most of the time, you can already win the lottery. Recon consists of finding as much as live assets. (subdomains, web applications, DB software, any other service or protocol you can communicate with) 

So in our case, I started crawling around and found the first exciting file.

https://www.antihack.me/public/front_assets/js/jquery.fileuploader.js


I thought maybe I got lucky as recently there is one jQuery upload vulnerability patched but then I saw its totally something else and its written by another company called innostudio.de then I tried to download it to perform a quick audit on it and I saw its commercial but as it was $10 I bought it and tried to read the code but then I found it the version I bought is far newer than version used in the site so if I find a 0day in this lib chances are target isn't vulnerable so I needed exact version which I search around and found the exact version on a restaurant app in GitHub Okay, that's nice, and like its single small file, we quickly can spot interesting functions, for example, let's look at filterFileName() function.

<?php

private function filterFilename($filename) {

$delimiter = '_';

$invalidCharacters = array_merge(array_map('chr', range(0,31)), 
 array("<", ">", ":", '"', "/", "\\", "|", "?", "*"));

// remove invalid characters

$filename = str_replace($invalidCharacters, $delimiter, $filename);

// remove duplicate delimiters

$filename = preg_replace('/(' . preg_quote($delimiter, '/') . '){2,}/', '$1', $filename);

return $filename;
}


What we have here is a function that seems to replace special characters to perform XSS on a filename that also raises a lot of questions.

  • How and when it's called?
  • Is there a bypass?
  • Do we even need to deal with it?

I let you play with this function; all you have to do is call this function on your various inputs and try to find a way to break it. Don't forget regex proven to be vulnerable when it comes to security. The next step is to see this uploader and try to upload unauthenticated files with the controlled path. 

 

#I RCE through chained vulnerabilities 

After a bit of directory busting around, I finally found the PHP file here:
 

 https://www.antihack.me/php/class.fileuploader.php

I could interact with it unauthenticated, but the issue is we need a way to make-instance from this uploader class to interact with its methods.I couldn't find a way from the registration page to trigger the uploader directly, and there is no instantiation in the class itself. So I dig and dig front-end sources till I found another new code in the commented section of app JS codes.

 

upload: {

   url: 'php/ajax_hacker_signup_image_upload.php',

   data: null,

   type: 'POST',

   enctype: 'multipart/form-data',

   start: true,

   synchron: true,

   beforeSend: null,

   onSuccess: function(data, item) {

    setTimeout(function() {

      item.html.find(‘.progress- holder').hide();

        item.renderImage();

       }, 400);

   },

 

Okay as we see POST parameters no token no authorisation nothing but a data sweet . and we can guess it's probably using same uploader but does this file exist ? Yes it does !

And it also responds to us with a warm JSON massage. 

 

{"hasWarnings":false,"isSuccess":false,"warnings":[],"files":[]}

Remember that editor we just bought now we can look at documentation and examples to interact with uploader class we found during previous steps all we have to do is perform a post with $_FILE to test. 

Here is the result. Sweet.

{"hasWarnings":false,"isSuccess":true,"warnings":[],"files":[{"date":"Tue, 22 Jan 2019 03:33:37 +0800”,"extension":"php5","file":"\/var\/www\/html\/Hackers\/Docs\/

pwned.php5","name":"pwned.php5","old_name":"pwned.php5","old_title":"pwned","replaced":false,"size":44,"size2":"0.04 KB”,"title":"pwned","type":"application\/octet-stream","uploaded":true}]}

Wow, we can upload a file with a controlled location/path/ filename. Is it heaven? Not quite yet.
 

 

What's going here? The server is using a .htaccess file to force this folder to server plain/text, and so no code exception here? :( maybe patched from previous reports, and it also uses no-sniff content-type header so we can't execute JS / HTML even in oldest browsers as well.

So we have done here; it's just as useless as a defacement? Not at all its unauthenticated file upload under our control, there are a lot of things we can test here :

 

  • Replace .htaccess file 
  • Try to control upload dir 
  • Enumerate other documents send by other 
  • Upload an endless number of files (DoS) 

 

Let's go back to the uploader code.

 

<?php

class FileUploader { 

 private $default_options = array(

 'limit' => null,

 'maxSize' => null,

 'fileMaxSize' => null,

 'extensions' => null,

 'required' => false,

 'uploadDir' => 'uploads/',

 'title' => array('auto', 12),

 'replace' => false,

 'listInput' => true,

 'files' => array()



Our two first assumptions are not possible here because file upload dir is static and not from user input and replace false by default but not that its not the case in all targets and a lot of targets you can control these variables the two other are possible, and we can upload endless files here so we found our first vulnerability here. 

So that's the impact of this issue? NO. Remember everything from previous right? We have these together.

  • we know target uses laravel
  • We have unrestricted file upload with our extension 
  • We have access to uploader source code 

What else can we do these? We can upload a phar file. Is a new PHP exploitation method 

To get all the info look at here.

"At BlackHat US 2018, @s_n_t released PHARGGC, a fork of PHPGGC which instead of building a serialized payload, builds a whole PHAR file. This PHAR file contains serialized data and as such, can be used for various exploitation techniques (file_exists, fopen, etc.). The paper is here."

If we can find a way to user input that goes to functions like files_exist, we do have unserliazation vulnerability, and in our case, we are lucky because PHARGCC already has POP gadgets for exploiting laravel In PHARGCC. So now all we need is an endpoint which we already have it 

https://www.antihack.me/php/ajax_remove_file.php


 

<?php

if (isset($_POST['file'])) {

  $file = '../uploads/' . str_replace(array('/', '\\'),
   '', $_POST['file']);

  if(file_exists($file))

  unlink($file);

}

Okay this is a perfect example for exploiting this vulnerability we need

 

  • Ability to upload phar
  • Full path disclosure of uploaded file
  • Trigger functions on file to trigger deserialization 

 

At writing time of this endpoint return, 500 error but any other endpoint as simple as that three-line above can trigger RCE through serialization, and that's game over.

Okay, that's good enough for one issue let's try to another page.

 

#II Advanced XSS through DNS email spoof check


As we are at unauthenticated level code I didn't find a lot of other functionalities to poke around another page I found is :

https://www.antihack.me/email_spoofing

But a single page email spoof checker with only one input, you probably guess it's not vulnerable, right? Nope.

Let's have an attack scenario for this one.  

The attacker: goes to the site and chat with staff or sends the admin an email and says an email script spoof checker returns odd error on his website.

 

The Staff: try to check the script with the hacker site and boom his/her cookies sent to the attacker, and now attacker owns everything, but as there are no bad guys here, don't steal anything we alert some sensitive information.

 

You can watch the video of this attack here.

What the fu*@ just happened? Okay, this one is an exciting look at this code. So basically https://www.antihack.me/check_domain will send a DNS request to target domain to find out SPF and DMARK (Mail authentication records) are set or not which leaks server IP as well in this case server IP is public but for example if target was behind cloud flare or any IP hiding or WAF mechanism this could be alone goldmine as attackers now can talk to IP directly they know target IP rage for network attacks. 

 

Okay, so we found DNS exfiltration, which leaks server ip, and in our case, IP was public, so this is not critical?. Not alone, but the same as other vulnerabilities, it will give us a ring for an exploit chain or at least some idea to play around.  

Now let's look at responsible code. 
 

$.ajax({

    type: 'post',

    url: 'https://www.antihack.me/check_domain',

    data: {

     '_token': $('input[name=_token]').val(),

     'domain': domain[1],

     'email': sEmail

    },

    success: function(data) {

    console.log(data);

    

    if (data.indexOf("FAIL") >= 0){

      var d = data.split("FAIL");

      toastr.error(d[1]);

      return false;

    }

    else{

     setTimeout(function(){   

      var d = data.split("CODE");

      

      if(d[0] == '' || d[1] == ''){

        $("#txt").html('vulnerable to email spoofing');

        $("#txt2").html('No email authentication detected on');

        $("#txt2").addClass('text-red');

        $("#txt").addClass('text-red');

        $("#spf").addClass('text-red');

        $("#dmarc").addClass('text-red');

        $("#btn-1").show();

        $("#btn-2").hide();

      }

      else{

       if(d[2] == 'YES'){

        $("#txt").html('vulnerable to email spoofing');

        $("#txt2").html('No email authentication detected on');

        $("#txt2").addClass('text-red');

        $("#txt").addClass('text-red');

        $("#spf").addClass('text-red');

        $("#dmarc").addClass('text-red');

        $("#btn-1").show();

 

This code will split the response with strings, and they will assign them to HTML or pass them to toast.error() if we got an error. Did you get the issue? It reminds me this vuln. Its quite simple I don't see any output sanitization here. But how we can reach this code?

1- We need to create a new domain

2- Create a TXT domain with SPF1 + FAIL(string) + XSS 

3- Get rendered as valid javascript in toast.error()

4- Profit ! 

 

But again, nothing is that easy. 

 

My domain provider didn't let me create a TXT record with <img> or <script> tag. It will filter them out as XSS; on the other hand, toaster.error doesn't play well with a lot of payloads as well.

 

Classic blacklist filters are such a bother. 

 

So after a bit of trial and error, I come up with this payload, which bypasses my domain provider sanitization and also runs in the content of toaster.error() I created a domain called antipwn.info, and here is the payload for impatient ones.

I created a text record : 

 

"v=spf1 include:spf.efwd.mogistrar-servers.com GOTOFAILClick for more detail : <input autofocus onfocus=eval(atob('YWxlcnQoZG9jdW1lbnQuZG9tYWluK2RvY3VtZW50LmNvb2tpZSk='))> ~all"

 

When code reaches this will split it and finally pass.

 <input autofocus onfocus=eval(atob('YWxlcnQoZG9jdW1lbnQuZG9tYWluK2RvY3VtZW50LmNvb2tpZSk='))> ~all

To the toast.error(), and we will have nice XSS.

Because of the context of this XSS even though we have this in response header: X-XSS-Protection : 1: mode blockAnd also, we got a Chrome/Safari XSS Auditor. This payload will execute on every single modern browser should be able to bypass all XSS protection extensions without any issue. So yea, its quite super XSS, and we pwned an app with a single input, which is genuinely cool.

 

Pro Tip: I guess it's possible to create a lot more new tools than a DNS record checker and classic call to action for attracting customers… 

 

#III Session expiration and logic issue

Here is PoC, a bit modified for unlimited domain spoof check.

curl 'https://www.antihack.me/check_domain' -H 'Cookie: laravel_session=eyJpdiI6ImpONEM2WVVlVytrZlFsYTg1TU1XRmc9PSIsInZhbHVlIjoiUVcxMDg4V3ZvN085R3lFdmZWYlJZRHhVNjBtRjZ3YXhoQXpBaEoxU3NSRWJseW1nZUQ4UURxVHJ0WGNSQWxhMEFKMnpkUlR3RU1IK0c3bjZleXJEakE9PSIsIm1hYyI6ImFlMDlmYjNmMDZjMTA5ZDdiODdlZWUxNGNkOGVhYWQxZDQ5YzJlOWIxMGQ1NjM2MTZmNDE4YWQ0NWVmNzNmNzMifQ%3D%3D' -H 'Origin: https://www.antihack.me' -H 'Accept-Encoding: gzip, deflate, br' -H 'Accept-Language: en-US,en;q=0.9' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36' -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' -H 'Accept: */*' -H 'Referer: https://www.antihack.me/email_spoofing' -H 'X-Requested-With: XMLHttpRequest' -H 'Connection: keep-alive' --data '_token=XWNGPsLub9q3HzZG9oeJHmarLpN93Ih6p9ftISGg&domain=mail.ru&email=me%40pwn.com' —compressed

 

Removed X-CSRF-TOKEN the email parameter doesn't matter; only domain does and seems email is just collected, and we can repeat this request millions of times without the need to solve any captcha or anything. We still need one valid laravel session and one valid _token, which we can intercept and obtain. 

 

#IV admin email and information disclosures 

Admin panel is public, and it's possible to enumerate all admin emails by sending forget password email, which is not a good practice at all, and as admin panel doesn't use HSTS header, any of your employees can perform SSLSTRIP and MITM on it. 

  • path disclosure #1 blog invalid route 
    • https://www.antihack.me/blog/'

       

  • path disclosure #2
  •  path disclosure #3 
    • https://www.antihack.me/writer-signup HTTP/1.1
       ------WebKitFormBoundaryAnything
      Content-Disposition: form-data; name="name"
      
       code'
      
      ———WebKitFormBoundaryAnything
      

       

  • path app code disclosure #4
    •  
      https://www.antihack.me/check_domain send domain without email parameter 

       

Conclusion:

One RCE one modern XSS four path disclosure one session fixation we call it a day for the minimal assets we check. 

 

Now you can guess how many more vulnerabilities we can discover in different components e.g., authenticated environments (usually more vulns there). As I'm getting old, I did not perform a test in their components.

 

Even though I finished my short assessment here, there are always questions you can ask yourself. In our case:

 

  • Does fileuploader.class.php contain any other vulnerability?
  • Is there any other way we can smuggle phar file and exploit laravel unserialized?
  • Is there any other way to trigger mail XSS?
  • What kind of platform-specific attack can we perform based on target stack technology?

 

I spend a day on this assessment, and I just touched the surface here for sure I missed so many vulnerabilities. As you see, I didn't use any special tool for finding these vulnerabilities, so you don't need expensive tools to get results. I just read and explore public code; the whole point of this post is to encourage you to start trying to hunt for vulnerabilities and believe me, you will be amazed by your results just by spending enough time and passionate don't let big brand names scare you as long as human create software and hardware there are vulnerabilities around. 

 

All vulnerabilities reported and fixed by the vendor privately as I don't participate in their program. 

 

That's it folks till then.

Assist me:
Buy Me a Coffee at ko-fi.com