|
& Y0 R M. @# W4 J& ^1 z T
在OWASP发布的top10排行榜中SQL注入漏洞一直是危害排名极高的漏洞,数据库注入一直是web中一个令人头疼的问题OWASP,Open Web Application Security Project,开放式Web应用程序安全项目:。 `0 m$ o; ~: q. _ `8 G
这是一个提供有关计算机和互联网应用程序的公正、实际、有成本效益信息的组织其目的是协助个人、企业和机构来发现和使用可信赖软件一个严重的SQL注入漏洞,可能会直接导致一家公司破产!这并不是戏言,其实SQL注入漏洞最主要的形成原因是在进行数据交互中,当前端的数据传入后端进行处理时,由于没有做严格的判断,导致其传入的“数据”在拼接到SQL语句中之后,由于其特殊性,被当作SQL语句的一部分被执行,从而导致数据库受损(被脱库、被删除、甚至整个服务器权限沦陷)。
h: v: ?9 ]( e; P" D0 _, ]% s 一、什么是SQL注入SQL注入是一种非常常见的数据库攻击手段,SQL注入漏洞也是网络世界中最普遍的漏洞之一大家也许都听过某某学长通过攻击学校数据库修改自己成绩的事情,这些学长们一般用的就是SQL注入方法。
5 g" X+ _6 ?( m5 P- M. _ SQL注入其实就是恶意用户通过在表单中填写包含SQL关键字的数据来使数据库执行非常规代码的过程简单来说,就是数据「越俎代庖」做了代码才能干的事情这个问题的来源是,SQL数据库的操作是通过SQL语句来执行的,而无论是执行代码还是数据项都必须写在SQL语句之中,这就导致如果我们在数据项中加入了某些SQL语句关键字(比如说SELECT、DROP等等),这些关键字就很可能在数据库写入或读取数据时得到执行。 " w; I" J+ h( F. E+ Q' O
二、SQL注入的产生需要满足以下两个条件1、参数用户可控:前端传给后端的参数用户可控。 4 m, P7 Y5 i% u; H
2、参数带入数据库查询:传入的参数拼接到SQL语句中,且带入数据库中查询。
- h& g4 C7 x1 V% I2 G/ J4 u 正是这个拼接的过程导致了代码的注入多言无益,我们拿真实的案例来说话下面我们先使用SQLite建立一个学生档案表SQL数据库操作示例:import sqlite3连接数据库:conn = sqlite3.connect(test.db)建立新的数据表:conn.executescript(DROP TABLE IF EXISTS students; W, P. z% d: }/ c
CREATE TABLE students+ |+ O! T3 ]3 Q
(id INTEGER PRIMARY KEY AUTOINCREMENT,9 t! R/ l& R- B7 J
name TEXT NOT NULL);)插入学生信息:students = [Paul,Tom,Tracy,Lily]- @: r0 B7 |* n1 D
1 q. M+ m' z0 G8 G( t* x4 v
for name in students:
6 E, B( G2 e* U0 h0 l query = "INSERT INTO students (name) VALUES (%s)" % (name)
5 S3 J$ z8 f5 U. W conn.executescript(query);检视已有的学生信息:cursor = conn.execute("SELECT id, name from students")& n9 t" l% b0 G
print(IDName)& T5 q0 y L3 w3 V
for row in cursor:
: }7 W5 ^" @7 v9 R) e9 m: n print({0}{1}.format(row[0], row[1]))
1 b5 ]; q4 G+ L6 U
3 k3 _4 _( q6 L5 \; ^' {* ` conn.close()。 2 @ A( G9 a& ?; o0 W
点击运行按钮,将会打印目前表中的内容上述程序中我们建立了一个test.db数据库以及一个students数据表,并向表中写入了四条学生信息那么SQL注入又是怎么一回事呢?我们尝试再插入一条恶意数据,数据内容就是漫画中的"Robert);DROP TABLE students;--",看看会发生什么情况。
* n0 f2 O" Z4 _3 W0 O SQL数据库注入示例:conn = sqlite3.connect(test.db)
% F) X" A# A3 ?) v 插入包含注入代码的信息:name = "Robert);DROP TABLE students;--"4 o% b5 G/ f8 E( {
query = "INSERT INTO students (name) VALUES (%s)" % (name)3 K$ s5 V. K: [7 Y& _7 F
h6 Q R/ I: o7 }3 F% |
conn.executescript(query)检视已有的学生信息:cursor = conn.execute("SELECT id, name from students")
% \7 p1 \- D* h print(IDName)
; i/ n7 U* Q' |0 g+ g. o; m for row in cursor:
& x; k( K; y8 ^ U$ k- ] print({0}{1}.format(row[0], row[1]))
" l, S+ o8 c1 y, x# g# L' S
6 Y! g7 e- B8 L conn.close()
- T- a: V. `0 _. u% S2 u- h+ j 你将会发现,运行后,程序没有输出任何数据内容,而是返回一条错误信息:表单students无法找到!这是为什么呢?问题就在于我们所插入的数据项中包含SQL关键字DROP TABLE,这两个关键字的意义是从数据库中清除一个表单。
- r+ @" c+ R4 ~% \; y 而关键字之前的Robert);使得SQL执行器认为上一命令已经结束,从而使得危险指令DROP TABLE得到执行也就是说,这段包含DROP TABLE关键字的数据项使得原有的简单的插入姓名信息的SQL语句:。 / @9 z5 D0 [$ X# X0 j
INSERT INTO students (name) VALUES (Robert)变为了同时包含另外一条清除表单命令的语句:INSERT INTO students (name) VALUES (Robert);DROP TABLE students; 2 a/ ]8 d6 x* n" t2 A
而SQL数据库执行上述操作后,students表单被清除,因而表单无法找到,所有数据项丢失当然,现在很多网站都有了防止SQL注入的操作,这里就不过多介绍了关于如何防止防止SQL注入,后期安仔这边会整理,如果你急用的话,可以百度搜索,了解一下。 % K- K6 B( w9 i2 g
SQL注入说白了,就是通过把SQL命令插入到WEB表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令三、SQL注入类型:1、按照注入点分类:(1)数字型注入:许多网页链接有类似的结构 。 2 M; z- G0 x, q. \3 s" G
http://xxx.com/users.php?id=1 基于此种形式的注入,注入点id为数字,一般被叫做数字型注入点,通过这种形式查询出后台数据库信息返回前台展示,可以构造类似以下的SQL语句进行爆破:select *** from 表名 where id=1 and 1=1。 9 s; p! u5 V. p* w; f; l
(2)字符型注入:网页链接有类似的结构http://xxx.com/users.php?name=admin 这种形式,注入点name为字符串,被称为字符型注入,可以用:select *** from 表名 where name=admin and 1=1。 ! x6 C* y: L- x
(3)搜索型注入:主要是指在数据搜索时没有过滤搜索参数,一般在链接地址中有 "keyword=“关键字”",注入点提交的是SQL语句,select * from 表名 where 字段 like %关键字% and %1%=%1%。 6 n% [4 }" X6 l1 N7 f) d0 \) I1 u
2、按照执行效果来分类:(1)基于布尔的盲注:根据页面返回判断条件真假注入(2)基于时间的盲注:即不能根据页面返回内容判断任何信息,用条件语句查看时间延迟语句是否执行(即页面返回时间是否增加)来判断(3)基于报错的注入:
2 T6 A0 W5 P& ^( x9 D- Q6 n* l, B 即页面会返回错误信息,或者把注入的语句的结果直接返回在页面中单引号双引号基于数字型注入(4)联合查询注入:可以使用union情况下注入四、SQL注入常见的绕过方法(1)大小写关键词绕过(UNiOn)(2)双写关键词绕过(ununionion) + W# Q" n3 d; K& e6 B$ X
(3)编码绕过(base64、url)(4)内联注释绕过(/*! Union */) 7 X7 [, X& ~2 I1 D
" M9 M$ G9 V: _, r8 f4 I
( I' n- @0 O) Y5 h/ f- J7 p* {
7 ^4 W2 L- ]0 {2 d* v5 r: L" V
" Q+ c! E8 E e5 U& T! m |