转载自:http://l-team.org/archives/lctf2016_wp_1.html
这一题的确是个福利题...并没有涉及到dex函数隐藏等小技巧,只是简单的使用proguard进行了混淆。可以静态也可动态(动态先改掉debug检测,还不如直接静态看一下),那么,关键部分源码:
private void getKey(){
try {
InputStream stream = this.getResources().getAssets().open("url.png");
int v = stream.available();
byte[] bs = new byte[v];
stream.read(bs, 0, v);
byte[] keybyte = new byte[16];
System.arraycopy(bs, 144, keybyte, 0, 16);
this.key = new String(keybyte, "utf-8");
}
catch (Exception e){
e.printStackTrace();
}
//code
}
private String handle(String naive){
try {
naive.getBytes("utf-8");
StringBuilder str = new StringBuilder();
for (int i = 0; i < naive.length(); i += 2) {
str.append(naive.charAt(i + 1));
str.append(naive.charAt(i));
}
return str.toString();
}catch (UnsupportedEncodingException e){
e.printStackTrace();
}
return null;
}
protected void Encryption(byte[] key){
try {
if (key == null) {
byte[] bytes = "".getBytes("utf-8");
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
byte[] bytes1 = messageDigest.digest(bytes);
secretKeySpec = new SecretKeySpec(bytes1, "AES");
cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
}
else {
secretKeySpec = new SecretKeySpec(key, "AES");
cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
}
}except{
//...
}
}
从url.png中获得key,然后使用handle函数进行处理(奇偶位互换)作为最终AES加密的key。flag密文:
byte[] bye = {21,-93,-68,-94,86,117,-19,-68,-92,33,50,118,16,13,1,-15,-13,3,4,103,-18,81,30,68,54,-93,44,-23,93,98,5,59};
new String(bye);
使用AES/ECB/PKCS5Padding,用key对选手输入进行加密,结果与flag密文进行比对;故解密时只需
init(Cipher.DECRYPT_MODE, secretKeySpec);
对flag密文进行解密即可。
flag:LCTF{1t's_rea1ly_an_ea3y_ap4}