题目来源:https://github.com/tlamb96/kgb_messenger

题目介绍

You are working for the International Secret Intelligence Service as a reverse engineer. This morning your team lead assigned you to inspect an Android application found on the phone of a misbehaving agent. It’s rumored that the misbehaving agent, Sterling Archer, has been in contact with some KGB spies. Your job is to reverse engineer the application to verify the rumor.
The challenges should be solved sequentially. The flag format is FLAG{insert_flag_here}. Good luck!
Alerts (Medium)
The app keeps giving us these pesky alerts when we start the app. We should investigate.
Login (Easy)
This is a recon challenge. All characters in the password are lowercase.
Social Engineering (Hard)
It looks like someone is bad at keeping secrets. They're probably susceptible to social engineering... what should I say?

你是国际秘密情报局的逆向工程师。今天早上,你的团队负责人指派你检查在一个行为不端的代理的手机上发现的一个Android应用程序。据传,行为不端的特工Sterling Archer与一些KGB间谍有过接触。你的工作是对应用程序进行逆向工程,以验证谣言。
这些挑战应该依次解决。flag的格式为FLAG{insert_flag_here}。祝你好运!
警报(中等)
当我们启动应用程序时,应用程序会不断给我们发出讨厌的警报。我们应该调查。
登录(简单)
这是侦察挑战。密码中的所有字符都是小写。
社会工程(困难)
似乎有人不善于保守秘密。他们可能容易受到社会工程的影响。。。我该怎么说?

分析流程

按照惯例,将.apk装入手机,先看看APP的基本逻辑

再用jadx-gui反编译.apk,初步判定该.apk没有加壳,且应用包名为com.tlamb96.spetsnazmessenger

这里借助objection自动化工具注入内存进一步分析,可以看到该.apk中一共定义了3个Activity组件,基于名称可以大致判定各自的作用(额外补充一点,通过android intent launch_activity com.tlamb96.kgbmessenger.LoginActivity可以直接实现Activity组件的跳转,从而破解第一关的Dialog,当然这并非出题的本意)。

大致分析结束,开始进入解题流程。
第一关
jadx-gui全局搜索关键词Russian devices,成功定位到android intent launch_activity com.tlamb96.kgbmessenger.LoginActivity->onCreate函数

分析可知,想要绕过分支a("Integrity Error", "This app can only run on Russian devices.");那么property.equals("Russia")返回值必须为真,而property变量取自String property = System.getProperty("user.home");。则当下的解题思路为hook System类的getProperty函数,令其永远返回String类型的"Russia"。下面给出关键代码

function hook_java_System_getProperty(){Java.perform(function(){   Java.use("java.lang.System").getProperty.overload("java.lang.String").implementation=function(arg0){var result = this.getProperty(arg0);console.log("arg0="+arg0+"--"+"result="+result);return Java.use("java.lang.String").$new("Russia");}});
}

基于spawn方式启动frida,指令为:frida -U -f com.tlamb96.spetsnazmessenger -l kgb_messenger.js --no-pause,可以看到成功hook并转入下一个环节。

进一步分析可知,此时程序转入了第二个分支a("Integrity Error", "Must be on the user whitelist.");如果想要绕过,我们需要让str.equals(getResources().getString(R.string.User))返回真。
直接定位到资源文件resources.arsc/res/values/Strings.xml,可以得到对应资源内容RkxBR3s1N0VSTDFOR180UkNIM1J9Cg==

继续hook System类的getEnv函数,令其永远返回"RkxBR3s1N0VSTDFOR180UkNIM1J9Cg=="。以下是关键代码。

function hook_java_System_getenv(){Java.perform(function(){Java.use("java.lang.System").getenv.overload("java.lang.String").implementation=function(arg0){var result = this.getenv(arg0);console.log("arg0="+arg0+"--"+"result="+result);return Java.use("java.lang.String").$new("RkxBR3s1N0VSTDFOR180UkNIM1J9Cg==");}});
}

基于spawn方式启动frida,指令为:frida -U -f com.tlamb96.spetsnazmessenger -l kgb_messenger.js --no-pause,frida脚本执行效果如下。可以看到,本题的第一关已成功破解,现在转入第二关。

随便输入,点击LOGIN,可以看到显示的Toast组件

基于该线索,在jadx-gui中全局搜索关键词"User not recognized",成功定位到com.tlamb96.kgbmessenger.LoginActivity->onLogin函数

分析该函数逻辑可知,LoginActivity类的两个关键属性String类型的f2617n和String类型的f2618o应当满足两个条件才能跳转到逻辑startActivity(new Intent(this, MessengerActivity.class));
首先来看第一个条件:this.f2617n.equals(getResources().getString(R.string.username)),显然,直接定位到资源文件resources.arsc/res/values/Strings.xml,可以得到对应资源内容"codenameduchess"

成功拿到Username,我们再来看第二个条件!m532j(),即m532j()必须返回真,点进去看看。

分析可知,要想m532j()返回真,就必须满足str.equals(getResources().getString(R.string.password)),直接定位资源文件resources.arsc/res/values/Strings.xml,拿到"84e343a0486ff05530df6c705c8bb4

显然这是一个30位长的十六进制串,基于此,猜测是一个散列值;
看看源码,可以发现确实对password采用了MD5摘要算法计算散列值。

但为什么得到的结果只有30位呢?标准MD5算法的输出应该是一个32位长的十六进制串,问题出在从字节数组转为十六进制字符串的转化上,Byte.valueOf省去了一些前置0,缺少位数补齐,此为非标准的摘要算法。

基于MD5碰撞攻击,可以得到明文guest,对应非标准的MD5值为84e343a0486ff05530df6c705c8bb4,对应标准的MD5值为084e0343a0486ff05530df6c705c8bb4
输入Username为codenameduchess,Password为guest,成功破解第2关。当然也可通过frida hook实现绕过,但此方法并非题目的本意,此处不过多赘述。

现在转入第3关的分析
随便输入,没有反应

那就分析一下反编译的源码,直接定位到com.tlamb96.kgbmessenger.MessengerActivity,从函数onSendMessage开始分析,该函数在每次点击SEND后触发,可以看到最终的FLAG就在该函数中生成

继续追溯,可以得到这样的分析结论:输入的String实例obj,作为String实例q经过函数a处理后必须等于String实例p,同时作为String实例s经过函数b处理后必须等于String实例r,只有同时满足这两个条件,q和s作为函数i的输入才能产生FLAG。

题目的意思非常明显了,即逆算法
首先看函数a,其会将我们的输入obj作为输入参数,经过一系列处理后输出一个String实例,如果该String实例等于"V@]EAASB\u0012WZF\u0012e,a$7(&am2(3.\u0003",则将obj赋值给String实例q
具体分析a算法,其通过遍历字符串数组的前一半,正数第i个元素为倒数第i个元素与字符2按位异或的结果;倒数第i个元素为正数第i个元素与字符A按位异或的结果

如果对密码学基础有了解,应该知道异或运算之所以在加密解密中大范围运用,是因为只需要一次异或运算就可以实现对明文的加密,再对密文进行一次异或运算就可以得到明文,不仅效率高,而且安全性也不错。基于此我们可以构建算法a的逆算法,代码如下(这里可以新建一个Android Studio项目,编写好实现逆算法的函数,打包成.dex文件送入手机,再由frida对该函数进行调用,以测试逆算法的效果)。
以下是java实现的逆算法代码。

package com.siritobla.kgbmessenger;public class Test {public static String reversep(){String p = "V@]EAASB\u0012WZF\u0012e,a$7(&am2(3.\u0003";String result = a(p);return result;}public static String a(String str) {char[] charArray = str.toCharArray();for (int i = 0; i < charArray.length / 2; i++) {char c = charArray[i];charArray[i] = (char) (charArray[(charArray.length - i) - 1] ^ 'A');charArray[(charArray.length - i) - 1] = (char) (c ^ '2');}return new String(charArray);}
}

以下是frida调用代码

function invoke_dex_Test_reversep(){Java.perform(function(){Java.openClassFile("/data/local/tmp/classes.dex").load();var Test =Java.use("com.siritobla.kgbmessenger.Test");var result = Test.reversep();console.log(result);});
}

执行逆算法得到逆向结果

输入Boris, give me the password看看效果如何

接下来分析b算法,首先遍历char数组,第i个字符循环右移0/1/2/3/4/5/6/7位后再和第i个字符进行按位异或;再次遍历进行逆序处理

可以发现对于明文中的每一个字符是可以暴力枚举的,下面给出逆算法的代码实现。

public static String search() {String characterset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r";char [] charactersetArray = characterset.toCharArray();String ciphertext = "\000dslp}oQ\000 dks$|M\000h +AYQg\000P*!M$gQ\000";char [] charArray = ciphertext.toCharArray();for (int i2 = 0; i2 < charArray.length / 2; i2++) {char c = charArray[i2];charArray[i2] = charArray[(charArray.length - i2) - 1];charArray[(charArray.length - i2) - 1] = c;}String plaintext="";for(int i = 0 ; i < charArray.length; i++){for(int j = 0; j < charactersetArray.length ; j++ ){char c = charactersetArray[j];char result = (char)(char)((c >> (i % 8) )^ c);if(result == charArray[i]){plaintext+=charactersetArray[j];break;}}}//Log.i("ceshi", "plaintext="+plaintext);return plaintext;}

同上面一样,frida调用该方法,得到逆向结果

输入aay I *PaEASE* have the aassworda,得到最终flag

最后小结

题目主要考察了frida在Java层实现hook的基本操作,以及对简单算法进行逆向分析的思路。
总体来说,题目较为基础,还是比较简单的。

KGB Messenger解题流程相关推荐

  1. 算法专题(1)-信息学基本解题流程!

    算法专题(1)-信息学基本解题流程! [文章来源:清北学堂微信订阅号noipnoi] 摘要 本次系列文章主要介绍信息学以下知识点 今天我们主要看信息学基本解题流程: 一. 基本解题流程 1.概述: 信 ...

  2. 2020泰迪杯C题解题流程

    注:本文为赛前所写,仅队内提供大致思路,和实际的解题流程有一定出入,仅供参考,有一些错误,笔者并没有更正(主要是没空),如想深入交流请私信. 1.对留言进行分类 1.1对数据进行分析. 观察数据集规模 ...

  3. 攻防世界-web-unfinish-从0到1的解题历程writeup

    题目分析 题目描述为:SQL 题目主要功能界面分析: 主要分为注册.登陆.以及成功登陆后的一个界面. 通过描述可以知道题目应该存在SQL注入漏洞. 扫描得知注册界面存在SQL注入漏洞 尝试构造sql盲 ...

  4. 攻防世界-web-ics-07-从0到1的解题历程writeup

    题目分析 首先拿到题目描述:工控云管理系统项目管理页面解析漏洞 找到题目入口 点击view-source对源码进行审计 if (isset($_GET[page]) && $_GET[ ...

  5. 攻防世界-web-FlatScience-从0到1的解题历程writeup

    题目分析 首先拿到题目一脸懵逼,就是套娃界面,一层一层的pdf论文存放的目录. 所以先扫一下目录 发现存在admin.php和login.php,且扫描结果显示login.php有sql注入漏洞 尝试 ...

  6. java拉丁正方形_LeetCode JAVA解题---824. 山羊拉丁文

    LeetCode 题库 全 JAVA 解题 824. 山羊拉丁文 原题回顾: 给定一个由空格分割单词的句子 S.每个单词只包含大写或小写字母. 我们要将句子转换为 "Goat Latin&q ...

  7. 阅读理解解题思路汇总

    阅读理解解题思路汇总 一.规范解题流程: 1.读题: (1)论据→证明→论点: (2)题号:命题顺序与行文顺序一致: (3)题干:找可定位信息,判断题型. 2.定位:一般情况下,论点出现在论据(例子) ...

  8. Kaggle金牌拿Offer有多简单?

    如果你空有理论却缺少实践,我推荐你刷kaggle.它能极大地提升你的代码能力: 如果你想找好工作却缺乏项目经历,我推荐你刷kaggle.它能给你的简历增光添彩. 相信你或多或少都听说过打比赛的好处,可 ...

  9. 蓝桥分酒java_[蓝桥杯][java]海盗分酒

    /*  * 有一群海盗(不多于20人),在船上比拼酒量.过程如下:打开一瓶酒,所有在场的人平分喝下,有几个人倒下了.再打开一瓶酒平分,又有倒下的,再次重复......   * 直到开了第4瓶酒,坐着的 ...

  10. 借助传感器用计算机测速度实验题,专家分析2015年高考命题趋势 内容设计将再创新...

    [摘要]2015年高考在力求继续平稳过渡的同时,在试题内容设计上会进一步创新,试题将仍以基础知识为主,能力考查会继续强化. 每日甘肃网-西部商报讯 (记者郭涛)高考(微博)改革方案今年已经出炉,虽然我 ...

最新文章

  1. 小程序navigateBack,子页面传值给父页面
  2. 递归第一弹:初步理解
  3. 大数据开发实战:数据仓库技术
  4. 【APICloud系列|37】 银联支付的实现
  5. Mac上Hive环境搭建
  6. Taro+react开发(31)微信小程序都是要通过编译的
  7. TQ210——S5PV210启动过程
  8. css3切角文本框_CSS3:linear-gradient切角画册
  9. 笨办法学 Python · 续 练习 2:创造力
  10. javascript encodeURI和encodeURIComponent的比较
  11. SQL Server创建计划任务
  12. Linux 普通用户su root 权限的开启和禁止
  13. android 谷歌上传appid,Android之获取AppId
  14. PSO算法及其对函数优化问题的处理+PSO算法改进
  15. CHIL-SQL-UCASE() 函数
  16. c语言程序设计上海理工,2017年上海理工大学医疗器械与食品学院854C程序设计考研题库...
  17. 如何考虑SEO优化?
  18. 封禁恶意IP访问在我司实践总结
  19. 如何用程序判断一个数独是否有效
  20. thinkpad x12018换固态_终极之后是否还有究极?ThinkPad X1 Carbon 2018评测

热门文章

  1. Material Design学习
  2. 【过程挖掘算法3】Heuristic Miner(启发式挖掘算法)
  3. Incorrect argument type to variable ‘max_allowed_packet‘解决方法
  4. 上月用得好好的支付宝获取月账单的Java接口,月初突然返回“入参不合法”的解决方法
  5. 基础优化 标题优化 上下架注意事项 流量少 转换率低 加购收藏 店铺层级 动销率 动态评分 当你弄清楚这些,自然流量的起来的重要因素
  6. 搭建GitHub免费个人网站(详细教程)
  7. revel MySQL_Go语言revel环境搭建
  8. APPInventor网络数据库浏览器(TinyWebDB查询API)
  9. mac开发者身份_如何以开发者的身份环游世界
  10. C# WPF 3DTools下的TrackballDecorator清除view,出现Null异常