WEB漏洞—SQL注入之类型及提交注入

WEB漏洞—SQL注入之类型及提交注入

Snipaste_2022-04-26_14-46-46

在前期进行注入的时候,需要了解的三个东西,一个是【数据库类型】、【数据类型】、【提交方法】

  • 一个是数据库不同的话,注入的方式也不同
  • 数据类型的话分为:数字, 字符,搜索,JSON等
  • 请求方法主要是:GET、POST、COOKIE、REQUEST、HTTP头等

Snipaste_2022-04-26_14-56-03

如果网站的SQL语句是这样写的,那么你在做SQL注入的时候,就需要注意闭合单引号,因为网站这里采用的是字符型,当然有的时候就算是数字,也需要闭合单引号。

还有一种情况就是,搜索型,在MySQL中如果要搜索一个东西,那么具体的SQL语句就是像下面一样,在关键字前后都加上一个百分号,那么你就不仅要闭合单引号还需要闭合百分号,这样才可以做到注入

Snipaste_2022-04-26_14-57-33

从上面两个例子,可以总结到,进行SQL注入的时候,需要对目标网站的数据库类型和类型还有提交方式进行一个收集,或者判断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php

$get=$_GET['g'];
echo $get;

$post=$_POST['p'];
echo $post;

$cookie=$_COOKIE['c'];
echo $cookie;

$requext=$_REQUEST['r'];
echo $requext;

$server=$_SERVER['HTTP_USER_AGENT'];
echo $server;

?>

Snipaste_2022-04-26_16-50-39

从这里可以看到如果是使用get方式,那么就会显示123

这个是数据包的情况

Snipaste_2022-04-26_16-54-14

然后我用g=123&p=456,结果还是123,这里是因为,我用的就是get方式提交的,所以,这里就没有显示456

Snipaste_2022-04-26_16-52-36

这个是数据包的情况,可以看到p在get提交,所以这里当然不会显示456

Snipaste_2022-04-26_16-55-59

然后我分别用get方式提交123,post 方式提交456,可能这里看到这里是post提交,认为是只显示456,但是get有一个特性就是只要在网址后面就可以接收到

Snipaste_2022-04-26_16-57-00

Snipaste_2022-04-26_16-57-28

接下来是cookie

Snipaste_2022-04-26_17-11-35

可以从图中看到,因为我不是真正的一个网站没有进行真正的交互,所以我要在数据包中进行更改,这里我改成了xxxxx,可以看到burp的预览模块中,同样也显示了xxxx

还有一种是requext的提交方式,如果是这种方式的话,就不用管是什么提交方式,因为如果是这种方式的话,不管是get方式还是post提交方式,以及cookie的方式,都是可以正常接收的。

那么为什么要说明这几种方式的不同或者说区别呢?因为在对网站进行注入的时候,一个网站可能只对一种提交方式做了过滤,那么我这个时候就可以用另外的提交方式进行绕过。如果是get,那么我就可以改为post,或者反过来,如果是cookie我就可以从post和get上下手,如果是requext那么我三种方式都可以试一试

如何判断网站可以使用哪几种的接收方式,如果目标网站默认是用get方式进行提交的话,那么我就可以更改这个get方式提交的内容,用post进行提交,如果网站没有变化,说明网站是可以用这种方式进行提交的

例子:127.0.0.1/index.php?id=1

Snipaste_2022-04-26_17-22-12

最后就是:$_SERVER

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
$_SERVER['HTTP_ACCEPT_LANGUAGE']//浏览器语言
$_SERVER['REMOTE_ADDR'] //当前用户 IP 。
$_SERVER['REMOTE_HOST'] //当前用户主机名
$_SERVER['REQUEST_URI'] //URL
$_SERVER['REMOTE_PORT'] //端口。
$_SERVER['SERVER_NAME'] //服务器主机的名称。
$_SERVER['PHP_SELF']//正在执行脚本的文件名
$_SERVER['argv'] //传递给该脚本的参数。
$_SERVER['argc'] //传递给程序的命令行参数的个数。
$_SERVER['GATEWAY_INTERFACE']//CGI 规范的版本。
$_SERVER['SERVER_SOFTWARE'] //服务器标识的字串
$_SERVER['SERVER_PROTOCOL'] //请求页面时通信协议的名称和版本
$_SERVER['REQUEST_METHOD']//访问页面时的请求方法
$_SERVER['QUERY_STRING'] //查询(query)的字符串。
$_SERVER['DOCUMENT_ROOT'] //当前运行脚本所在的文档根目录
$_SERVER['HTTP_ACCEPT'] //当前请求的 Accept: 头部的内容。
$_SERVER['HTTP_ACCEPT_CHARSET'] //当前请求的 Accept-Charset: 头部的内容。
$_SERVER['HTTP_ACCEPT_ENCODING'] //当前请求的 Accept-Encoding: 头部的内容
$_SERVER['HTTP_CONNECTION'] //当前请求的 Connection: 头部的内容。例如:“Keep-Alive”。
$_SERVER['HTTP_HOST'] //当前请求的 Host: 头部的内容。
$_SERVER['HTTP_REFERER'] //链接到当前页面的前一页面的 URL 地址。
$_SERVER['HTTP_USER_AGENT'] //当前请求的 User_Agent: 头部的内容。
$_SERVER['HTTPS']//如果通过https访问,则被设为一个非空的值(on),否则返回off
$_SERVER['SCRIPT_FILENAME'] #当前执行脚本的绝对路径名。
$_SERVER['SERVER_ADMIN'] #管理员信息
$_SERVER['SERVER_PORT'] #服务器所使用的端口
$_SERVER['SERVER_SIGNATURE'] #包含服务器版本和虚拟主机名的字符串。
$_SERVER['PATH_TRANSLATED'] #当前脚本所在文件系统(不是文档根目录)的基本路径。
$_SERVER['SCRIPT_NAME'] #包含当前脚本的路径。这在页面需要指向自己时非常有用。
$_SERVER['PHP_AUTH_USER'] #当 PHP 运行在 Apache 模块方式下,并且正在使用 HTTP 认证功能,这个变量便是用户输入的用户名。
$_SERVER['PHP_AUTH_PW'] #当 PHP 运行在 Apache 模块方式下,并且正在使用 HTTP 认证功能,这个变量便是用户输入的密码。
$_SERVER['AUTH_TYPE'] #当 PHP 运行在 Apache 模块方式下,并且正在使用 HTTP 认证功能,这个变量便是认证的类型

可以看到这个网站很大可能就是用$_SERVER,来判断我的浏览器和操作系统还有屏幕分辨率的信息的

Snipaste_2022-04-26_17-31-34

然后抓包修改之后

Snipaste_2022-04-26_17-33-30

Snipaste_2022-04-26_17-34-00

可以看到这里也同样进行了修改。 那么这个时候不妨试想一下,如果这个网站对这个数据带入到数据库中进行查询,那么这里就会产生一个注入漏洞。

演示案例:

参数字符型注入测试—>sqllilabs less 5 6

POST数据提交注入测试—->sqllilabs less 11

参数JSON数据注入测试—->本地环境代码演示

COOKIE数据提交注入测试—–>sqllilabs less 20

HTTP头部参数数据注入测试—–>sqllilabs less 18

参数字符型注入测试—>sqllilabs less 5 6

【这里有一个小坑,就是之前由于为了开启魔术引号,将php的版本降到5.2的版本,然后这关的注入就有问题了,最后我将php的版本改到了5.6.9,然后就没有问题了】

查看源代码,可以看到这一关对这个id这里的进行单引号闭合,所以在做这一关的时候,需要闭合单引号。

$sql=”SELECT * FROM users WHERE id=’$id’ LIMIT 0,1”;【这个是源代码】

然后构造注入语句

http://127.0.0.1/sqli-labs-master/Less-5/?id=1‘ and ‘1’=’2 –+

这样就可以闭合单引号,带入到数据库中的样子是?

$sql=”SELECT * FROM users WHERE id=’1’ and ‘1’=’2’ LIMIT 0,1”;【就是这个样子,其实这里的1加不加两个单引号都可以,加上单引号,我个人认为是因为2是字符型,所以左边的1也需要是字符型,但是本意就是让其报错,所以这里是数字型还是字符型,意义都不大了】

第五关就单纯说明一个单引号的问题,这里涉及后面的布尔盲注

第六关

$id = ‘“‘.$id.’”‘;

看到这里的语句,个人理解是连接了两个字符型的双引号,所以这里就是需要闭合双引号就可以了

和第五关其他都一样,就单引号改为双引号

Snipaste_2022-04-26_18-16-23

http://127.0.0.1/sqli-labs-master/Less-6/index.php?id=1“ and 1=2–+

第11关

Snipaste_2022-04-26_18-17-15

后面的流程就不演示了。。。

Snipaste_2022-04-26_18-34-34

关于为什么–+不行,#就可以,我复制了三条弹幕,感觉都对

  • POST是否编码是由请求头中的“Content-Type”决定的
  • hackbar中post框的+号不会被转码成空格
  • –+中的+在URL里面是空格,在post传输的时候是+,所以如果在URL连接中添加空格需要进行URL编码【这个后面有一个弹幕说不行。。】

第20关

首先说一下怎么用渗透版火狐,清楚当前页面的cookie,因为我直接用admin和admin进行登陆的话是直接过关的。。。

Snipaste_2022-04-26_18-50-57

Snipaste_2022-04-26_18-51-28

这样就可以了

然后进行注入,这一关考验的是cookie注入

弹幕大神:看了下源码,两个条件cookie不为空且submit为空即可绕过,post提交方式去掉submit也行,要么就是直接像他这样GET请求

弹幕大神2:点submit抓post包也可以,只要把post传的submit那项去掉就行,cookie照常注入

Snipaste_2022-04-26_19-13-12

后面的流程就不进行了,照常注入即可

第18关

Snipaste_2022-04-26_19-56-25

很直观的看到这里有一个IP地址,那么这里极有可能是,有$_SERVER函数,那么就可以用$_SERVER注入进行尝试

JSON

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于ECMAScript的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C、C++、C#Java、JavaScript、PerlPython等)。这些特性使JSON成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成(一般用于提升网络传输速率)。

JSON 语法

JSON 语法规则
JSON 语法是 JavaScript 对象表示语法的子集。

数据在键值对中
数据由逗号分隔
花括号保存对象
方括号保存数组

JSON 名称/值对
JSON 数据的书写格式是:名称/值对。

名称/值对组合中的名称写在前面(在双引号中),值对写在后面(同样在双引号中),中间用冒号隔开。

JSON 值
JSON 值可以是:
数字(整数或浮点数)
字符串(在双引号中)
逻辑值(true 或 false)
数组(在方括号中)
对象(在花括号中)
null

基础结构

JSON结构有两种结构

1、对象:对象在js中表示为“{}”括起来的内容,数据结构为 {key:value,key:value,…}的键值对的结构,在面向对象的语言中,key为对象的属性,value为对应的属性值,所以很容易理解,取值方法为 对象.key 获取属性值,这个属性值的类型可以是 数字、字符串、数组、对象几种。
2、数组:数组在js中是中括号“[]”括起来的内容,数据结构为 [“java”,”javascript”,”vb”,…],取值方式和所有语言中一样,使用索引获取,字段值的类型可以是 数字、字符串、数组、对象几种。
基础示例

简单地说[2] ,JSON 可以将 JavaScript 对象中表示的一组数据转换为字符串,然后就可以在函数之间轻松地传递这个字符串,或者在异步应用程序中将字符串从 Web 客户机传递给服务器端程序。这个字符串看起来有点儿古怪,但是JavaScript很容易解释它,而且 JSON 可以表示比”名称 / 值对”更复杂的结构。例如,可以表示数组和复杂的对象,而不仅仅是键和值的简单列表。

*名称 / 值对*
按照最简单的形式,可以用下面这样的 JSON 表示”名称 / 值对”:

1
{"firstName":"Brett"}