2014 ASIS Cyber Security Contest Finals Numdroid
首先利用 file 命令判断一下文件类型,发现是个压缩包,解压缩一下,得到对应的文件,然后继续看一下,发现该文件是 apk 文件。
安装一下程序。简单看一下页面,可以发现程序主要是输入0-9数字密码,然后登陆。如果输入错的话会爆出 “Wrong Password” 的信息。
1、根据相应的字符串来定位一下源程序中的关键函数。根据 strings.xml 可以发现该字符串的变量名为 wrong,继而我们找到了如下代码。
2、也可以直接切入入口函数OnCreate函数进行流程分析。
protected void ok_clicked() { DebugTools.log("clicked password: " + this.mScreen.getText()); boolean result = Verify.isOk(this, this.mScreen.getText().toString()); DebugTools.log("password is Ok? : " + result); if (result) { Intent i = new Intent(this, LipSum.class); Bundle b = new Bundle(); b.putString("flag", this.mScreen.getText().toString().substring(0, 7)); i.putExtras(b); startActivity(i); return; } Toast.makeText(this, R.string.wrong, 1).show(); this.mScreen.setText(""); }
继续定位到 Verify.isOk 中。如下
public static boolean isOk(Context c, String _password) { String password = _password; if (_password.length() > 7) { password = _password.substring(0, 7); } String r = OneWayFunction(password); DebugTools.log("digest: " + password + " => " + r); if (r.equals("be790d865f2cea9645b3f79c0342df7e")) { return true; } return false; }
可以发现程序主要是取 password 的前 7 位进行 OneWayFunction 加密,然后与 be790d865f2cea9645b3f79c0342df7e 进行比较。如果相等就会返回 true。这里我们再看一下 OneWayFunction,如下
private static String OneWayFunction(String password) { List<byte[]> bytes = ArrayTools.map(ArrayTools.select(ArrayTools.map(new String[]{"MD2", "MD5", "SHA-1", "SHA-256", "SHA-384", "SHA-512"}, new AnonymousClass1(password)), new SelectAction<byte[]>() { public boolean action(byte[] element) { return element != null; } }), new MapAction<byte[], byte[]>() { public byte[] action(byte[] element) { int i; byte[] b = new byte[8]; for (i = 0; i < b.length / 2; i++) { b[i] = element[i]; } for (i = 0; i < b.length / 2; i++) { b[(b.length / 2) + i] = element[(element.length - i) - 2]; } return b; } }); byte[] b2 = new byte[(bytes.size() * 8)]; for (int i = 0; i < b2.length; i++) { b2[i] = ((byte[]) bytes.get(i % bytes.size()))[i / bytes.size()]; } try { MessageDigest digest = MessageDigest.getInstance("MD5"); digest.update(b2); byte[] messageDigest = digest.digest(); StringBuilder hexString = new StringBuilder(); for (byte aMessageDigest : messageDigest) { String h = Integer.toHexString(aMessageDigest & MotionEventCompat.ACTION_MASK); while (h.length() < 2) { h = "0" + h; } hexString.append(h); } return hexString.toString(); } catch (NoSuchAlgorithmException e) { return ""; // 注意这里,如果算法不存在的话,应该是会返回空字符串 } }
函数大概就是执行了几个hash函数,由于Hash函数是不可逆的,因此这道题的唯一解法必然是爆破,这是很明显的一道爆破题。
由于代码中没有过度混淆且逻辑比较清晰,以及Hash算法并非自定义算法,涉及到的主要流程比较少,因此我们可以直接把Verify类抠出来直接跑。
提取出 java 程序之后,在 Verify 类中添加 main 函数并修复部分错误,从而得到对应的答案。
输入之后得到如下
然后我们计算对应的 MD 值,从而获得 flag 为 ASIS_{3c56e1ed0597056fef0006c6d1c52463}
CTFWILIKI