前期工作

查壳无壳

逆向分析

文件结构

MainActivity代码

  1. public class MainActivity extends c {
  2. static {
  3. System.loadLibrary("native");
  4. }
  5. /* access modifiers changed from: private */
  6. public boolean a(String str) {
  7. try {
  8. return ncheck(new a().a(str.getBytes()));
  9. } catch (Exception e) {
  10. return false;
  11. }
  12. }
  13. private native boolean ncheck(String str);
  14. /* access modifiers changed from: protected */
  15. public void onCreate(Bundle bundle) {
  16. super.onCreate(bundle);
  17. setContentView((int) R.layout.activity_main);
  18. findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
  19. public void onClick(View view) {
  20. if (MainActivity.this.a(((EditText) ((MainActivity) this).findViewById(R.id.edit)).getText().toString())) {
  21. Toast.makeText(this, "You are right!", 1).show();
  22. } else {
  23. Toast.makeText(this, "You are wrong! Bye~", 1).show();
  24. }
  25. }
  26. });
  27. }
  28. }

可以看到点击触发MainActivity的a方法,调用了a类的a方法对输入的字符串处理再对结果用native方法ncheck处理。

来看看a类的a方法

  1. public class a {
  2. private static final char[] a = {'i', '5', 'j', 'L', 'W', '7', 'S', '0', 'G', 'X', '6', 'u', 'f', '1', 'c', 'v', '3', 'n', 'y', '4', 'q', '8', 'e', 's', '2', 'Q', '+', 'b', 'd', 'k', 'Y', 'g', 'K', 'O', 'I', 'T', '/', 't', 'A', 'x', 'U', 'r', 'F', 'l', 'V', 'P', 'z', 'h', 'm', 'o', 'w', '9', 'B', 'H', 'C', 'M', 'D', 'p', 'E', 'a', 'J', 'R', 'Z', 'N'};
  3. public String a(byte[] bArr) {
  4. StringBuilder sb = new StringBuilder();
  5. for (int i = 0; i <= bArr.length - 1; i += 3) {
  6. byte[] bArr2 = new byte[4];
  7. byte b = 0;
  8. for (int i2 = 0; i2 <= 2; i2++) {
  9. if (i + i2 <= bArr.length - 1) {
  10. bArr2[i2] = (byte) (b | ((bArr[i + i2] & 255) >>> ((i2 * 2) + 2)));
  11. b = (byte) ((((bArr[i + i2] & 255) << (((2 - i2) * 2) + 2)) & 255) >>> 2);
  12. } else {
  13. bArr2[i2] = b;
  14. b = 64;
  15. }
  16. }
  17. bArr2[3] = b;
  18. for (int i3 = 0; i3 <= 3; i3++) {
  19. if (bArr2[i3] <= 63) {
  20. sb.append(a[bArr2[i3]]);
  21. } else {
  22. sb.append('=');
  23. }
  24. }
  25. }
  26. return sb.toString();
  27. }
  28. }

又是一个换表的Base64

使用IDA查看so层的ncheck方法,先看看字符串

在最下面看到了个可以的字符串,上面也看到了ncheck的方法名,跟进这个字符串

在IDA导入jni.h的过程中出了点问题,导入后还是无法显示JNI接口函数,参考了https://www.52pojie.cn/thread-503009-1-1.html中的方法解决

选中env变量,按一下“y”键,将_JNIEnv 改成JNIEnv*,即可解决

ncheck代码

第一个dowhile作用为将字符串前后两半互换。

第二个dowhile中__ OFSUB __ 功能是产生(v10-30)的溢出标志位,__ OFSUB __功能参考了

https://blog.csdn.net/youyou519/article/details/103782264

https://jingyan.baidu.com/article/5d6edee23100a3d8eadeecf0.html

因为正数减正数是不会溢出的,所以溢出标志位为0,v12为0。当v10大于或等于30时v11也为0,二者异或为0,所以第二个dowhile的条件其实相当于v10 <= 30。这个循环的功能为将字符串两两互换。

之后和MbT3sQgX039i3g==AQOoMQFPskB1Bsc7比较,相等则返回1。

脚本编写

  1. a = [
  2. 'i', '5', 'j', 'L', 'W', '7', 'S', '0', 'G', 'X', '6', 'u', 'f', '1', 'c',
  3. 'v', '3', 'n', 'y', '4', 'q', '8', 'e', 's', '2', 'Q', '+', 'b', 'd', 'k',
  4. 'Y', 'g', 'K', 'O', 'I', 'T', '/', 't', 'A', 'x', 'U', 'r', 'F', 'l', 'V',
  5. 'P', 'z', 'h', 'm', 'o', 'w', '9', 'B', 'H', 'C', 'M', 'D', 'p', 'E', 'a',
  6. 'J', 'R', 'Z', 'N'
  7. ]
  8. s = ''.join(a)
  9. def My_base64_decode(inputs):
  10. # 将字符串转化为2进制
  11. bin_str = []
  12. for i in inputs:
  13. if i != '=':
  14. x = str(bin(s.index(i))).replace('0b', '')
  15. bin_str.append('{:0>6}'.format(x))
  16. #print(bin_str)
  17. # 输出的字符串
  18. outputs = ""
  19. nums = inputs.count('=')
  20. while bin_str:
  21. temp_list = bin_str[:4]
  22. temp_str = "".join(temp_list)
  23. #print(temp_str)
  24. # 补足8位字节
  25. if (len(temp_str) % 8 != 0):
  26. temp_str = temp_str[0:-1 * nums * 2]
  27. # 将四个6字节的二进制转换为三个字符
  28. for i in range(0, int(len(temp_str) / 8)):
  29. outputs += chr(int(temp_str[i * 8:(i + 1) * 8], 2))
  30. bin_str = bin_str[4:]
  31. print("Decrypted String:\n%s " % outputs)
  32. raw = list('MbT3sQgX039i3g==AQOoMQFPskB1Bsc7')
  33. for i in range(0, len(raw), 2):
  34. raw[i], raw[i + 1] = raw[i + 1], raw[i]
  35. raw[:16], raw[16:] = raw[16:], raw[:16]
  36. My_base64_decode(''.join(raw))

flag

flag{just_ANot#er_@p3}

XCTF-easyjni的更多相关文章

  1. 攻防世界(XCTF)WEB(进阶区)write up(四)

    ics-07  Web_php_include  Zhuanxv Web_python_template_injection ics-07 题前半部分是php弱类型 这段说当传入的id值浮点值不能为1 ...

  2. 攻防世界(XCTF)WEB(进阶区)write up(三)

    挑着做一些好玩的ctf题 FlatScience web2 unserialize3upload1wtf.sh-150ics-04web i-got-id-200 FlatScience 扫出来的lo ...

  3. 攻防世界(XCTF)WEB(进阶区)write up(一)

      cat ics-05 ics-06 lottery Cat XCTF 4th-WHCTF-2017 输入域名  输入普通域名无果  输入127.0.0.1返回了ping码的结果 有可能是命令执行 ...

  4. XCTF攻防世界Web之WriteUp

    XCTF攻防世界Web之WriteUp 0x00 准备 [内容] 在xctf官网注册账号,即可食用. [目录] 目录 0x01 view-source2 0x02 get post3 0x03 rob ...

  5. xctf进阶-unserialize3反序列化

    一道反序列化题: 打开后给出了一个php类,我们可以控制code值: `unserialize()` 会检查是否存在一个 `__wakeup()` 方法.如果存在,则会先调用 `__wakeup` 方 ...

  6. 攻防世界Mobile5 EasyJNI 安卓逆向CTF

    EasyJNI 最近正好在出写JNI,正好看到了一道JNI相关的较为简单明了的CTF,就一时兴起的写了,不得不说逆向工程和正向开发确实是可以互补互相加深的 JNI JNI(Java Native In ...

  7. 日常破解--从XCTF的app3题目简单了解安卓备份文件以及sqliteCipher加密数据库

    一.题目来源     题目来源:XCTF app3题目 二.解题过程     1.下载好题目,下载完后发现是.ab后缀名的文件,如下图所示:     2.什么是.ab文件?.ab后缀名的文件是Andr ...

  8. 日常破解--XCTF easy_apk

    一.题目来源     来源:XCTF社区安卓题目easy_apk 二.破解思路     1.首先运行一下给的apk,发现就一个输入框和一个按钮,随便点击一下,发现弹出Toast验证失败.如下图所示: ...

  9. XCTF练习题-WEB-webshell

    XCTF练习题-WEB-webshell 解题步骤: 1.观察题目,打开场景 2.根据题目提示,这道题很有可能是获取webshell,再看描述,一句话,基本确认了,观察一下页面,一句话内容,密码为sh ...

  10. 【XCTF】ics-04

    信息: 题目来源:XCTF 4th-CyberEarth 标签:PHP.SQL注入 题目描述:工控云管理系统新添加的登录和注册页面存在漏洞,请找出flag 解题过程 进入注册页面,尝试注册: 进行登录 ...

随机推荐

  1. Spring boot启动时报 java.sql.SQLException: java.lang.ClassCastException: java.math.BigInteger cannot be cast to java.lang.Long错误

    Spring boot启动时报 java.sql.SQLException: java.lang.ClassCastException: java.math.BigInteger cannot be ...

  2. MMDetection 快速开始,训练自定义数据集

    本文将快速引导使用 MMDetection ,记录了实践中需注意的一些问题. 环境准备 基础环境 Nvidia 显卡的主机 Ubuntu 18.04 系统安装,可见 制作 USB 启动盘,及系统安装 ...

  3. Docker-MsSqlServer和安装版本异同

    创建SqlServer容器 docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=<YourStrong@Passw0rd&g ...

  4. Redis必知必会系列

    1.常用命令 https://www.cnblogs.com/huozhonghun/p/11636053.html 2.Redis是什么 Redis 是 C 语言开发的一个开源的(遵从 BSD 协议 ...

  5. 【项目实践】一文带你搞定Spring Security + JWT

    以项目驱动学习,以实践检验真知 前言 关于认证和授权,R之前已经写了两篇文章: [项目实践]在用安全框架前,我想先让你手撸一个登陆认证 [项目实践]一文带你搞定页面权限.按钮权限以及数据权限 在这两篇 ...

  6. LeetCode876 链表的中间结点

    给定一个带有头结点 head 的非空单链表,返回链表的中间结点. 如果有两个中间结点,则返回第二个中间结点. 示例 1: 输入:[1,2,3,4,5] 输出:此列表中的结点 3 (序列化形式:[3,4 ...

  7. Flutter 应用入门:计数器

    用Android Studio创建的Flutter应用模板默认是一个简单的计数器示例. // 导入包 import 'package:flutter/material.dart'; // 应用入口,启 ...

  8. SpringBoot 集成Shiro之使用Redis缓存授权认证信息

    因为用户认证与授权需要从数据库中查询并验证信息,但是对于权限很少改变的情况,这样不断从数据库中查询角色验证权限,对整个系统的开销很大,对数据库压力也随之增大.因此可以将用户认证和授权信息都缓存起来,第 ...

  9. mysql的导入

    方法1 load data [local] infile 'filename' into table tablename[option] ields terminated by 'string'(字段 ...

  10. 【win10】win10下两个显示器不同桌面壁纸

    win10系统下,双屏显示为不同的桌面壁纸 操作: 1.鼠标右键点击个性化 2.点击背景选项 3.在图片上右键选择要添加为背景的图片 同理,将另一个屏幕壁纸设为监视器1 最后效果为两个分屏为不同桌面壁 ...