re学习笔记(63)BJDCTF3-re-ViQinere|py2

好久没做题了,,,手都生疏了。费半天劲也就做了两道,,,在线求大腿
第一题ViQinere解题脚本>=97写成了>97楞是找了俩小时的BUG,,,
py2题一个简单的原生tea加密,,因为字面值默认是32位导致运算的时候溢出了,又找了好几个小时的BUG,,,,,

ViQinere

在这里插入图片描述
看输出前的那个加密函数
在这里插入图片描述
里面的jiami()函数是这样的
在这里插入图片描述
整个加密逻辑就在那一个函数里,,写逆脚本,,,爆破也可
nc连接服务器得到加密后的密文
在这里插入图片描述

#include <stdio.h>
#include <string.h>
int bh(char x)
{
    if (x > 96 && x <= 122)
        return x - 97;
    else if (x >= 65 && x <= 90)
        return x - 65 - 128;
    else return x;
}

char TaQini[] = "TaQini";
char abcd[] = "zyxwvutsrqponmlkjihgfedcba";

int main(void)
{
    int i, n = 0, p, j, k;
    char result[54] = "FQD{GfjuJ5UbLrWjZjpvErXkiAZzlvO0xTa!cwnLLAsy3B0iEvEy}";
    char flag[55] = { 0 },temp;
    for (i = 0; i < 54; i++)
    {
        if (result[i] >= 97 && result[i] <= 122)
        {
            temp = bh(TaQini[n++ & 5]);
            p = strchr(abcd, result[i]) - abcd;
            p = p - (temp & 0x7f) + 97;
            while (p < 97) p += 26;
            while (p > 122)p -= 26;
            flag[i] = p;
        }
        else if (result[i] >= 65 && result[i] <= 90)
        {
            temp = bh(TaQini[n++ & 5]);
            p = strchr(abcd, result[i]+32) - abcd;
            p = p - (temp & 0x7f) + 65;
            while (p < 65) p += 26;
            while (p > 90) p -= 26;
            flag[i] = p;
        }
        else flag[i] = result[i];
    }
    puts(flag);
}

在这里插入图片描述
得到flag BJD{ThisI5MyViQiNireCiPheRHaveY0uTr!edtOBRut3F0rCeIt}
再进行MD5 32位加密就可提交,得到378e148c67dbf85b15bdd0f54a7fa71d

py2

下载下来是个pyo文件,去在线pyc,pyo反编译python反编译反编译得到源代码

import ctypes
from base64 import b64encode, b64decode
 
def decode():
    fd = open('./libc.so', 'rb')
    data = fd.read()
    fd.close()
    fd = open('./libc.so', 'wb')
    fd.write(b64decode(data))
    fd.close()
 
 
def check():
    if b64encode(pwd) == 'YmpkMw==':
        decode()
        dl = ctypes.cdll.LoadLibrary
        lib = dl('./libc.so')
        reply = lib.check
        reply(int(flag[:length // 2], 16), int(flag[length // 2:], 16), int(pwd.encode('hex'), 16))
        print 'your input is BJD{%s}' % flag.decode('hex')
    else:
        print 'your password is wrong!'
 
 
if __name__ == '__main__':
    print 'Please input your flag:'
    flag = raw_input()
    flag = flag.encode('hex')
    length = len(flag)
    print 'Please input your password:'
    pwd = raw_input()
    check()

读取了flag,将其转换为十六进制字符串
读取密码pwd然后base64加密和'YmpkMw=='比较
然后对so文件进行base64解密,可以先运行一次取出解密后的so文件进行静态分析
然后将flag的十六进制字符串分成前后两部分,解释成数值,和pwd='bjd3’解释成十六进制一起传进so文件的check方法内

so文件的check方法
在这里插入图片描述
code方法是原生tea,只不过将32位改成了64位。。
在这里插入图片描述
根据传进去的参数我们可以得到,*a2 a2[1] a2[2] a2[3]是tea的密钥,是check函数里的v4[4]数组
并且全部相等且等于bjd3的十六进制字符串对应的数值也就是0x626a6433

而a1则是待加密的数据,分成了两个64位数据,即v4、v5来加密

加密完后,将v4、v5又重新赋值到a1的地址,并在check函数内进行比较,若相等则成功,不相等则失败

关于tea加密可以看re加密算法:RSA|SM4|RC4|MD5|Tea
解题脚本

脚本需要注意的地方就是tea的sum值,按照32位数的时候会溢出,而我偷懒没有计算出来粘贴上去,而是直接左移5位,,导致溢出算不出来,,,
解决方法是手动计算出SUM赋给变量,或者字面值后添加LL后缀显式表明是64位值,,,

#include <stdio.h>
#include <string.h>
int main()
{
    unsigned __int64 v4, v5,v6;
    v4 = 0x0AF9D869B6947017D;
    v5 = 0x0D760262509C2F6D0;
    int i = 32;
    v6 = 0x9E3779B9LL<<5; //字面值默认为32位值,进行的是32位运算,会溢出
    __int64 a2 = 0x626a6433;
    while (i--)
    {
        v5 -= (v4 + v6) ^ ((v4 << 4) + a2) ^ ((v4 >> 5) + a2);
        v4 -= (v5 + v6) ^ ((v5 << 4) + a2) ^ ((v5 >> 5) + a2);
        v6 -= 0x9E3779B9;

    }
    printf("%.8llx %.8llx", v4, v5);
    return 0;
}

在这里插入图片描述
得到结果 676f745f 74656121
转换为字符串得到got_tea!
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Forgo7ten

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值