[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__);
?>
<?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__);
?>
解题步骤
竟然考密码学。直接无了
参考wp:https://tiaonmmn.github.io/2020/04/23/BUUOJ%E5%88%B7%E9%A2%98-Web-WebDog/
弄半天弄不明白啥原理,关键有个文章竟然在审核,直接麻了。大概懂一点。
贴里面的padding脚本
# 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
inermediaryValue = ""
plainText = ""
# 爆破时不断需要更改的iv
iv = ""
URL = "http://75943db7-6c4b-49df-a6dc-fc3cb9439966.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):
# print(i)
"""
iv由三部分组成:
待爆破位置 chr(0)*(N-step)
正在爆破位置 chr(i)
使 iv[N-step+1:] ^ inermediaryValue = padding 的 xor(padding,inermediaryValue)
"""
iv = chr(0)*(N-step)+chr(i)+xor(padding,inermediaryValue)
data = {
"data": "ly7auKVQCZWum/W/4osuPA==",
"iv": iv
}
r = requests.post(URL,data = data)
while r.status_code != 200:
time.sleep(0.1)
r = requests.post(URL, data=data)
if r.text !="False":
inermediaryValue = xor(chr(i),chr(step)) + inermediaryValue
print(inermediaryValue)
break
plainText = xor(inermediaryValue,IV)
print(plainText)
原理和wp里面说的一样。按照填充规则,缺k位,就填充k个0xk。然后用这个规律去填充iv,从而爆破中间值。
条件:
知道iv,不清楚加密Key,能够区分解密成功与否
得到FlagIsHere.php
然后就是字节翻转(好像叫这个吧)。
贴脚本
import requests
import base64
url = 'http://75943db7-6c4b-49df-a6dc-fc3cb9439966.node4.buuoj.cn:81/FlagIsHere.php'
target = b'weber\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b'
orginal = b'piapiapiapia\x04\x04\x04\x04'
iv = base64.b64decode('5k47/QkcbyEWau0LNWvorg==')
result = b''
for i in range(16):
result+=bytes([target[i] ^ iv[i] ^ orginal[i]])
print(base64.b64encode(result))
这也是根据填充规则来搞得。
然后得到一个网址。在buu上直接下载附件就行。
class文件,idea直接打开,然后ascii即可
总之,涉及深层的加解密原理不太懂,只能做做脚本小子罢了