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 函数,比较 ...
随机推荐
- deepFreeze
obj1 = { internal: {} }; Object.freeze(obj1); obj1.internal.a = 'aValue'; obj1.internal.a // 'aVal ...
- Spring cloud学习--Zuul01
Zuul解决的问题 作为系统的统一入口,屏蔽了系统内部各个微服务的细节 可以与微服务治理框架结合,实现自动化的服务实例维护以及负载均衡的路由转发 实现接口权限校验与微服务业务逻辑的解耦 搭建Zuul服 ...
- css禁止事件
js有多种禁止事件的方法, css也有: pointer-events:none
- Spring Boot 1.x 正式退役,2.x大步向前!
Java技术栈 www.javastack.cn 优秀的Java技术公众号 早在<Spring Boot 2.1.5 正式发布,1.5.x 即将结束使命!>一文中栈长就提醒大家 Sprin ...
- 16、NumPy ——字节交换
NumPy 字节交换 在几乎所有的机器上,多字节对象都被存储为连续的字节序列.字节顺序,是跨越多字节的程序对象的存储规则. 大端模式:指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地 ...
- 1481:Maximum sum (前缀和+dp)
[题目描述] 对一个序列A={a1, a2,..., an}给出函数: t1 t2 d(A) = max{ ∑ai + ∑aj | 1 <= s1 <= t1 < s2 <= ...
- python学习第五天流程控制分支if和循环while
所有的逻辑结构围绕分支和循环进行,比如登陆注册,支付成功与否等等,下面讲述分支if用法和while用法 if age>30: print("www.96net.com.cn" ...
- Mysql命令收集【重要】
1.在linux上获取Mysql服务器状态,及版本: [root@host]# mysqladmin --version 结果信息: mysqladmin Ver 8.42 Distrib 5.7. ...
- Javascript 数组的一些操作
(1) shift 删除原数组第一项,并返回删除元素的值:如果数组为空则返回undefined var a = [1,2,3,4,5]; var b = a.shift(); //a:[2,3,4, ...
- CSS-02 BFC的理解
两个概念 感觉BFC挺重要的,于是最近查阅网上资料后小结一下,如果有不对的地方还望指正. 先理解两个概念: BOX :盒子模型 Block-Leave Box :块级元素 display属性为bloc ...