美文网首页
2019年7月23日做题笔记(CyBRICS的一道逆向题Matr

2019年7月23日做题笔记(CyBRICS的一道逆向题Matr

作者: Ginkgo_Alkaid | 来源:发表于2019-07-23 16:29 被阅读0次
题目

前些日子打了CyBRICS CTF国际赛,被虐哭。写篇笔记,记录下一些题目,这道Matreshka考察了java,go,python的基本逆向知识,涉及简单的加密算法,难度不是很大,首先是题目给了一个Code2.class文件和一个data.bin文件,可以直接将class反编译成java源码,看下代码逻辑:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;

class Code2
{
  Code2() {}
  
  public static byte[] decode(byte[] paramArrayOfByte, String paramString) throws Exception
  {
    SecretKeyFactory localSecretKeyFactory = SecretKeyFactory.getInstance("DES");
    byte[] arrayOfByte1 = paramString.getBytes();
    javax.crypto.spec.DESKeySpec localDESKeySpec = new javax.crypto.spec.DESKeySpec(arrayOfByte1);
    javax.crypto.SecretKey localSecretKey = localSecretKeyFactory.generateSecret(localDESKeySpec);
    Cipher localCipher = Cipher.getInstance("DES");
    localCipher.init(2, localSecretKey);
    byte[] arrayOfByte2 = localCipher.doFinal(paramArrayOfByte);
    return arrayOfByte2;
  }
  
  public static byte[] encode(byte[] paramArrayOfByte, String paramString) throws Exception { SecretKeyFactory localSecretKeyFactory = SecretKeyFactory.getInstance("DES");
    byte[] arrayOfByte1 = paramString.getBytes();
    javax.crypto.spec.DESKeySpec localDESKeySpec = new javax.crypto.spec.DESKeySpec(arrayOfByte1);
    javax.crypto.SecretKey localSecretKey = localSecretKeyFactory.generateSecret(localDESKeySpec);
    Cipher localCipher = Cipher.getInstance("DES");
    localCipher.init(1, localSecretKey);
    byte[] arrayOfByte2 = localCipher.doFinal(paramArrayOfByte);
    return arrayOfByte2;
  }
  
  public static void main(String[] paramArrayOfString) throws Exception {
    String str = "matreha!";
    byte[] arrayOfByte1 = encode(System.getProperty("user.name").getBytes(), str);
    byte[] arrayOfByte2 = { 76, -99, 37, 75, -68, 10, -52, 10, -5, 9, 92, 1, 99, -94, 105, -18 };
    for (int i = 0; i < arrayOfByte2.length; i++) {
      if (arrayOfByte2[i] != arrayOfByte1[i]) {
        System.out.println("No");
        return;
      }
    }
    java.io.File localFile = new java.io.File("data.bin");
    FileInputStream localFileInputStream = new FileInputStream(localFile);
    byte[] arrayOfByte3 = new byte[(int)localFile.length()];
    localFileInputStream.read(arrayOfByte3);
    localFileInputStream.close();
    byte[] arrayOfByte4 = decode(arrayOfByte3, System.getProperty("user.name"));
    FileOutputStream localFileOutputStream = new FileOutputStream("stage2.bin");
    localFileOutputStream.write(arrayOfByte4, 0, arrayOfByte4.length);
    localFileOutputStream.flush();
    localFileOutputStream.close();
  }
}

可以看出这段用了DES算法对字符串进行encode,密钥key为matreha!,如果和结果和byte[] arrayOfByte2 = { 76, -99, 37, 75, -68, 10, -52, 10, -5, 9, 92, 1, 99, -94, 105, -18 };相同则继续将bin文件使用这段字符串进行decode操作,保存成stage2.bin文件,所以我们需要知道这段字符串的真正内容,只需要使用密钥matreha!直接decode这段byte[] arrayOfByte2 = { 76, -99, 37, 75, -68, 10, -52, 10, -5, 9, 92, 1, 99, -94, 105, -18 };即可。
完整代码如下所示:

package test;
import java.io.UnsupportedEncodingException;
import java.util.*;
import java.util.Base64.Encoder;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;

public class Code2
{
  Code2() {}
  
  public static byte[] decode(byte[] paramArrayOfByte, String paramString) throws Exception
  {
    SecretKeyFactory localSecretKeyFactory = SecretKeyFactory.getInstance("DES");
    byte[] arrayOfByte1 = paramString.getBytes();
    javax.crypto.spec.DESKeySpec localDESKeySpec = new javax.crypto.spec.DESKeySpec(arrayOfByte1);
    javax.crypto.SecretKey localSecretKey = localSecretKeyFactory.generateSecret(localDESKeySpec);
    Cipher localCipher = Cipher.getInstance("DES");
    localCipher.init(2, localSecretKey);
    byte[] arrayOfByte2 = localCipher.doFinal(paramArrayOfByte);
    return arrayOfByte2;
  }
  
  public static byte[] encode(byte[] paramArrayOfByte, String paramString) throws Exception { SecretKeyFactory localSecretKeyFactory = SecretKeyFactory.getInstance("DES");
    byte[] arrayOfByte1 = paramString.getBytes();
    javax.crypto.spec.DESKeySpec localDESKeySpec = new javax.crypto.spec.DESKeySpec(arrayOfByte1);
    javax.crypto.SecretKey localSecretKey = localSecretKeyFactory.generateSecret(localDESKeySpec);
    Cipher localCipher = Cipher.getInstance("DES");
    localCipher.init(1, localSecretKey);
    byte[] arrayOfByte2 = localCipher.doFinal(paramArrayOfByte);
    return arrayOfByte2;
  }
  
  public static void main(String[] paramArrayOfString) throws Exception {
    String str = "matreha!";
    byte[] arrayOfByte1 = encode("lettreha".getBytes(), str);
    byte[] arrayOfByte2 = { 76, -99, 37, 75, -68, 10, -52, 10, -5, 9, 92, 1, 99, -94, 105, -18 };
    byte[] arrayOfByte7 = decode(arrayOfByte2, str);
    String s = new String(arrayOfByte7);
    for (int i = 0; i < arrayOfByte2.length; i++) {
      if (arrayOfByte2[i] == arrayOfByte1[i]) {
        System.out.println(s);
        return;
      }
    }
    java.io.File localFile = new java.io.File("data.bin");
    FileInputStream localFileInputStream = new FileInputStream(localFile);
    byte[] arrayOfByte3 = new byte[(int)localFile.length()];
    localFileInputStream.read(arrayOfByte3);
    localFileInputStream.close();
    byte[] arrayOfByte4 = decode(arrayOfByte3, "lettreha");
    FileOutputStream localFileOutputStream = new FileOutputStream("stage2.bin");
    localFileOutputStream.write(arrayOfByte4, 0, arrayOfByte4.length);
    localFileOutputStream.flush();
    localFileOutputStream.close();
  }
}

可以得出真正的密钥为lettreha,替换掉System.getProperty("user.name"),可以得到stage2.bin,根据文件头可以看出是一个elf可执行文件,直接扔入IDA,分析一下就可以找到关键跳转:


IDA

将这第一个跳转改为jnz,第二个跳转改为jmp就可以直接进入写入文件,可以得到第三个文件,是一个pyc文件,需要反编译出py源码,我用的是uncompyle6.exe:

# uncompyle6 version 3.2.4
# Python bytecode 3.7 (3394)
# Decompiled from: Python 3.6.2 (v3.6.2:5fd33b5, Jul  8 2017, 04:14:34) [MSC v.1900 32 bit (Intel)]
# Embedded file name: ./1.py
# Size of source mod 2**32: 439 bytes
def decode(data, key):
    idx = 0
    res = []
    for c in data:
        res.append(chr(c ^ ord(key[idx])))
        idx = (idx + 1) % len(key)

    return res

flag = [
 40, 11, 82, 58, 93, 82, 64, 76, 6, 70, 100, 26, 7, 4, 123, 124, 127, 45, 1, 125, 107, 115, 0, 2, 31, 15]
print('Enter key to get flag:')
key = input()
if len(key) != 8:
    print('Invalid len')
    quit()
res = decode(flag, key)
print(''.join(res))
# okay decompiling result.pyc

可以看出是一个简单的按位异或加密,可以根据flag的开头是cybrics{来轻易得到密钥,从而得到最终flag,解题脚本如下:

def decode(data, key):
    idx = 0
    res = []
    for c in data:
        res.append(chr(c ^ ord(key[idx])))
        idx = (idx + 1) % len(key)
    return res

flag = [40, 11, 82, 58, 93, 82, 64, 76, 6, 70, 100, 26, 7, 4, 123, 124, 127, 45, 1, 125, 107, 115, 0, 2, 31, 15]

key=''
a="cybrics{"
for i in range(8):
    key+=chr(flag[i]^ord(a[i]))
print key

res = decode(flag, key)
print(''.join(res))

最后得到flag为:


flag

相关文章

  • 2019年7月23日做题笔记(CyBRICS的一道逆向题Matr

    前些日子打了CyBRICS CTF国际赛,被虐哭。写篇笔记,记录下一些题目,这道Matreshka考察了java,...

  • 2019年7月8日做题笔记(安恒6月月赛简单迷宫)

    这是一道2019年安恒6月月赛的逆向题目,是一道简单的迷宫题,之前没有详细的做题的过程,现在补上,题目地址:htt...

  • 准备考试最好的方法就是做题。

    准备考试最好的方法就是做题。 只不过,不要被动做题,每道题都要认真,每道题,都肯定对应着某个学习难点,一道题做错了...

  • CyBRICS CTF 的一道baby密码题 Zakukozh

    题目如下所示,考点是仿射密码: 下面是对仿射密码的一个简介,仿射密码对相同字母加密后的结果是一样的,这是一个入手点...

  • 数学考试

    这次数学考试没有考好,爸爸让我找原因。首先,做题不仔细,没有好好读题,做题很马虎,很简单的一道题都做错。...

  • DES

    2017年SWPU的一道逆向题,先前很少接触逆向里的密码算法题,ida f5反编译的结果一开始也觉得无从下手不知道...

  • 复习研究课:张楠《修改病句》

    一、病句类型及修改办法 删 二、拿出练习纸做题训练。 展示 一道题一道题地交流! 我是这样修改的,因为:…… 有没...

  • CyBRICS-CTF 2020

    Cybrics比赛感觉都没队友在打......简单记录下做的几道题 Hunt 签到不谈。 Gif2png 首先是源...

  • WpsecCTF Crypto部分

    1 水流滴滴答 2.丧心病狂的APL 这题原题是来自于plaidctf2018的一道最简单的逆向题,但是要理解起来...

  • 【学科状元谈学法】语文之道

    (一)做题 一,认真审题。 审题时首先把题眼画出来。题眼其实就是这道题问什么。我在预习课本内容中碰见了这样一道题,...

网友评论

      本文标题:2019年7月23日做题笔记(CyBRICS的一道逆向题Matr

      本文链接:https://www.haomeiwen.com/subject/okhalctx.html