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 函数,比较 ...
随机推荐
- ichunqiu在线挑战--我很简单,请不要欺负我 writeup
挑战链接: http://www.ichunqiu.com/tiaozhan/114 知识点: 后台目录扫描,SQL Injection,一句话木马, 提权,登陆密码破解 这个挑战是为像我这种从来都没 ...
- SpringBoot实现上传下载(二)
这篇写下载. **1.实现思路** 上一篇的数据库设计中,我们有一个字段始终没有用到fileName,这是用来给Layer对象存储文件名的,以此来完成文件与对象的对应, :nextTick
在阅读 nextTick 的源码之前,要先弄明白 JS 执行环境运行机制,介绍 JS 执行环境的事件循环机制的文章很多,大部分都阐述的比较笼统,甚至有些文章说的是错误的,以下为个人理解,如有错误, ...
- JS的video在手机上有些手机能播放,而有些不能原因
一,一开始我video是这样写的,直接给地址,然后有很多手机却不能播放,或者说卡在一开始的页面,是什么原因呢? <video id='video' > <source src='xx ...
- git如何删除远程仓库的某次错误提交
git如何删除远程仓库的某次错误提交 如果远程仓库,能ssh访问,那就跟本地没什么区别 reset命令有3种方式 git reset --mixed 此为默认方式,不带任何参数的git res ...
- vue项目中配置favicon图标
如上图所示,页面顶部的小图标会让页面显得高大上,一般把这种图标叫做favicon图标.利用vue-cli脚手架搭建的项目,如果不手动配置,页面中是不会显示favicon图标. 不配置是这样子的: fa ...
- KVC、KVO 理解
参考经典链接: https://www.jianshu.com/p/f8198ca5e682 https://www.jianshu.com/p/be80318115a7 一. KVC 1.KVC介绍 ...
- Linux就该这么学06学习笔记
参考链接:https://www.linuxprobe.com/chapter-06.html 1.一切从“/”开始 Linux系统中的一切文件都是从“根(/)”目录开始的,并按照文件系统层次化标准( ...
- HTML基础:<a>标签 编写个人收藏夹
编写个人收藏夹 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <t ...