2021CISCN-Re-glass

glass

在这里插入图片描述

将so文件拖入IDA进行分析:

Java_com_ciscn_glass_MainActivity_checkFlag函数

bool __fastcall Java_com_ciscn_glass_MainActivity_checkFlag(int a1, int a2, int a3)
{
  char *input; // r4
  int key_len; // r5
  char key[256]; // [sp+0h] [bp-220h] BYREF
  char v7[260]; // [sp+100h] [bp-120h] BYREF

  input = sub_F0C(a1, a3);
  if ( strlen(input) != 39 )
    return 0;
  memset(v7, 0, 0x100u);
  qmemcpy(key, "12345678", sizeof(key));
  key_len = strlen(key);
  RC4_init(v7, key, key_len);
  RC4_crypt(v7, input, 39);
  crypt2(input, 39, key, key_len);
  return memcmp(input, &unk_497C, 39u) == 0;
}

一个标准的RC4加密之后,进行了另外一个加密crypt2

crypt2函数

int __fastcall sub_10D4(int input, int flag_len, int key, int key_len)
{
  int i; // r4
  int v5; // r6
  char v6; // r5
  char v7; // lr
  char v8; // r12
  int i_1; // lr
  int j; // r6

  for ( i = 0; i < flag_len; i += 3 )
  {
    v5 = input + i;
    v6 = *(input + i + 2);
    v7 = *(input + i + 1);                      // 每次循环取3个
    v8 = *(input + i) ^ v6;
    *(input + i) = v8;                          // 0 = 0 2
    *(v5 + 2) = v6 ^ v7;                        // 2 = 2 1
    *(v5 + 1) = v7 ^ v8;                        // 1 = 1 0 2
  }                                             // 0 1 2
                                                // 从每三位的第一位向左异或
																									//逆向的话就从每三位的第一位向右异或
  for ( i_1 = 0; i_1 < flag_len; i_1 += key_len )
  {
    for ( j = 0; (key_len & ~(key_len >> 31)) != j && i_1 + j < flag_len; ++j )
      *(input + j) ^= *(key + j);
    input += key_len;
  }
  return input;
}

解题脚本

#include <stdio.h>
#include <stdlib.h>

void rc4_init(unsigned char*s,unsigned char*key,unsigned long len)
{
    int i=0;
    int j=0;
    unsigned char k[256]={};
    unsigned char temp = 0;
    for(i=0;i<256;i++)
    {
        s[i]=i;         //0-255赋给s
        k[i]=key[i%len];   //将k重新计算
    }
    for(i=0;i<256;i++)
    {
        j=(j+s[i]+k[i])%256;    //给j赋值
        temp=s[i];
        s[i]=s[j];
        s[j]=temp;    //s[i]和s[j]交换
    }
}

void rc4_crypt(unsigned char*s,unsigned char*data,unsigned long len)
{
    int i=0,j=0,t=0;
    unsigned long k=0;
    unsigned char temp;
    for(k=0;k<len;k++)
    {
        i=(i+1)%256;            //固定方式生成的i
        j=(j+s[i])%256;          //固定方式生成的j
        temp=s[i];
        s[i]=s[j];
        s[j]=temp;             //交换s[i]和s[j]
        t=(s[i]+s[j])%256;      //固定方式生成的t
        data[k]^=s[t];          //来作为s的下标和data进行异或运算
    }
}

int main()
{
    unsigned char s[256]={0};
    int i=0,j=0;
    char key[256] = "12345678";
    unsigned char data[512]={0xA3, 0x1A, 0xE3, 0x69, 0x2F, 0xBB, 0x1A, 0x84, 0x65, 0xC2, 0xAD, 0xAD, 0x9E, 0x96, 0x05, 0x02,0x1F, 0x8E, 0x36, 0x4F, 0xE1, 0xEB, 0xAF, 0xF0, 0xEA, 0xC4, 0xA8, 0x2D, 0x42, 0xC7, 0x6E, 0x3F,0xB0, 0xD3, 0xCC, 0x78, 0xF9, 0x98, 0x3F, 0x00};
    unsigned long data_len = 39;
    unsigned long key_len = 8;
    for(i=0;i<39;i+=key_len)
    {
        for (j = 0; (key_len & ~(key_len >> 31)) != j && i + j < 39; ++j)
        {
            data[i+j] = data[i+j] ^ key[j];
        }
    }
    for(i=0;i<data_len;i+=3)
    {
        //向右循环回去
        data[i+1] = data[i] ^ data[i+1];
        data[i+2] = data[i+1] ^ data[i+2];
        data[i] = data[i+2] ^ data[i];
    }
    rc4_init(s,(unsigned char*)key,key_len);//初始化得到s
    rc4_crypt(s,(unsigned char*)data,data_len);//解密
    for(i=0;i<39;i++)
    {
        printf("%c",data[i]);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值