刷题笔记:[NPUCTF2020]web狗


前言

我摊牌了,就是懒得写前端
<?php
error_reporting(0);
include('config.php');   # $key,$flag
define("METHOD", "aes-128-cbc");  //定义加密方式
define("SECRET_KEY", $key);    //定义密钥
define("IV","6666666666666666");    //定义初始向量 16个6
define("BR",'<br>');
if(!isset($_GET['source']))header('location:./index.php?source=1');


#var_dump($GLOBALS);   //听说你想看这个?
function aes_encrypt($iv,$data)
{
    echo "--------encrypt---------".BR;
    echo 'IV:'.$iv.BR;
    return base64_encode(openssl_encrypt($data, METHOD, SECRET_KEY, OPENSSL_RAW_DATA, $iv)).BR;
}
function aes_decrypt($iv,$data)
{
    return openssl_decrypt(base64_decode($data),METHOD,SECRET_KEY,OPENSSL_RAW_DATA,$iv) or die('False');
}
if($_GET['method']=='encrypt')
{
    $iv = IV;
    $data = $flag;
    echo aes_encrypt($iv,$data);
} else if($_GET['method']=="decrypt")
{
    $iv = @$_POST['iv'];
    $data = @$_POST['data'];
    echo aes_decrypt($iv,$data);
}
echo "我摊牌了,就是懒得写前端".BR;

if($_GET['source']==1)highlight_file(__FILE__);
?>

还给了HelloWorld.class

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

public class HelloWorld {
    public HelloWorld() {
    }

    public static void main(String[] var0) {
        System.out.println("众所周知,你是一名WEB选手,掌握javaweb也是一项必备技能,那么逆向个java应该不过分吧?");
        byte[] var10000 = new byte[]{102, 108, 97, 103, 123, 119, 101, 54, 95, 52, 111, 103, 95, 49, 115, 95, 101, 52, 115, 121, 103, 48, 105, 110, 103, 125};
    }
}

题解

先看到HelloWorld.class,

一堆数字,很像是ascii码。

解个码

这是干嘛?

先看看加密结果

IV:6666666666666666
ly7auKVQCZWum/W/4osuPA==

Padding Oracle攻击

padding oracle针对的是加密算法中的CBC Mode,当加密算法使用CBC Mode时,如果满足攻击条件,那么利用Padding Oracle能够在不知道密钥的情况下,解密任意密文,或者构造出任意明文的合法密文

针对的是CBC模式,而不是某一个加密算法,所以任何分组加密算法,只要使用了CBC模式,都会受到影响。此类加密算法包括AES、DES、3-DES、Blowfish

条件:

  • 已知密文+IV(初始化向量)
  • 可触发解密过程且知道密文解密结果

cbc,IV已知,密文已知,

原理复杂,直接抄代码吧

# coding:utf-8
import requests
import base64
import time

# b'\x97.\xda\xb8\xa5P\t\x95\xae\x9b\xf5\xbf\xe2\x8b.<'
CYPHERTEXT = base64.b64decode("ly7auKVQCZWum/W/4osuPA==")
# initialization vector
IV = "6666666666666666"
# PKCS7 16个字节为1组
N = 16
# intermediaryValue ^ IV = plainText
middle = ""
plainText = ""
# 爆破时不断需要更改的iv
iv = ""
URL = "http://4772e5d6-efa2-4d4d-a22d-b9d7e03266bb.node4.buuoj.cn:81/index.php?source=1&method=decrypt"


def xor(a, b):
    """
    用于输出两个字符串对位异或的结果
    """
    return "".join([chr(ord(a[i]) ^ ord(b[i])) for i in range(len(a))])


for step in range(1, N + 1):
    padding = chr(step) * (step - 1)
    print(step, end=",")
    for i in range(0, 256):
        """
        iv由三部分组成:
            待爆破位置 chr(0)*(N-step)
            正在爆破位置 chr(i)
            使 iv[N-step+1:] ^ middle = padding 的 xor(padding,middle)
        """
        iv = chr(0) * (N - step) + chr(i) + xor(padding, middle)
        data = {
            "data": "ly7auKVQCZWum/W/4osuPA==",
            "iv": iv
        }
        r = requests.post(URL, data=data)
        time.sleep(0.1)
        if r.text != "False":
            middle = xor(chr(i), chr(step)) + middle
            print(middle)
            break
plainText = xor(middle, IV)
print(plainText)

爆出FlagIsHere.php。整无语了,一开始抄的其他博客的代码,折腾半天跑不出来,最后发现那个博客少复制了一段……

KiDFHJhflXUyK/v/spFuuQ==
<?php
#error_reporting(0);
include('config.php');    //$fl4g
define("METHOD", "aes-128-cbc");
define("SECRET_KEY", "6666666");
session_start();

function get_iv(){    //生成随机初始向量IV
    $random_iv='';
    for($i=0;$i<16;$i++){
        $random_iv.=chr(rand(1,255));
    }
    return $random_iv;
}

$lalala = 'piapiapiapia';

if(!isset($_SESSION['Identity'])){
    $_SESSION['iv'] = get_iv();

    $_SESSION['Identity'] = base64_encode(openssl_encrypt($lalala, METHOD, SECRET_KEY, OPENSSL_RAW_DATA, $_SESSION['iv']));
}
echo base64_encode($_SESSION['iv'])."<br>";

if(isset($_POST['iv'])){
    $tmp_id = openssl_decrypt(base64_decode($_SESSION['Identity']), METHOD, SECRET_KEY, OPENSSL_RAW_DATA, base64_decode($_POST['iv']));
    echo $tmp_id."<br>";
    if($tmp_id ==='weber')die($fl4g);
}

highlight_file(__FILE__);
?>

CBC翻转攻击

import base64


def add(s):
    # 块长度为128位=16个字节,需要补齐,填充模式是PK7
    t = 16 - len(s)
    p = r'\x' + hex(t)[2:].zfill(2)
    print(s + p * t)


# add('weber')
# 在python3里,需要传入byte类型,否则将会自动解码hex,记得补齐
target = b'weber\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b'  # 目标字符串
orginal = b'piapiapiapia\x04\x04\x04\x04'  # 源字符串

iv = base64.b64decode('5g0fBClXjQo96618lfQHnw==')  # 初始向量
result = b''
for i in range(16):
    result += bytes([target[i] ^ iv[i] ^ orginal[i]])

print(base64.b64encode(result))
b'4QEcETI99mhXkM8WmvsIkA=='

一开始生成的sRpq7ZA2Eo4vGkeq9EJp+Q==不行,清理了下cookie就重新生成就OK了,难道是加号的缘故?

原来正常操作是这个网盘能下载之前那个helloworld.class文件。

参考链接

Padding Oracle Attack的一些细节与实现


文章作者: 巡璃
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 巡璃 !
评论
  目录