JarvisOJ 逆向Writeup
1. 爬楼梯
先运行apk,查看具体的功能
爬一层楼是可以点击的,爬到了,看FLAG是不可以点击的.我们可以大致的了解到到了具体的楼层才可以看到flag,多次打开软件,楼层数目是随机的.
用APKIDE反编译后,用jd-gui查看源码
package com.ctf.test.ctf_100; import android.os.Bundle;
import android.os.Debug;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.util.Random; public class MainActivity
extends AppCompatActivity
{
public int has_gone_int; //已经爬的楼层
public int to_reach_int; //要爬的楼层 static
{
if (!Debug.isDebuggerConnected()) {
System.loadLibrary("ctf"); //导入库文件
}
} public void Btn_up_onclick(View paramView)
{
this.has_gone_int += 1; //每点击一次按钮,已经爬的楼层+1.
paramView = "" + this.has_gone_int;
((TextView)findViewById(2131492948)).setText(paramView);
if (this.to_reach_int <= this.has_gone_int) { //如果已经爬的楼层 大于或等于要爬的楼层,设置按钮空间点击有效
((Button)findViewById(2131492950)).setClickable(true);
}
} public void btn2_onclick(View paramView)
{
((TextView)findViewById(2131492951)).setText("{Flag:" + get_flag(this.to_reach_int) + "}"); //显示flag
} public native String get_flag(int paramInt); protected void onCreate(Bundle paramBundle) //创建
{
super.onCreate(paramBundle);
setContentView(2130968601);
((Button)findViewById(2131492950)).setClickable(false); //设置显示flag控件按钮点击无效.也就是说刚开始我们是不能点击的,需要一定的条件.
//如果我们将此处改为true,那么开始的时候就可以点击了.
this.has_gone_int = 0; //设置已经爬的楼层的默认值为0
paramBundle = new Random();
for (this.to_reach_int = paramBundle.nextInt();; this.to_reach_int = paramBundle.nextInt())
{
if (this.to_reach_int < 0) {
this.to_reach_int *= -1;
}
if (5 < this.to_reach_int)
{
this.to_reach_int %= 32;
this.to_reach_int *= 16384;
((TextView)findViewById(2131492947)).setText("" + this.to_reach_int);
((TextView)findViewById(2131492951)).setText("");
return;
}
}
}
}
从源码中我们有非常多的思路来显示flag,因为APKIDE我无法回编译成功,所以用android killer来进行回编译成功了
查看smail源码,查看setclickable字符串,
const/4 v3, 0x1 invoke-virtual {v0, v3}, Landroid/widget/Button;->setClickable(Z)V
invoke-virtual {v0, v5}, Landroid/widget/Button;->setClickable(Z)V
有两处调用了setClickable函数,v3和v5的分别是0x0,0x1,这就是传参中的true和false.我们把上面中的false改为true.然后就可以获得flag
FindPass
用jadx打开apk,找到主要函数
public void GetKey(View view) {
String fkey = ((EditText) findViewById(R.id.editText1)).getText().toString();
if (TextUtils.isEmpty(fkey.trim())) { //如果输入的字符串为空,则输出下面的话
Toast.makeText(this, "请输入key值!", 1).show();
return;
}
char[] ekey = getResources().getString(R.string.fkey).toCharArray(); //从资源中获取字符串ekey
int changdu = ekey.length; //资源中的字符串长度
char[] cha = new char[1024]; //新建一个1024长度的字符数组
try {
new InputStreamReader(getResources().getAssets().open("src.jpg")).read(cha); //读取一张图片的数据到cha数组中
} catch (Exception e) {
e.printStackTrace();
}
for (int i = 0; i < changdu; i++) {
int temp2 = cha[ekey[i]] % 10;
if (i % 2 == 1) {
ekey[i] = (char) (ekey[i] + temp2);
} else {
ekey[i] = (char) (ekey[i] - temp2);
}
}
if (fkey.equals(new String(ekey))) {
Toast.makeText(this, "恭喜您,输入正确!Flag==flag{Key}", 1).show();
} else {
Toast.makeText(this, "not right! lol。。。。", 1).show();
}
}
在这里也学到了一些新的知识,android用id定位某些资源,将这些资源都放在xml文件中.从中提取出来fkey字符串的值
我们可以看到就是用图片的字节数据和资源中的字符串进行运算就可以得到flag.一直弄不出来,后来看别人的WP,写出来了.原来是数据类型的问题.InputStreamReader函数读取8位的字节流.也就是说是byte.它的取值范围从-128~127.而python的取值范围是0~255.所以flag中有一位出现错误,总是找不出来错误原因.贴上抄别人的代码.图片资源从解压的APK中获取.
ekey='Tr43Fla92Ch4n93'
changdu =len(ekey)
cha =[]
flag=''
f =open('src.jpg','rb')
f.seek(0,0)
for i in range(0,1024):
byte = f.read(1)
cha.append(ord(byte))
#print(cha)
for i in range(len(ekey)):
if cha[ord(ekey[i])]<128:
temp2 = cha[ord(ekey[i])] % 10
else :
temp2 =(-(cha[ord(ekey[i])]%128))%10 if i % 2 == 1:
flag +=chr(ord(ekey[i]) + temp2)
else:
flag +=chr(ord(ekey[i]) -temp2) print(flag) #Qv49CmZB2Df4jB-
最后运行模拟器验证,发现终于对了.
Classical Crackme
先运行查看信息,发现一个输入框,查壳.用C#写的直接去看源码
找到了关键信息,base64解密得到flag
JarvisOJ 逆向Writeup的更多相关文章
- 简单的Elf逆向Writeup
ElfCrackMe1 html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acrony ...
- IDF-CTF-简单的Elf逆向Writeup
ElfCrackMe1 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !imp ...
- IDF实验室-简单的ELF逆向 writeup
题目:http://ctf.idf.cn/index.php?g=game&m=article&a=index&id=39 下载得到ElfCrackMe1文件,直接用IDA打开 ...
- 社团的CTF逆向题WriteUp
最近社团弄了CTF比赛,然后我就帮忙写了逆向的题目,这里写一下WriteUp,题目和源码在附件中给出 一个简单的逆向:one_jmp_to_flag.exe 这题算是签到题,直接OD智能搜索就完事了, ...
- JarvisOJ平台Web题部分writeup
PORT51 题目链接:http://web.jarvisoj.com:32770/ 这道题本来以为是访问服务器的51号端口,但是想想又不太对,应该是本地的51号端口访问服务器 想着用linux下的c ...
- 【Data URL】【RE】【bugku】逆向入门writeup
在写wp之前先来了解一下Data URL是什么 Data URL 在浏览器向服务端发送请求来引用资源时,一般浏览器都有同一时间并发请求数不超过4个的限制.所以如果一个网页需要引用大量的服务端资源,就会 ...
- DDCTF2019逆向分析前俩题WriteUP
DDCTF2019 笔者做了前俩道题.冷不丁过去一个月了.现在在此做一下WriteUp:题目链接: 1:题目1 2:题目2 reverse1:writeup: 1.程序打开后如下所示 2.查壳结果为U ...
- 实验吧逆向catalyst-system Writeup
下载之后查看知道为ELF文件,linux中执行之后发现很慢: 拖入ida中查看发现有循环调用 sleep 函数: 这是已经改过了,edit -> patch program -> chan ...
- 南京邮电大学 CTF 逆向部分 Writeup
Hello,RE! 提示 IDA 中按 R . Google 到 IDA 中 R 快捷键是 Character ,转为字符串. 丢进 IDA(虽然我并不会使用 IDA 有个 strcmp 函数,比较 ...
随机推荐
- BZOJ 5450 轰炸 (强连通缩点+DAG最长路)
<题目链接> 题目大意: 有n座城市,城市之间建立了m条有向的地下通道.你需要发起若干轮轰炸,每轮可以轰炸任意多个城市.但每次轰炸的城市中,不能存在两个不同的城市i,j满足可以通过地道从城 ...
- elementUI 导航栏点击之后改变背景色,背景色悬停
一开始设置的是: .menuLeft .el-menu-item:hover{ background: #6db6ff !important; } .menuLeft .el-submenu__tit ...
- go web编程——自定义路由设计
本文主要讲解go语言web编程中自定义路由器的设计.在此之前需要先了解一下go语言web编程中路由与http服务的基本原理,可以参考笔者另一篇博文:go web编程——路由与http服务 . 我们已经 ...
- 初涉kafka
前言: 今天终于搭建成功kafka环境,并创建了第一个topic,并生产.消费消息,如下图: 生产: 消费: 心情真的是好激动,大家都说搭建环境其实特别简单,但是我的学习却一直卡在搭建环境上面,不是虚 ...
- sqlite查询语句
搜索距现在六个月前的月份第一天日期: SELECT date('now','start of month','-6 month','0 day'); 搜索距现在六个月前的日期: SELECT date ...
- CSS-02 BFC的理解
两个概念 感觉BFC挺重要的,于是最近查阅网上资料后小结一下,如果有不对的地方还望指正. 先理解两个概念: BOX :盒子模型 Block-Leave Box :块级元素 display属性为bloc ...
- vue不是内部或外部命令的解决方法
1.在nodejs的安装目录下,找到vue.cmd,将此路径加到环境变量中,我是通过nvm管理node版本的,路径是C:\Users\hy\AppData\Roaming\nvm\v6.10.0,关闭 ...
- spring cloud学习笔记四 熔断器Hystrix
我们知道分布式服务有这样一个特点,每一个微服务都有自己的业务,并且很多时候一个微服务的业务要依赖于其他微服务,如果这些相互关联的微服务中其中某个微服务请求失败时,就会导致其他调用它的微服务也会请求失败 ...
- MongoDB 存储引擎选择
MongoDB存储引擎选择 MongoDB存储引擎构架 插件式存储引擎, MongoDB 3.0引入了插件式存储引擎API,为第三方的存储引擎厂商加入MongoDB提供了方便,这一变化无疑参考了MyS ...
- <select multiple="multiple"> 数据回显
var names = yunying_name.split(","); for (var i = 0; i < names.length; i++) { names[i] ...