XCTF_MOBILE15_人民的名义-抓捕赵德汉1-200

初见

题目附件为一个jar文件。

提示信息为:flag{xxxxxx},这是flag格式的提示。

直接运行jar:

提示输入password。

输入错误显示“Incorrect password”,并要求再次输入:

XCTF_MOBILE15_人民的名义-抓捕赵德汉1-200_第1张图片

从运行情况看,重点在password的验证上。

下面静态分析一下jar文件。

静态分析

使用jd-gui打开jar文件,看见里面有6个文件:

XCTF_MOBILE15_人民的名义-抓捕赵德汉1-200_第2张图片

三个后缀名为class的为类文件。

简单看一下三个类文件,可以发现,checkPassword类基础自ClassLoader,并实现了main方法。也就是这个jar文件的入口函数。

main方法

main方法主要做两件事:

  1. 创建checkerObject对象。
  2. 在一个循环中使用checkerObject.checkPassword方法检测用户输入

main方法里,提示用户输入、提示输入错误的字符串,和运行时看到的一致:

    CheckInterface checkerObject = loadCheckerObject();
    BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
    while (true) {
      System.out.println("Enter password:");
      String line = stdin.readLine();
      if (checkerObject.checkPassword(line)) {
        System.out.println("Well done, that is the correct password");
        System.exit(0);
        continue;
      } 
      System.out.println("Incorrect password");
    }

现在要重点搞清楚checkerObject的checkPassword方法如何检测用户的输入。

checkPassword方法

直接在jd-gui点击checkPassword方法名,会定位到CheckInterface类:

public interface CheckInterface {
  boolean checkPassword(String paramString);
}

可见,CheckInterface类是一个接口,里面包含一个方法checkPassword。

那么谁实现了这个接口呢,我第一反应想到了CheckPassword和CheckInterface之外的第三个类newClassName:

public class CheckPass implements CheckInterface {
  public boolean checkPassword(String input) {
    MessageDigest md5Obj = null;
    try {
      md5Obj = MessageDigest.getInstance("MD5");
    } catch (NoSuchAlgorithmException e) {
      System.out.println("Hash Algorithm not supported");
      System.exit(-1);
    } 
    byte[] hashBytes = new byte[40];
    md5Obj.update(input.getBytes(), 0, input.length());
    hashBytes = md5Obj.digest();
    return byteArrayToHexString(hashBytes).equals("fa3733c647dca53a66cf8df953c2d539");
  }
  
  ... ...
}

可见这个类实现了CheckInterface接口,并且有checkPassword方法。

这个checkPassword方法也很简单,就是对输入的字符串计算MD5,比较MD5值是否为"fa3733c647dca53a66cf8df953c2d539"。到MD5破解网站上可以直接得到明文:

XCTF_MOBILE15_人民的名义-抓捕赵德汉1-200_第3张图片

 将monkey99提交给jar程序,显示验证通过:

XCTF_MOBILE15_人民的名义-抓捕赵德汉1-200_第4张图片

提交flag为:flag{monkey99},题目验证通过。

看上去题目已经做完了,但真的如此嘛?

事实并不这样简单

在CheckPassword类的main方法中可以看到,checkerObject对象来自于loadCheckerObject函数的返回值。看看loadCheckerObject函数的反编译代码,发现checkerObject对象其实和newClassName没有关系,而是来自对ClassEnc文件的解密:

  private static CheckInterface loadCheckerObject() {
    CheckPassword mycl = new CheckPassword();
    InputStream in = CheckPassword.class.getClass().getResourceAsStream("/ClassEnc");
    ByteArrayOutputStream bout = new ByteArrayOutputStream();
    int len = 0;
    byte[] bytes = new byte[512];
    while ((len = in.read(bytes)) > -1)
      bout.write(bytes, 0, len); 
    byte[] myClassBytesEnc = bout.toByteArray();
    in.close();
    SecretKeySpec secretKeySpec = new SecretKeySpec(hexStringToByteArray(hexKey), "AES");
    Cipher decAEScipher = Cipher.getInstance("AES");
    decAEScipher.init(2, secretKeySpec);
    byte[] myClassBytes = decAEScipher.doFinal(myClassBytesEnc);
    Class myclass = (Class)mycl.defineClass(null, myClassBytes, 0, myClassBytes.length);
    CheckInterface passCheckObject = myclass.newInstance();
    return passCheckObject;
  }

这个函数其实就是以hexKey为秘钥,用AES算法对ClassEnc文件进行解密,并用解密后的内容创建一个新类,最后创建一个这个新类的对象并返回。

可见,checkerObject对象其实是这里解密后的类的对象,而不是newClassName类的对象,之前我们仅根据newClassName类实现了CheckInterface接口,假设这两者有关系,虽然成功解题了,却只是歪打正着。

将jar文件的后缀名修改为zip,解压后,即可得到ClassEnc文件。使用下面的python脚本即可对ClassEnc文件进行解密:

import os
from Crypto.Cipher import AES
filename="ClassEnc"
key = "bb27630cf264f8567d185008c10c3f96"
key_bytes = bytes.fromhex(key)
aes = AES.new((key_bytes), AES.MODE_ECB)
data = bytearray(os.path.getsize(filename))    
with open(filename, 'rb') as f:        
	f.readinto(data)    
	f.close()    
decryption_data = aes.decrypt(data)
with open(filename+"_decryption", 'ba') as f:
    f.write(decryption_data)
f.close()

运行该脚本后,解密ClassEnc文件,并将解密后内容保存在ClassEnc_decryption文件中。

有趣的是,这里解密后的ClassEnc_decryption文件和jar包里自带的newClassName.class文件是完全一致的。难怪按照newClassName.class类也可以解出题目。

这里不知是题目作者故意留下newClassName.class文件还是忘了删除newClassName.class文件。

你可能感兴趣的:(CTF,android,逆向,ctf)