Category Archives: Vulnerabilities

CVE-2013-4339: Two Exploits for WordPress 3.6 URL Redirect Restriction Bypass

According to WordPress, version 3.6 is affected by a URL Redirect Restriction Bypass issue that allows an attacker to craft a URL in such a way that, should it be clicked, would take the victim to a site of the attacker’s choice via the Location: tag in a 302 Redirect. Current descriptions of the WordPress issue may be found at WordPress (1, 2), Mitre and OSVDB.

I can confirm that this issue exists in versions 3.1 and 3.6. Due to the range of versions, I assume that it exists in all releases in between but I have not confirmed it. If running an outdated version of WordPress please upgrade to the latest version, which is 3.6.1 at the time of this writing. The current 3.6.1 release fixes four additional issues (1, 2, 3, 4) as well.

There are two attack vectors: the first is a full URL redirect; the second is a partial redirect, as the victim is automatically taken to a WordPress error page with the attacker’s link embedded in a prominently displayed tag.

In order for either exploit to work (assuming the victim clicks on the link) two conditions must be true: first, the victim must be logged into the site (wp-admin); and second, they must have permission to the editing page (edit-tags.php or edit-comments.php). If either of these two conditions are false the vulnerable code will not be reached.

Exploit 1: edit-tags.php Full URL Direct

The above exploit URL will do a full redirect when the link is clicked on by the victim. It is important to note that in order for the exploit to work the string ‘edit-tags.php’ must be present in the _wp_http_referer parameter. For example:

In this case I chose to put it after a ‘?’ and by doing so I create a dummy parameter so that any valid URL before the ‘?’ executes on the attacker’s server. Under normal circumstances servers such as Apache and IIS will not view web application parameters (the stuff after the ‘?’) as pointing to valid server files to execute. On the application side, WordPress should discard the extra parameter.

Alternatively an attacker may create a URL such as:

This URL has a ‘/’ instead of a ‘?’. This means that the attacker would need to create a valid page named ‘edit-tags.php’ on the attacker’s server in order to have their code run.

The normal WordPress login code prevents access to any page under wp-admin if the user has not authenticated. After authentication, the code in edit-tags.php below prevents users without permission from accessing the page:

Exploit 2: edit-comments.php Embedded Link Partial Redirect

The above exploit URL will embed the attackers link in the error page of WordPress with the text “Please try again” as seen in the image below.


Similar to Exploit 1, the normal WordPress login code prevents access to any page under wp-admin if the user has not authenticated. After authentication, the code in edit-comments.php below prevents users without permission from accessing the page:

Vulnerability: CVE-2013-1421 – WebCalendar 1.2.5 & 1.2.6 Category Name Persistent XSS

WebCalendar versions 1.2.5 and 1.2.6 contain a Persistent XSS in the Category Name field. Version 1.2.5 was tested and then compared with 1.2.6 to determine that the vulnerability is in both versions. Please see screen shots below.

Vulnerability: CVE-2013-1422 – WebCalendar 1.2.5 & 1.2.6 Valid User Determination

WebCalendar versions 1.2.5 and 1.2.6 allow an attacker to determine a valid user id on the system. After submitting an invalid ID the software, “Invalid Login: no such user.” Please see screen shot below.


Publicly Disclosed Vulnerabilities & Exploits between 2000-2006

Here is a list of my publicly disclosed vulnerabilities from 2000 through 2006. I figure these should be added to my public OSVDB profile. (I actually have two!) It’s 2013. These were found a long time ago. Still, I did the work; why not receive the credit?

It should be emphasized that these are vulnerabilities that were publicly disclosed and not the totality of those that I’ve discovered between 2000-2006.  If I can find additional ones I will update this as necessary. This page is more for historical accuracy and record keeping than anything else.

Date CVE / CAN / BID Vuln Name and Link
08/25/00 CVE-2000-0777 MS00-061 : Microsoft Money Password Vulnerability
11/01/01  CAN-2001-0721 MS01-054: Microsoft UPnP Denial of Service Vulnerability
11/08/01 BID: 3518 IBM HTTP Server Source Code Disclosure Vulnerability
02/07/02 BID: 4059 OS/400 User Account Name Disclosure Vulnerability
02/18/02 CVE-2002-0291 Dino’s Webserver Denial of Service Vulnerability
02/21/02 CVE-2002-0298 Nombas ScriptEase:WebServer Edition GET Request Denial of Service Vulnerability
03/22/02 CVE-2002-0479 Gravity Storm Service Pack Manager 2000 Directory Permissions Vulnerability
06/25/02 BID: 5094 Microsoft Internet Explorer CLASSID Denial of Service Vulnerability
06/30/02 BID: 5357 Microsoft Windows mplay32 Buffer Overflow
10/08/02 CVE-2002-1529 SurfControl SuperScout Email Admin Server XSS
10/08/02 CVE-2002-1530 SurfControl SuperScout Email Admin Server Data Integrity
10/09/02 CVE-2002-1531 SurfControl SuperScout Email Admin Server Content-Length: DoS
10/09/02 CVE-2002-1532 SurfControl SuperScout Email Admin Server Incomplete Get Request DoS
08/29/05 CVE-2005-2787 Vulnerability and Perl Exploit: SimplePHPBlog
05/17/06 CVE-2006-2531 Ipswitch WhatsUp Professional 2006 Authentication Bypass Vulnerability

Vulnerability: OrangeHRM 2.7.1 Vacancy Name Persistent XSS

OrangeHRM 2.7.1 — the latest stable release as of this writing — suffers from a persistent XSS in the vacancy name variable. Steps:

  1. Navigate to following URL:
  2. Add or Edit a Vacancy
  3. In the Vacancy Name parameter put XSS script
  4. Save
  5. Navigate back to top Vacancy page (click back button)
  6. Witness XSS

Screen prints in the gallery below. The images should be self-explanatory.The direct URL to the list of vacancy page is below.

I contacted OrangeHRM but did not receive a reply.

PHP uniqid() – Entropy Analysis and Potentially Vulnerable Apps

This research started with my reporting a zero-day that Front Accounting’s reporting used uniqid() and it’s file names were non-random. Given where the application saves these reports by default they are retrievable by anyone who can guess the proper URL report name. OSVDB asked me to what extent does this issue overlap with a larger, previously reported PHP issue of non-randomness in the generation of PHPSESSIONID. Over the course of my research I discovered that, while both suffered issues of non-randomness, uniqid() and LCG were independent from each other after PHP3. As of PHP4+, uniqid() is not used to generate session cookies. While uniqid()  uses an LCG randomness routine it only does so when the more_entropy flag is set by the developer. LCG is not the cause of the lack of uniqid() entropy. In fact it is just the opposite. It helps it when the flag is set but not significantly. As such it is my humble opinion that CVE and OSVDB descriptions needed to be updated to reflect this information. In our tweets Steve Christey was still worried — and rightly so — that many applications use the uniqid() function and might be vulnerable. So, here we are.

It’s clear that uniqid() is non-random. This is even reported in the PHP documentation. The question is how non-random is it? Furthermore, what’s the impact? How many apps are using the function?

I tested the non-randomness by writing some sample PHP code taken almost straight from the documentation. I did this because I felt it best to use the sample code provided by PHP to their users. I assume here that it will be the way most people will use the function (copy and paste). Two apps were written: one to test the function regularly and one to test it with added entropy. Since I’m not a math geek, I used burp‘s Sequencer functionality to test the entropy. I have fairly smallish sample sizess but I believe I do not need a larger ones to change the general nature of the result. (I leave this to the next researcher.) I then used Search Diggity to scan through google’s project code as well as doing a direct search. I attached a gallery with annotations showing the testing procedure and results.


With or without the more_entropy option, uniqid(), as represented in the PHP sample code and documentation, results in poor entropy and should not be used. According to burp, with a sample size of 4016 tokens, uniqid() without more_entropy is “extremely poor” and has a effective entropy of 10 bits. With a sample size of 7515 tokens, uniqid() with more_entropy enabled is “poor” with an effective entropy of 29 bits. According to burp the reliability of the sample sizes were either reasonable or good. It is my opinion that if the tests were conducted over a larger sample size the effective entropy will only decrease: by how much I’m not certain.

The question remains: are there vulnerable applications and to what extent? Search Diggity returns 100 instances of uniqid() being used on google code. Google’s own search engine returns 60K+ strings matching uniqid(). Important:  google’s query is a bit of a false indicator since it returns results that matches the string including languages other than PHP. And, I didn’t scan other repositories such as Sourceforge or Github.

Lesson 1: heed the PHP documentation and do not use uniqid() when the need for a random string arises. Lesson 2: it seems that there is a decent amount of potential vulnerable code.

Below are the pictures to support the research. Many thanks to OSVDB and Steve Christy for an excellent exchange of tweets. Enjoy and happy hunting.

PHP uniqid() and LCG non-randomness write-up

In twitter conversations with OSVDB the question arose whether the Front Accounting 2.3.13 Predictable File Name and Public Path vulnerability I disclosed yesterday had a connection with a previously reported LCG vulnerability in 2010 since the LCG in PHP apparently uses the uniqid() function.

Although there is a loose connection, the upshot is that they are different. Here’s why.

After checking though the PHP SVN this morning, it seems like the connection is tenuous at best. If we begin with the LCG revisions we notice that in branches 5.2 and 5.3 that we are adding entropy through as shown below:

But from our standpoint — determining the connection between LCG and uniqid() — this doesn’t matter much. It’s the fact that it uses the following structure and call:

The call to uniqid() also uses the timeval structure:

Unlike LCG, uniqid() adds it’s randomness in the following way:

Since randomness is added differently, the gettimeofday() function is in fact the only overlap between uniqid.c and lcg.c that concerns us to understand the connection and the difference for this analysis.

For our purposes to answer OSVDB’s initial inquiry the answer comes down to this:

  • Both LCG and the uniqid() function use the same gettimeofday call as the initial seed for randomness, whether through returning a string for uniqid() or as part of PHPSESSIONID
  • LCG and uniqid() are totally separate and use independent calls to fill data structures defined in separate areas of memory
  • the functions do not call one another at all
  • LCG uses the php_combined_lcg() function which does not use uniqid() in any functions below it for session token creation

From an attackers point of view, the key in the LCG attack is the ability to use a function such as uniqid() — which is much more likely to be used by a developer — to get the server’s seed (actual time on the box) and off of which we will base our attack on the PHPSESSIONID since neither offer enough entropy.

Conclusion 1: LCG does not use uniqid() as it’s seed generator. We can see this from the SVN of the committed LCG code linked to earlier: uniqid was neither removed or added. A quick search of the actual LCG code will show that this header or function is not included in the PHPSESSION generating code. The description in NVD and OSVDB is is in fact incorrect for the 2010 attack*.

Conclusion 2: The non-randomness I described in my Front Accounting vuln release is based solely off the uniqid() function and is independent from the LCG functions although both have a similar but not exact non-randomness issue.

I cannot take full credit for this as some of the critical pieces of the LCG attack analysis come from Andreas Bogk in this post at Full-Disclosure.

* The original post of the LCG issue in 2001 shows that PHPLIB session.c called uniqid() but code apparently is for PHP3 and is no longer maintained since 2007. This is most likely where the NVD / OSVBD confusion comes from. Note that the write-up and tool released by samy kamkar for the 2010 disclosure does not mention uniqid(). At no point is uniqid() used in session.c as described in the original 2001 post as of PHP4.

0-Day: Front Accounting 2.3.13 Predictable File Name and Public Path

Front Accounting (FA) had document storage capabilities. Three issues arise:

1) FA stores documents under the server root
2) FA uses a non-random way to generate the report names
3) these reports do not have any authentication, able to be retrieved by anyone

The known file locations are below where X is company number starting at 0 (zero).


The software uses the uniqid PHP routine which is known for being non-random:

Because it is difficult to show, please see the screen print below regarding the non-random name.

I emailed the software company through their website but did not receive a reply. This was also disclosed to but I believe it was not publicly reported since the email contained the image below as an attachment (or the original email was HTML and not TXT).


Forbes: Stuxnet may be of Chinese Origin

A logical alternative theory of who targeted Iran:

In 2008, China decided to assist the IAEA inspectors after it learned that Iran was in possession of blueprints to shape uranium metal into warheads, according to this article in The Telegraph. That same article discloses that Chinese designs for centerfuges were discovered in Iran, supplied via Pakistan’s AQ Khan.

On April 13, 2010, Beijing reiterated its opposition to Iran’s goal to develop nuclear weapons capabilities while stating that sanctions against Iran would be counter-productive. In other words, the PRC wanted to support its third largest supplier of oil (after Saudi Arabia and Angola) while at the same time seeking ways to get Iran to stop its uranium fuel enrichment program. What better way to accomplish that goal than by covertly creating a virus that will sabotage Natanz’ centerfuges in a way that simulates mechanical failure while overtly supporting the Iranian government by opposing sanctions pushed by the U.S. It’s both simple and elegant.

Bottom line: we’ll never know unless someone comes forward.

Unannounced Ethical Hacking

The French Twitter hacker claimed it was an ethical hack. This defense has rarely been credible in the US since 9/11 due to the uptick in professional services and change in cultural mindset.

… he wanted to reveal just how vulnerable online data systems are to break-ins — and he says he didn’t mean any harm.”I’m a nice hacker,” suspect Francois Cousteix told France 3 television Thursday, a day after he was released from police questioning, adding that his goal was to warn Internet users about data security.

Here is why I no longer report security vulnerabilities I find.