bugku安卓部分题解

bugku安卓部分题解


一、signin

1、首先将APK放进模拟器中运行,查看其报错关键字“Try again”,为后面做关键词定位做准备

2、利用APKIDE加载APK并进行反汇编

3、搜索“Try again”定位到Mainactivity.class利用jd查看其java源码(如果smali基础较好可以直接看smali代码)

   源码:

    public class MainActivity
  extends AppCompatActivity
{
  private String getFlag()
  {
return getBaseContext().getString(2131427360);
  }
  
  private void showMsgToast(String paramString)
  {
Toast.makeText(this, paramString, 1).show();
  }
  
  public void checkPassword(String paramString)
  {
if (paramString.equals(new String(Base64.decode(new StringBuffer(getFlag()).reverse().toString(), 0)))) {
  showMsgToast("Congratulations !");
} else {
  showMsgToast("Try again.");
}
  }
  
  protected void onCreate(Bundle paramBundle)
  {
super.onCreate(paramBundle);
setContentView(2131296283);
((Button)findViewById(2131165261)).setOnClickListener(new View.OnClickListener()
{
  public void onClick(View paramAnonymousView)
  {
paramAnonymousView = ((EditText)MainActivity.this.findViewById(2131165253)).getText().toString();
MainActivity.this.checkPassword(paramAnonymousView);
  }
});
  }
}

4、对getflag()方法中调用的ID进行逐级搜索查看到其加密字符串:

991YiZWOz81ZhFjZfJXdwk3X1k2XzIXZIt3ZhxmZ

5、在checkPassword()方法中对该字符串进行了解密即可的flag,以下为解密步骤

reverse()  ---->   Base64.decode
对字符串进行反转 ---->  对反转后的字符串进行base64解密

二、mobile1(gctf)

1、利用模拟器安装该APK发现界面与signin相似,直接利用androidkiller打开并反编译

2、查看Mainactivity.class文件,并利用jd打开

   部分关键源码:

   onCreate方法:

public void onCreate(Bundle paramBundle)
  {
super.onCreate(paramBundle);
setContentView(2130968601);
setTitle(2131099677);
this.edit_userName = "Tenshine";
this.edit_sn = ((EditText)findViewById(2131492945));
this.btn_register = ((Button)findViewById(2131492946));
this.btn_register.setOnClickListener(new View.OnClickListener()
{
  public void onClick(View paramAnonymousView)
  {
if (!MainActivity.this.checkSN(MainActivity.this.edit_userName.trim(), MainActivity.this.edit_sn.getText().toString().trim()))
{
  Toast.makeText(MainActivity.this, 2131099678, 0).show();
  return;
}
Toast.makeText(MainActivity.this, 2131099675, 0).show();
MainActivity.this.btn_register.setEnabled(false);
MainActivity.this.setTitle(2131099673);
  }
});
  }

   checkSN方法:

private boolean checkSN(String paramString1, String paramString2)
  {
if (paramString1 != null) {
  try
  {
if (paramString1.length() == 0) {
  return false;
}
if ((paramString2 != null) && (paramString2.length() == 22))
{
  Object localObject = MessageDigest.getInstance("MD5");
  ((MessageDigest)localObject).reset();
  ((MessageDigest)localObject).update(paramString1.getBytes());
  paramString1 = toHexString(((MessageDigest)localObject).digest(), "");
  localObject = new StringBuilder();
  int i = 0;
  while (i < paramString1.length())
  {
((StringBuilder)localObject).append(paramString1.charAt(i));
i += 2;
  }
  paramString1 = ((StringBuilder)localObject).toString();
  boolean bool = ("flag{" + paramString1 + "}").equalsIgnoreCase(paramString2);
  if (bool) {
return true;
  }
}
  }
  catch (NoSuchAlgorithmException paramString1)
  {
paramString1.printStackTrace();
  }
}
return false;
  }

3、可见在oncreate中调用了checkSN并传递两个值(‘Tenshine’和前台输入的flag)

4、在checkSN中首先对‘Tenshine’进行了MD5加密,之后截取其偶数位的字母;将截取的字母加上flag{}恰为22个字母,与我们输入falg在验证中长度必须为22相互验证。由此可以解除flag


三、mobile2(gctf)

flag在Mainactivity.xml里(脑洞题,不解释)


四、First_Mobile(xman)

1、利用Androidkiller对apk进行反编译利用jd查看其源文件定位到Mainactivity:

protected void onCreate(final Bundle paramBundle)
  {
super.onCreate(paramBundle);
setContentView(2130968602);
paramBundle = (EditText)findViewById(2131427413);
((Button)findViewById(2131427414)).setOnClickListener(new View.OnClickListener()
{
  public void onClick(View paramAnonymousView)
  {
new encode();
if (encode.check(paramBundle.getText().toString()))
{
  Toast.makeText(MainActivity.this.getApplicationContext(), "correct", 1).show();
  return;
}
Toast.makeText(MainActivity.this.getApplicationContext(), "failed", 1).show();
  }
});
  }
}

2、发现其调用了encode()方法,点击查看:

public class encode
{
  private static byte[] b = { 23, 22, 26, 26, 25, 25, 25, 26, 27, 28, 30, 30, 29, 30, 32, 32 };
  
  public static boolean check(String paramString)
  {
byte[] arrayOfByte1 = paramString.getBytes();
byte[] arrayOfByte2 = new byte[16];
int i = 0;
while (i < 16)
{
  arrayOfByte2[i] = ((byte)((arrayOfByte1[i] + b[i]) % 61));
  i += 1;
}
i = 0;
while (i < 16)
{
  arrayOfByte2[i] = ((byte)(arrayOfByte2[i] * 2 - i));
  i += 1;
}
return new String(arrayOfByte2).equals(paramString);
  }
}

以上为它对flag的加密算法,我们反向求解的运算法则:a[i]=122*n - 2b[i] +i (a[i]:flag对应的数列 n:任意值)对以上求解即可得到flag


五、HelloSmali2

1、本体通过对XMan.java进行分析,源码:

public class XMan {
public static void main(String[] args) {
String v6 = "+/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
String s = "xsZDluYYreJDyrpDpucZCo";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
int tmp = v6.indexOf(s.charAt(i));
String ss = Integer.toBinaryString(tmp);
if (ss.length() == 5) {
ss = "0" + ss;
} else if (ss.length() == 4) {
ss = "00" + ss;
} else if (ss.length() == 3) {
ss = "000" + ss;
} else if (ss.length() == 2) {
ss = "0000" + ss;
} else if (ss.length() == 1) {
ss = "00000" + ss;
} else if (ss.length() == 0) {
ss = "000000" + ss;
}
sb.append(ss);
}
String x = sb.toString() + "0000";
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < x.length(); i += 8) {
String tmp = x.substring(i, i + 8);
byte b = (byte) Integer.parseInt(tmp, 2);
stringBuilder.append((char) b);
}
System.out.println(stringBuilder.toString());


}
}

2、通过对源码的分析其算法思路是:查找字符串s在v6中对应的位置–>计算该数的二进制并补足6位–>按顺序连接所有二进制并在最后补0使其为8的倍数–>按每8位截取并转化为字符串即可解得

3、从上述代码可以发现它好像是base64解密,找到base64解密源码然后调用它解密

4、更简单的方法:既然已经给了java文件,为什么不直接用他写好的算法呢–>编译一下然后运行


fake-func

emmm本题分析了半天结果还是基础知识不扎实啊,直接上大神的WP链接:https://www.52pojie.cn/thread-820158-1-1.html

1、将APK反编译后发现调用了checkflag()方法,该方法存在于libcheckso.so文件中

2、利用IDA查看该方法并查看Java_com_example_p7xxtmx_1g_fakefunc_check_checkflag()方法——然后分析了半天。。。。接下来蒙蔽

3、看了大神的WP后get到新姿势(当对方法分析发现没有什么异常的时候,可以对JNI_OnLoad或者.init_array进行检查,一般会在这里面增加一些跳转代码来隐藏真正的函数)

4、在.init_array中进行了跳转到sub_E28,在这个函数里又调用了sub_E08,分析后得出这里进行了一个base64解密

5、在sub_E28里又有一个想base64但又不是base64加密的字符串

4、然后就是对后面的函数中的跳转进行查看,没用反回对下一个跳转继续查看。。。

5、当跳转到sub_F24就是我们所要的关键之一(利用findcrypt3能够查看加密算法)byte_4255-对应-RijnDael_AES_LONG_4255所以判断为AES加密

6、然后上网对前面的两个字符串试一下。得出了flag


MagicImageViewer

本题的WP与上一题同出一处,因为不会不敢写。。。等以后回头再来做一做


rev1(xman)

emmm直接编译运行了一下Xman.java然后就是flag了。。。

你可能感兴趣的:(CTF-RE,Android逆向学习)