ISCC_re

本文介绍了一个Python脚本,该脚本涉及字符串校验和解密。脚本通过异或运算检查给定的`flag`是否满足特定条件,即与预设的ASCII值序列进行异或运算后的和为0。此外,还展示了C语言的函数实现,用于对输入字符串进行一系列操作,包括减去64、异或、倒序排列等。最后,通过逆向分析`mix`函数,推测原始明文。
摘要由CSDN通过智能技术生成

garden

pyc反编译一下

#!/usr/bin/env python
# visit https://tool.lu/pyc/ for more information
import platform
import sys
import marshal
import types

def check(s):
    f = '2(88\x006\x1a\x10\x10\x1aIKIJ+\x1a\x10\x10\x1a\x06'
    if len(s) != len(f):
        return False
    checksum = None
    for a, b in zip(f, s):
        checksum += ord(b) ^ ord(a) ^ 123
    
    return checksum == 0

if sys.version_info.major != 2 or sys.version_info.minor != 7:
    sys.exit('\xe8\xaf\x95\xe8\xaf\x95 Python 2.7.')
if len(sys.argv) != 2:
    sys.exit('usage: bronze.pyc <flag>')
flag = sys.argv[1]
if len(flag) >= 32:
    print '\xe5\xa4\xaa\xe9\x95\xbf\xe4\xba\x86.'
    sys.exit(1)
alphabet = set('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789{}!@#$%+')
for ch in flag:
    if ch not in alphabet:
        print '\xe4\xb8\x8d\xe5\xaf\xb9.'
        sys.exit(1)
        continue
if check(flag):
    print '\xe5\xb0\xb1\xe6\x98\xaf\xe8\xbf\x99\xe4\xb8\xaa!'
    sys.exit(0)
else:
    print '\xe6\x90\x9e\xe9\x94\x99\xe4\xba\x86.'
    sys.exit(1)

有几个输出的东西不太对劲,不过不影响,应该只是一些提示信息, 

关键函数:

 下面flag要传进函数中的s,最后要满足checksum为0,

ord()把字符转成ascii或unciode码,这些码都是正数,所以异或完还是正数

所以  要满足和为0,需要每项都是0

所以所以      ord(b) ^ ord(a) ^ 123==0

所以所以所以    b= chr(ord(a) ^ 123)

脚本:


f = '2(88\x006\x1a\x10\x10\x1aIKIJ+\x1a\x10\x10\x1a\x06'
for i in f:
    b = chr(ord(i) ^ 123)
    print(b, end='')

Analysis

题目本身和题目名字,题目说明一样直白

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char Plaintext[3]; // [esp+11h] [ebp-97h] BYREF
  _BYTE v5[57]; // [esp+14h] [ebp-94h] BYREF
  int v6; // [esp+4Dh] [ebp-5Bh]
  char input[64]; // [esp+51h] [ebp-57h] BYREF
  char v8[7]; // [esp+91h] [ebp-17h] BYREF
  int v9; // [esp+98h] [ebp-10h]
  int i; // [esp+9Ch] [ebp-Ch]

  __main();
  v6 = 0;
  memset(v5, 0, 4 * (((Plaintext - v5 + 64) & 0xFFFFFFFC) >> 2));
  Plaintext[0] = 67;
  Plaintext[1] = -33;
  Plaintext[2] = 20;
  v5[0] = 3;
  v5[1] = 13;
  v5[2] = 44;
  v5[3] = 9;
  v5[4] = 1;
  v5[5] = 23;
  v5[6] = 23;
  v5[7] = 8;
  v5[8] = -4;
  v5[9] = 43;
  v5[10] = -6;
  v5[11] = 20;
  v5[12] = 23;
  v5[13] = -7;
  v5[14] = 37;
  v5[15] = -11;
  v5[16] = 34;
  v5[17] = 61;
  v5[18] = -50;
  v5[19] = 24;
  v5[20] = 22;
  v5[21] = 10;
  qmemcpy(v8, "REVERSE", sizeof(v8));
  v9 = strlen(Plaintext);
  printf(Format);
  scanf("%s", input);
  mix(input, v8, v9);
  for ( i = 0; i < v9; ++i )
  {
    if ( input[i] != Plaintext[i] )
    {
      puts(Buffer);
      return 0;
    }
  }
  puts(aFlag);
  return 0;
}

从最后的循环判断,推出谁是plaintext明文,

关键是用明文逆mix函数推input

int __cdecl mix(char *input, char *key, int len_P)
{
  char v3; // dl
  int result; // eax
  char v5; // [esp+14h] [ebp-24h]
  int n; // [esp+18h] [ebp-20h]
  int m; // [esp+1Ch] [ebp-1Ch]
  int l; // [esp+20h] [ebp-18h]
  size_t k; // [esp+24h] [ebp-14h]
  int j; // [esp+28h] [ebp-10h]
  int i; // [esp+2Ch] [ebp-Ch]

  for ( i = 0; i < len_P; ++i )
    input[i] -= 64;
  for ( j = 0; j < len_P; ++j )
    input[j] -= input[j + 1];
  for ( k = 0; k < strlen(key); ++k )           // 密钥变形
    key[k] %= 64;
  for ( l = 0; l < len_P; ++l )
    input[l] += key[l % 7];
  for ( m = 0; len_P / 2 > m; ++m )             // 倒序排列
  {
    v5 = input[m];
    input[m] = input[len_P - m - 1];
    input[len_P - m - 1] = v5;
  }
  for ( n = 0; ; ++n )                          // 循环a3次
  {
    result = n;
    if ( n >= len_P )
      break;
    if ( (key[n % 7] & 1) != 0 )
      v3 = input[n] + 2;
    else
      v3 = input[n] + 1;
    input[n] = v3;
  }
  return result;
}

自下而上,写脚本

 第一步要使用到密钥,所以先对密钥进行变形

ISCC{REVERSE_IS_NOT_HARD}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值