Skip to content

Commit 4f26cca

Browse files
committed
RaziCTF2020
1 parent 9f97d1c commit 4f26cca

File tree

22 files changed

+261
-2
lines changed

22 files changed

+261
-2
lines changed

README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,15 @@ Here we upload:
99
- Helpful tools and sitess
1010

1111

12-
##### Design by our CTF Team, [0xDED5EC](https://ctftime.org/team/50270).
12+
##### Design by our CTF Team, [TernaryBits](https://ctftime.org/team/50270).
1313

1414
## List of challenges
15+
### Android
16+
17+
- [razictf2020-chasing-a-lock](./android/razictf2020-chasing-a-lock/)
18+
- [razictf2020-ctf-coin](./android/razictf2020-ctf-coin/)
19+
- [razictf2020-friends](./android/razictf2020-friends/)
20+
1521
### Cryptograpy:
1622

1723
- [Tamuctf-crypto3: :)](./cryptography/tamuctf_\:\)/tamuctf-crypto3.md)
@@ -32,4 +38,4 @@ Here we upload:
3238
### Web:
3339

3440
- [UTCTF-web1: epic admin pwn](./web/epic-admin-pwn/WRITEUP.md)
35-
- [UTCTF-web3: Shrek Fans Only](./web/shrek-fans-only/WRITEUP.md)
41+
- [UTCTF-web3: Shrek Fans Only](./web/shrek-fans-only/WRITEUP.md)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Challenge: Chasing a Lock
2+
score: 858
3+
difficulty: easy
4+
5+
## Description
6+
[app-release.apk](./app-release.apk)
7+
8+
as locks are so popular many will chase them but why? maybe a flag :)
9+
10+
### Write-up
11+
[link](./WRITEUP.md)
12+
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# Write-up: Chasing a Lock
2+
![badge](https://img.shields.io/badge/Post%20CTF-Writeup-success)
3+
4+
## Description
5+
6+
### My Story
7+
First I executed the app and this is it:
8+
9+
![chasing a lock](./challenge.png)
10+
11+
Each time you touch the lock, the counter at the bottom of the page will decrease by one; while the lock changes its position randomly every second.
12+
13+
me: "So I should make the counter zero!" :D
14+
15+
I got the point and opened JADX and found the source code without any obfuscation. This is the source code of MainActivity:
16+
```
17+
package com.example.razictf_2;
18+
19+
import android.os.Bundle;
20+
import android.util.DisplayMetrics;
21+
import android.view.View;
22+
import android.view.View.OnClickListener;
23+
import android.widget.ImageButton;
24+
import android.widget.TextView;
25+
import androidx.appcompat.app.AppCompatActivity;
26+
import java.util.Random;
27+
import java.util.Timer;
28+
import java.util.TimerTask;
29+
30+
public class MainActivity extends AppCompatActivity {
31+
public void onCreate(Bundle bundle) {
32+
super.onCreate(bundle);
33+
setContentView((int) R.layout.activity_main);
34+
final ImageButton imageButton = (ImageButton) findViewById(R.id.my_button);
35+
final DisplayMetrics displayMetrics = new DisplayMetrics();
36+
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
37+
new Timer().schedule(new TimerTask() {
38+
public void run() {
39+
MainActivity.this.runOnUiThread(new Runnable() {
40+
public void run() {
41+
Random random = new Random();
42+
float nextFloat = random.nextFloat() * ((float) displayMetrics.widthPixels);
43+
float nextFloat2 = random.nextFloat() * ((float) displayMetrics.heightPixels);
44+
new Timer();
45+
imageButton.animate().x(nextFloat).y(nextFloat2).setDuration(0).start();
46+
}
47+
});
48+
}
49+
}, 0, 1000);
50+
imageButton.setOnClickListener(new OnClickListener() {
51+
public void onClick(View view) {
52+
TextView textView = (TextView) MainActivity.this.findViewById(R.id.Num);
53+
int parseInt = Integer.parseInt(textView.getText().toString());
54+
if (parseInt == 0 || parseInt < 0) {
55+
textView.setText("0");
56+
return;
57+
}
58+
int i = parseInt - 1;
59+
String run = new switcher().run(i);
60+
if (run != null) {
61+
((TextView) MainActivity.this.findViewById(R.id.Flag)).setText(run);
62+
}
63+
textView.setText(String.valueOf(i));
64+
}
65+
});
66+
}
67+
}
68+
```
69+
70+
And this is the interesting point:
71+
```
72+
String run = new switcher().run(i);
73+
```
74+
75+
It seems the magic part is inside the `switcher` class. This is the source code:
76+
```
77+
package com.example.razictf_2;
78+
79+
public class switcher {
80+
public String run(int i) {
81+
if (i != 0) {
82+
return null;
83+
}
84+
a1 a1Var = new a1();
85+
StringBuilder sb = new StringBuilder();
86+
sb.append(" ");
87+
sb.append(a1Var.run(i));
88+
String sb2 = sb.toString();
89+
a2 a2Var = new a2();
90+
System.out.println(a2Var.run(i));
91+
StringBuilder sb3 = new StringBuilder();
92+
sb3.append(sb2);
93+
sb3.append(a2Var.run(i));
94+
String sb4 = sb3.toString();
95+
a3 a3Var = new a3();
96+
StringBuilder sb5 = new StringBuilder();
97+
sb5.append(sb4);
98+
sb5.append(a3Var.run(i));
99+
String sb6 = sb5.toString();
100+
a4 a4Var = new a4();
101+
StringBuilder sb7 = new StringBuilder();
102+
sb7.append(sb6);
103+
sb7.append(a4Var.run(i));
104+
String sb8 = sb7.toString();
105+
a5 a5Var = new a5();
106+
StringBuilder sb9 = new StringBuilder();
107+
sb9.append(sb8);
108+
sb9.append(a5Var.run(i));
109+
return sb9.toString();
110+
}
111+
}
112+
```
113+
114+
### Exploit Time
115+
So the only thing I need to do is hooking the `run` method and rewrite the value of `i` argument to zero. It's really easy using Frida.
116+
I wrote [loader.py](./loader.py) and [script.js](./script.js).
117+
118+
### Flag
119+
And this is the result:
120+
![flag](./flag.png)

android/razictf2020-chasing-a-lock/app-release.apk

Whitespace-only changes.
30.2 KB
Loading
36 KB
Loading
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import time
2+
import frida
3+
4+
device = frida.get_usb_device()
5+
pid = device.spawn(["com.example.razictf_2"])
6+
device.resume(pid)
7+
time.sleep(1) # Without it Java.perform silently fails
8+
session = device.attach(pid)
9+
with open("script.js") as f:
10+
script = session.create_script(f.read())
11+
script.load()
12+
13+
# prevent the python script from terminating
14+
input()
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
console.log("Script loaded successfully ");
2+
Java.perform(function x() { //Silently fails without the sleep from the python code
3+
console.log("Inside java perform function");
4+
//get a wrapper for our class
5+
var my_class1 = Java.use("com.example.razictf_2.switcher"); // freind page
6+
//replace the original implmenetation of the function `fun` with our custom function
7+
my_class1.run.implementation = function (i) {
8+
//print the original arguments
9+
console.log(": run(" + i + ")");
10+
//call the original implementation of `fun` with args (2,5)
11+
i = 0;
12+
var ret_value = this.run(i);
13+
return ret_value;
14+
}
15+
});

android/razictf2020-ctf-coin/1.png

Loading

android/razictf2020-ctf-coin/2.png

50.3 KB
Loading

0 commit comments

Comments
 (0)