BUGKU-逆向(reverse)-writeup (5)

如果a()方法返回真,则输出flag。第一个参数为句柄,第二个参数调用了另外一个a方法返回一个字符串,第三个参数是我们输入的字符串。
跟过去看下a()方法,发现为重载(JAVA重载概念)

static String a(MainActivity arg1) { return arg1.v; } static boolean a(MainActivity arg1, String arg2, String arg3) { return arg1.a(arg2, arg3); } private boolean a(String arg4, String arg5) { return new c().a(arg4, arg5).equals(new String(new byte[]{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})); }

static String a(MainActivity arg1)方法直接返回了字符串,返回的是arg1.v

private boolean a(String arg4, String arg5)方法中调用了equals方法进行比较返回布尔值。

由于arg4是类d中传入的MainActivity.a(this.a),所以得先看返回了什么字符串v,而v是MainActivity的String类型的数据成员以及有相应的方法进行赋值p方法。

private void p() { try { InputStream v0_1 = this.getResources().getAssets().open("url.png"); int v1 = v0_1.available(); byte[] v2 = new byte[v1]; v0_1.read(v2, 0, v1); byte[] v0_2 = new byte[16]; System.arraycopy(v2, 144, v0_2, 0, 16); this.v = new String(v0_2, "utf-8"); } catch(Exception v0) { v0.printStackTrace(); } }

首先读取url.png文件以二进制数据取出来。从文件的144位置开始,读取16字符保存为v。

用winhex打开这张文件,找到144位置,往后的16位为this_is_the_key.

BUGKU-逆向(reverse)-writeup

得到了key后,要看回三参数的a方法

static boolean a(MainActivity arg1, String arg2, String arg3) { return arg1.a(arg2, arg3); } private boolean a(String arg4, String arg5) { return new c().a(arg4, arg5).equals(new String(new byte[]{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})); }

发现三参数a方法调用了两参数a方法,将this_is_the_key. 与用户输入作为参数传了进去。.而两参数a方法是调用类c的两参数a方法.计算完后和后面的字节比较。相等返回真。跟过去看下类c的两参数a方法

public String a(String arg5, String arg6) { String v0 = this.a(arg5); String v1 = ""; a v2 = new a(); v2.a(v0.getBytes()); try { v0 = new String(v2.b(arg6.getBytes()), "utf-8"); } catch(Exception v0_1) { v0_1.printStackTrace(); v0 = v1; } return v0; }

首先将this_is_the_key.传入一个参数a方法,然后将返回值赋值给v0。看下一个参数a方法。

private String a(String arg4) { String v0_2; try { arg4.getBytes("utf-8"); StringBuilder v1 = new StringBuilder(); int v0_1; for(v0_1 = 0; v0_1 < arg4.length(); v0_1 += 2) { v1.append(arg4.charAt(v0_1 + 1)); v1.append(arg4.charAt(v0_1)); } v0_2 = v1.toString(); } catch(UnsupportedEncodingException v0) { v0.printStackTrace(); v0_2 = null; } return v0_2; }

将传入的字符串每两个字符为一组然后交换这两个字符的位置最后返回改变后的字符串。就是变成htsii__sht_eek.y,可以手动也可以写脚本。

#!usr/bin/env python #!coding=utf-8 __author__ = 'zhengjim' key = 'this_is_the_key.' ckey ="" for i in range(0,len(key),2): ckey += key[i+1] ckey += key[i] print(ckey)

回到类c的两参数a方法,实例化的了类a,然后将用户输入作为参数带入。跟过去看看。

package com.example.ring.myapplication; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import javax.crypto.Cipher; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.SecretKeySpec; public class a { private SecretKeySpec a; private Cipher b; public a() { super(); } protected void a(byte[] arg4) { if(arg4 != null) { goto label_15; } try { this.a = new SecretKeySpec(MessageDigest.getInstance("MD5").digest("".getBytes("utf-8")), "AES"); this.b = Cipher.getInstance("AES/ECB/PKCS5Padding"); return; label_15: this.a = new SecretKeySpec(arg4, "AES"); this.b = Cipher.getInstance("AES/ECB/PKCS5Padding"); } catch(UnsupportedEncodingException v0) { v0.printStackTrace(); } catch(NoSuchAlgorithmException v0_1) { v0_1.printStackTrace(); } catch(NoSuchPaddingException v0_2) { v0_2.printStackTrace(); } } protected byte[] b(byte[] arg4) { this.b.init(1, this.a); return this.b.doFinal(arg4); } }

发现是用AES加密,ECB模式,PKCS5Padding填充。然后要找下密钥。this.a = new SecretKeySpec(arg4, "AES");是将arg4作为密钥。而arg4则是在类c中传入的v0.getBytes(),也就是密钥为htsii__sht_eek.y。

回到类c的两参数a方法,将返回的字符串赋值给v0然后再返回。到了MainActivity的两参数a方法,与那串字符串比较。正确则返回真,就出现Congratulations!。
所以百度了一个AES解密网站。由于网站输出的是base64。所以讲密文转为base64格式。

#!usr/bin/env python #!coding=utf-8 __author__ = 'zhengjim' import base64 str1 = [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] ctext = '' for i in str1: ctext += chr((i+256)%256) a = base64.b64encode(ctext) print(a)

得到了密文为FaO8olZ17bykITJ2EA0B8fMDBGfuUR5ENqMs6V1iBTs=,密钥为htsii__sht_eek.y,AES解密后出现flag。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpfypp.html