buuctf [GUET-CTF2019]encrypt纯静态做法

二刷buu,发现网上的这个题的题解大部分都是动调(可能是我没找到静态),于是想写一篇纯静态分析的文章。

这个题的考点如名字所示,就是一个魔改base64和rc4加密。
首先拖进ida
在这里插入图片描述
上面那8个硬编码赋值一看就像key,直接改了个名。
看到结尾的密文对比,顿时有了个大致方向
在这里插入图片描述

进入sub_4006B6函数里面,发现是rc4的s盒初始化
在这里插入图片描述
传入的参数是放s盒的数组,key和key的长度
在这里插入图片描述
没看出来的可以看下这个博客,关于rc4加密的
https://www.cnblogs.com/zwios/p/4196836.html
然后下面的sub_4007DB函数显然就是rc4的crypt函数,查看代码发现没有魔改,很棒。
接下来看sub_4008FA函数
在这里插入图片描述
这里从padding和&0x3f等很容易联想到base64(从最后对比的密文也可以很容易联想到),但是这里的base64和正常的base64不一样,因为我们惊奇的发现没有表,而换成了另一种逻辑:
1.把我们的输入(rc4加密过的输入)三个字节一组,变成四个六位的数(这里和base64原理一样)
2.把四个数每个加上61,存入输出的数组之中。
对,就改了第二步,所以我们直接手撕一下就行。
由此,总的程序逻辑清晰了:
1.先将输入rc4加密,key已知。
2.将加密的结果魔改base64加密
3.和密文进行对比
脚本如下:

from base64 import *
import binascii
from Crypto.Util.number import *
duibi="Z`TzzTrD|fQP[_VVL|yneURyUmFklVJgLasJroZpHRxIUlH\\vZE="
# for i in range(len(duibi)-1):
#     print(hex(ord(duibi[i])-61),end=",")#得到shuru
shuru=[0x1d,0x23,0x17,0x3d,0x3d,0x17,0x35,0x7,0x3f,0x29,0x14,0x13,0x1e,0x22,0x19,0x19,0xf,0x3f,0x3c,0x31,0x28,0x18,0x15,0x3c,0x18,0x30,0x9,0x2e,0x2f,0x19,0xd,0x2a,0xf,0x24,0x36,0xd,0x35,0x32,0x1d,0x33,0xb,0x15,0x3b,0xc,0x18,0x2f,0xb,0x1f,0x39,0x1d,0x8,0]
def four_to_three(a1,a2,a3,a4):
    return (a1<<18)|(a2<<12)|(a3<<6)|a4
for i in range(0,len(shuru),4):
    temp=four_to_three(shuru[i],shuru[i+1],shuru[i+2],shuru[i+3])
    a1=temp>>16
    a2=(temp>>8)&0xff
    a3=(temp)&0xff
    print(hex(a1)[2:].rjust(2,'0'),end="")
    print(hex(a2)[2:].rjust(2,'0'), end="")
    print(hex(a3)[2:].rjust(2,'0'), end="")
data1="7635fdf57d47fe95137a26593fff31a1857c63026ebd936a3e4d8dd727732d5ecc62f2dfe5d2"
def rc4_crypt(text,key):
    textlen=len(text)
    keylen=len(key)
    ciper=[]
    count=0
    s=list(range(256))
    for i in range(256):
        count=(count+s[i]+key[i%keylen])%256
        s[i],s[count]=s[count],s[i]
    i=0
    j=0
    for m in range(textlen):
        i=(i+1)%256
        j=(j+s[i])%256
        s[i],s[j]=s[j],s[i]
        k=s[(s[i]+s[j])%256]
        ciper.append(k^text[m])
    ciper_text=''.join("%02x"%i for i in ciper)
    return ciper_text.upper()
if __name__ == "__main__":
    data = '7635fdf57d47fe95137a26593fff31a1857c63026ebd936a3e4d8dd727732d5ecc62f2dfe5d2'
    key = '1020303020201040'
    print()
    print("rc4 result:", rc4_crypt(binascii.a2b_hex(data), binascii.a2b_hex(key.upper())))
    print(long_to_bytes(0x666C61677B65313061646333393439626135396162626535366530353766323066383833657D))

这里由于密文最后有=,所以我们需要在shuru数组最后加一个0作为padding,然后丢进rc4加密。加密的结果去掉最后的俩0就行。

有不对的地方希望师傅们提出来,一定改正

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值