BUUCTF-[安洵杯 2019]crackMe1

题目下载:下载

这道题涉及到SM4加密和变表base64。

SM4简单了解:SM4算法过程_不是小白才怪的博客-CSDN博客_sm4算法

先运行一下程序,

发现有一个Messagebox,并且内容是hooked。

载入IDA,使用IDA的插件Findcrypt查看有没有什么加密算法。加密算法一般都是关键,在做题前可以养成这个习惯。

 发现有Base64和SM4,跟进base64:

发现对base64表进行了大小写互换,然后调用了MessageBoxA函数(这个再上面执行程序的时候出现过) 。

MessageBox指的是显示一个模态对话框,其中包含一个系统图标、 一组按钮和一个简短的特定于应用程序消息,如状态或错误的信息。消息框中返回一个整数值,该值指示用户单击了哪个按钮。

参数:

int MessageBox(
  [in, optional] HWND    hWnd,
  [in, optional] LPCTSTR lpText,
  [in, optional] LPCTSTR lpCaption,
  [in]           UINT    uType
);

第一个参数:hWnd
该参数是一个窗口句柄,指定该对话框的所有者窗口。如果该参数为空(0/NULL),则该对话框不属于任何窗口。

第二个参数:lpText
该参数是一个字符串,指显示在对话框中的内容。

第三个参数:lpCaption
也是是一个字符串,指对话框的标题。如果此参数为空,则默认使用“错误”作为标题

第四个参数:nType
指定显示按钮的数目及形式,使用的图标样式,缺省按钮是什么以及消息框的强制回应等。

然后下面有AddVectoredExceptionHandler()函数

AddVectoredExceptionHandler(First,Handler):注册向量异常处理程序

参数:

第一个参数:First

应调用处理程序的顺序。 如果参数为非零,则处理程序是第一个要调用的处理程序。 如果参数为零,则处理程序是要调用的最后一个处理程序。

第二个参数:Handler

指向要调用的处理程序的指针。

所以就是当messageboxA后发生异常,触发了 AddVectoredExceptionHandler()函数异常处理,调用了Handler。

跟进Handler:
是SM4加密,密钥是“where_are_u_now?”,正好是128比特,符合sm4长度特征。

跟进sub_411172()看一看里面的SM4加密:

回到sm4加密函数处,有个SetUnhandledExceptionFilter()函数

SetUnhandledExceptionFilter():使应用程序能够取代进程的每个线程的顶级异常处理程序。

调用此函数后,如果在未调试的进程中发生异常,并且异常会将其设置为未处理的异常筛选器,该筛选器将调用 lpTopLevelExceptionFilter 参数指定的异常筛选器函数。

所以发生异常会调用TopLevelExceptionFilter,跟进:

 跟进sub_41126C:

将原来的base64的'='补位变成了'!',并且其中还有一个凯撒移位间接变表。

所以整体逻辑:str1即用户输入经过sm4加密,base64表的大小写互换与移位后的base加密结果与str2两两互换相等。

from pysm4 import decrypt, encrypt
import base64
#sm4密钥
key = "where_are_u_now?"
mk=key.encode().hex()
#str2位置互换
str2='1UTAOIkpyOSWGv/mOYFY4R=='
str2_lst=list(str2)                #字符串不能被修改,
for i in range(0,len(str2),2):
    v2=str2_lst[i]
    str2_lst[i]=str2_lst[i+1]
    str2_lst[i+1]=v2
str2=''.join(str2_lst)
#求base64的变表
base64_table='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
base64_table2=''
for i in base64_table:
    if i.isupper():
        base64_table2+=chr(ord(i)+32)
    elif i.islower():
        base64_table2+=chr(ord(i)-32)
    else:
        base64_table2+=i
base64_table3=''
for i in base64_table2:
    base64_table3+=base64_table2[(base64_table2.index(i)+24)%64]
#base解密
biao=str.maketrans(base64_table3,base64_table)
cipher=base64.b64decode(str2.translate(biao).encode('utf-8'))
cipher=cipher.hex()
#sm4解密
cipher= 0x59d095290df2400614f48d276906874e
mk = 0x77686572655f6172655f755f6e6f773f
flag=decrypt(cipher,mk)
print('flag{'+bytes.fromhex(hex(flag)[2:]).decode()+'}')










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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值