plc
ida打开 patch掉反调试
首先读取输入,若长度不为5则退出
然后将输入作为rc4密钥进行s盒置换
v78[0] = main_main_func1;
v78[1] = v34;
v82 = v78;
v35 = v34;
All = io_ReadAll(off_4DD9D8, v34, v78, 0, 1, v36, v37, v38, v39, v63, v67);
v45 = v77->ptr;
if ( v77->len <= 1 )
runtime_panicIndex(1LL);
v75 = All;
v73 = v45[1];
v46 = runtime_makeslice(&RTYPE_uint8, v35, v35, 0, 1, v41, v42, v43, v44, v64, v68, v71);
v48 = v75;
v49 = v35;
for ( i = 0LL; v49 > i; ++i )
*(v46 + i) = v73 ^ *(v48 + i);
v51 = v76;
v52 = *(v76 + 1024);
v53 = *(v76 + 1025);
for ( j = 0LL; v49 > j; ++j )
{
v55 = *(v51 + 4LL * ++v52);
v53 += v55;
v56 = *(j + v46);
*(v51 + 4LL * v52) = *(v51 + 4LL * v53);
*(v51 + 4LL * v53) = v55;
v47 = (v55 + *(v51 + 4LL * v52));
*(v46 + j) = *(v51 + 4 * v47) ^ v56 ^ 0x11;
}
*(v51 + 1024) = v52;
*(v51 + 1025) = v53;
os_WriteFile("./flag.png", 10, v46, v49, v49, 420, v52, v53, v47, v65, v69, *v70, v72);
(*v82)();`
首先获取flag.png 然后将数据与输入的第二个字符异或后进行魔改rc4加密
rc4是单字节加密,且png文件头前八位不变,可以利用010读取加密过的flag文件头,然后仿写算法对密钥进行爆破
#include<stdio.h>
#include<string.h>
#define N 4010
void rc4_init(unsigned char* s, unsigned char* key, unsigned long Len_k)
{
unsigned int i = 0, j = 0;
char k[256] = { 0 };
unsigned char tmp = 0;
for (i = 0; i < 256; i++) {
s[i] = i;
k[i] = key[i % Len_k];
}
for (i = 0; i < 256; i++) {
j = (j + s[i] + k[i]) % 256;
tmp = s[i];
s[i] = s[j];
s[j] = tmp;
}
}
void rc4_crypt(unsigned char* Data, unsigned long Len_D, unsigned char* key, unsigned long Len_k) //加解密
{
unsigned char s[256];
rc4_init(s, key, Len_k);
int i = 0, j = 0, t = 0;
unsigned long k = 0;
unsigned char tmp;
for (k = 0; k < Len_D; k++) {
i = (i + 1) % 256;
j = (j + s[i]) % 256;
tmp = s[i];
s[i] = s[j];
s[j] = tmp;
t = (s[i] + s[j]) % 256;
Data[k] = Data[k] ^ s[t] ^0x11;
}
}
int main(){
unsigned char key[]={30,30,30,30,30,0};
unsigned long key_len = sizeof(key) - 1;
unsigned char datat[]= {0x89,0x50,0x4E,0x47,0x0D,0x0A,0x1A,0x0A};
unsigned char data[] = {0x89,0x50,0x4E,0x47,0x0D,0x0A,0x1A,0x0A};
unsigned char tr[]={0x85,0x43,0x72,0x78,0x26,0xc0,0x2e,0x6e};
int cnt=1;
while(1){
rc4_crypt(data, sizeof(data), key, key_len);
for (int i=0;i<8;i++) data[i]^=key[1];
for (int i = 0; i < sizeof(data); i++){
if ((data[i])!=tr[i]){
break;
}
if (i==4) {
for (int j = 0; j < sizeof(key); j++){
printf("%c",key[j]);
}
return 0;
}
}
for (int i=0;i<8;i++) data[i]=datat[i];
for (int i=0;i<5;i++){
if (key[i]<125){
key[i]++;
break;
}else{
key[i]=30;
}
if (i==2) printf("%d\n",key[4]);
}
if (key[4]==124) return 0;
}
return 0;}
爆破得到密码为0173d 利用rc4加密对称性,输入0173d即可还原flag
docCrack
宏VBA密码工程文件密码破解 - 『脱壳破解区』 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn
破解后看里面函数
tempPath = ThisDocument.Path & "\temp1"
Set tempfile = fso.CreateTextFile(tempPath, True)
fso.GetFile(tempPath).Attributes = 1
tempfile.WriteLine xpkdb
tempfile.Close
batPath = ThisDocument.Path & "\temp.bat"
Set batFile = fso.CreateTextFile(batPath, True)
fso.GetFile(batPath).Attributes = 2#改为1
batFile.WriteLine "@echo off"
batFile.WriteLine "cd /d " & ThisDocument.Path
batFile.WriteLine "certutil -decode temp1 temp|certutil -decode temp temp.exe"
batFile.WriteLine "del temp"#删掉
batFile.WriteLine "temp.exe " & """" & Result & """"
batFile.Close
Set objExec = objShell.Exec(batPath)
Set objStdOut = objExec.StdOut
Do While Not objStdOut.AtEndOfStream
output = Trim(objStdOut.ReadLine)
Loop
output = Left(output, Len(output))
StartTime = Timer
Do While Timer < StartTime + 1
DoEvents
Loop
fso.DeleteFile batPath
fso.DeleteFile tempPath
If output = "good" Then
temp = MsgBox("good!!!", , "congratulations!!!")
Exit Do
Else
temp = MsgBox("Sorry, U are wrong!!!", , "Hacked_by_??????")
isContinue = MsgBox("Continue?", vbYesNo + vbQuestion, "Warning")
End If
使用bat创建了一个temp.exe 执行后删除
我们修改代码使其可见并不被删除 执行宏 拖入ida
if ( argc == 2 )
{
for ( j = 0; j < j_strlen(argv[1]) && j < 0x36; ++j )
v7[j + 64] = argv1 << 6;
for ( j = 0; j < 0x36; ++j )
{
if ( v7[j] != v7[j + 64] )
{
sub_7FF77FF91190("bad");
return 0;
}
}
sub_7FF77FF91190("good");
return 0;
}
else
{
sub_7FF77FF91190("no way!!!");
return 1;
}
//发现是将输入数据向左移6位 写脚本解密
#include<stdio.h>
#include<string.h>
#define N 4010
int main(){
unsigned char ida_chars[] =
{
0xC0, 0x10, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00, 0x15,
0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0xC0, 0x14, 0x00, 0x00,
0x40, 0x10, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x40, 0x14,
0x00, 0x00, 0x40, 0x19, 0x00, 0x00, 0x80, 0x19, 0x00, 0x00,
0x00, 0x16, 0x00, 0x00, 0x80, 0x0D, 0x00, 0x00, 0x00, 0x1D,
0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0xC0, 0x18, 0x00, 0x00,
0x80, 0x19, 0x00, 0x00, 0x40, 0x1A, 0x00, 0x00, 0x00, 0x18,
0x00, 0x00, 0x80, 0x18, 0x00, 0x00, 0x40, 0x1D, 0x00, 0x00,
0x00, 0x1A, 0x00, 0x00, 0x80, 0x1C, 0x00, 0x00, 0x00, 0x1D,
0x00, 0x00, 0x80, 0x09, 0x00, 0x00, 0x80, 0x09, 0x00, 0x00,
0x80, 0x09, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x40, 0x11,
0x00, 0x00, 0x80, 0x0D, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00,
0x80, 0x19, 0x00, 0x00, 0x40, 0x1D, 0x00, 0x00, 0x80, 0x18,
0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0xC0, 0x0D, 0x00, 0x00,
0x40, 0x18, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x80, 0x12,
0x00, 0x00, 0x80, 0x19, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00,
0x40, 0x1D, 0x00, 0x00, 0xC0, 0x0D, 0x00, 0x00, 0x00, 0x16,
0x00, 0x00, 0x40, 0x14, 0x00, 0x00, 0x80, 0x0D, 0x00, 0x00,
0x40, 0x1D, 0x00, 0x00, 0x80, 0x1C, 0x00, 0x00, 0x80, 0x0C,
0x00, 0x00, 0x80, 0x18, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00,
0x80, 0x09, 0x00, 0x00, 0x80, 0x09, 0x00, 0x00, 0x80, 0x09,
0x00, 0x00, 0x80, 0x1E, 0x00, 0x00
};
for (int i=0;i<sizeof(ida_chars);i+=4){
printf("%c",((((ida_chars[i+1]<<8)|(ida_chars[i]))&0xffff)>>6));//CFTDSA|QefX6tXcfi`buhrt&&&XE6pfubX7aXJfdu7XQ6ur2bt&&&z
}
结果均为可见字符,这里随便猜一下是异或,将前六位异或“DASCTF”发现结果均为7
char tt[]="CFTDSA|QefX6tXcfi`buhrt&&&XE6pfubX7aXJfdu7XQ6ur2bt&&&z";
for (int i=0;i<sizeof(tt);i++){
printf("%c",tt[i]^7);
}
得到flag
你这主函数保真吗
找到加密逻辑在__static_initialization_and_destruction_0函数里
挨个看,发现首先对输入进行ROT13,再进行离散余弦变换后与密文比较
for ( i = 0; i < size; ++i )
{
for ( j = 0; j < size; ++j )
{
v5 = *std::vector<int>::operator[](j, v10);
v2 = cos((j + 0.5) * (i * 3.141592653589793) / size);
v6 = v2 * v5;
v3 = std::vector<double>::operator[](i, v11);
*v3 = *v3 + v6;
}
if ( i )
v4 = sqrt(2.0 / size);
else
v4 = sqrt(1.0 / size);
v7 = v4;
eax9 = std::vector<double>::operator[](i, v12);
*eax9 = *eax9 * v7;
}
return retstr;
//首先进行逆离散余弦变换,然后进行rot13解密
#include <stdio.h>
#include <math.h>
char rot13(char c) {
// 检查字符是否为大写字母
if (c >= 'A' && c <= 'Z') {
return 'A' + (c - 'A' + 13) % 26;
}
// 检查字符是否为小写字母
else if (c >= 'a' && c <= 'z') {
return 'a' + (c - 'a' + 13) % 26;
}
// 其他字符保持不变
return c;
}
#define N 33 // DCT的大小
int main() {
double out[N] = { 513.355, -37.7986, 8.7316, -10.7832, -1.3097, -20.5779, 6.98641, -29.2989,
15.9422, 21.4138, 29.4754, -2.77161, -6.58794, -4.22332, -7.20771, 8.83506,
-4.38138, -19.3898, 18.3453, 6.88259, -14.7652, 14.6102, 24.7414, -11.6222,
-9.754759999999999, 12.2424, 13.4343, -34.9307, -35.735, -20.0848, 39.689,
21.879, 26.8296/* 在这里填入你的DCT输出数据 */ };
double input[N];
double v2, v5, v6, v3;
// IDCT 计算
for (int i = 0; i < N; ++i) {
v3 = 0.0;
for (int j = 0; j < N; ++j) {
v5 = out[j]; // DCT系数
v2 = (j == 0) ? sqrt(1.0 / N) : sqrt(2.0 / N); // 权重
v6 = v2 * cos((i + 0.5) * (j * M_PI) / N); // 余弦函数
v3 += v5 * v6; // 累加结果
}
input[i] = v3; // 还原的输入值
printf("%c", (int)(input[i]+0.5));
}
printf("\n");
char tt[]="QNFPGS{Ju0_1f_Zn1a_@aq_ShaaL_Qpg}";
for (int i=0;i<sizeof(tt);i++){
printf("%c",rot13(tt[i]));
}
return 0;
}
rustVM
题目难度简单 直接ida打开,看一眼逻辑
进行一些初始化操作,随便输入一点东西动态调试跑起来
这里进行长度检测和头尾检测,然后异或值匹配头部和尾部
同样是比较头尾和检验长度的操作,应该是混淆
这里有一大坨0x3f加上位运算,调试发现是对输入base64
然后传入关键函数,这个函数多次出现,flag经过base64转化为base64_res传入
找到关键的vm函数,进行简单分析
这里的opcode比较复杂,不同二进制位控制不同流程,上两位控制最外层,下位控制数组下标,这里写了一个加法器和一个异或器,下面还有一大堆重复调用,调试后发现a1[1048]决定a[1052]的大小,而在check里a[1052]必须为0,调试其他函数发现加法器并不影响值,直接断在异或处,反复调试拿到数据,异或一把梭。
import base64
#aa = [0x18,0x18,0x33,0xb1,0x18,0x9,0x36,0xa4,0xe,0xa6,0x13,0x2a,0x1c,0x9e,0x33,0x1b,0xc,0x96,0x36,0x57,0x05,0x5d,0x26,0xad,0x0c,0xae,0x36,0x75,0xd,0x65,0x25,0xac,0xd,0x9,0x3,0x8c,0x10,0xa0,0x35,0x76,0x0e,0x47,0x16,0x2c,0x8,0x10,0x38,0x01,0x0e,]
a = [0,0x82,0x11,0x92,0xa8,0x39,0x82,0x28,0x9a,0x61,0x58,0x8b,0xA2,0x43,0x68,0x89,0x4,0x8f,0xB0,0x43,0x49,0x3A,0x18,0x39,0x72,0xc,0xBa,0x76,0x98,0x13,0x8b,0x46,0x33,0x2B,0x25,0xA2,0x8b,0x27,0xB7,0x61,0x7C,0x3F,0x58,0x56]
b= [0x18,0xb1,0x9,0xa4,0xA6,0x2A,0x9E,0x1B,0x96,0x57,0x5D,0xAd,0xAE,0x75,0x65,0xAC,0x09,0x8C,0xA0,0x76,0x47,0x2C,0x10,0x01,0x7C,0x0f,0xBa,0x47,0x95,0x30,0x9b,0x74,0x3f,0x2D,0x2D,0x9A,0x87,0x31,0xBa,0x43,0x70,0x2C,0x4C,0x56]
cc=[]
for i in range(0,len(a)):
cc.append(a[i]^b[i])
print(cc)
dd="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=`"
flag = ''
for i in range(0,len(cc)):
# print(table[each],end='')
flag+= dd[cc[i]]
print(base64.b64decode(flag.encode("utf-8")))
(还有frida爆破和ponce爆破的方法,未完待续)
Comments | NOTHING