Skip to content

Commit 4eabfb9

Browse files
committed
Update README and document for Quark Script
1 parent af017de commit 4eabfb9

17 files changed

+303
-25
lines changed

README.md

Lines changed: 104 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Quark-Engine is also bundled with [Kali Linux](https://tools.kali.org/tools-list
3939
## Quark Script - Ecosystem for Mobile Security Tools
4040

4141
#### Innovative & Interactive
42-
The goal of Quark Script aims to provide an innovative way for mobile security researchers to analyze or pentest the targets.
42+
The goal of Quark Script aims to provide an innovative way for mobile security researchers to analyze or __pentest__ the targets.
4343

4444
Based on Quark, we integrate decent tools as Quark Script APIs and make them exchange valuable intelligence to each other. This enables security researchers to __interact__ with staged results and perform __creative__ analysis with Quark Script.
4545

@@ -64,7 +64,6 @@ Quark Script is now in a beta version. We'll keep releasing practical APIs and a
6464
* return: Quark rule instance
6565

6666
</details>
67-
6867
<details>
6968
<summary><b> runQuarkAnalysis(SAMPLE_PATH, ruleInstance) </b></summary>
7069

@@ -84,6 +83,16 @@ Quark Script is now in a beta version. We'll keep releasing practical APIs and a
8483
* params: none
8584
* return: detected behavior instance
8685

86+
</details>
87+
<details>
88+
<summary><b> quarkResultInstance.getAllStrings(none) </b></summary>
89+
90+
<br>
91+
92+
* Description: Get all strings inside the target APK file.
93+
* params: none
94+
* return: python list containing all strings inside the target APK file.
95+
8796
</details>
8897
<details>
8998
<summary><b> behaviorInstance.firstAPI.fullName </b></summary>
@@ -124,6 +133,16 @@ Quark Script is now in a beta version. We'll keep releasing practical APIs and a
124133
* params: none
125134
* return: method instance
126135

136+
</details>
137+
<details>
138+
<summary><b> behaviorInstance.getParamValues(none) </b></summary>
139+
140+
<br>
141+
142+
* Description: Get parameter values that API1 sends to API2 in the behavior.
143+
* params: none
144+
* return: python list containing parameter values.
145+
127146
</details>
128147
<details>
129148
<summary><b> methodInstance.getXrefFrom(none) </b></summary>
@@ -146,7 +165,7 @@ Quark Script is now in a beta version. We'll keep releasing practical APIs and a
146165

147166
</details>
148167
<details>
149-
<summary><b> Objection(none) </b></summary>
168+
<summary><b> Objection(host) </b></summary>
150169

151170
<br>
152171

@@ -156,7 +175,7 @@ Quark Script is now in a beta version. We'll keep releasing practical APIs and a
156175

157176
</details>
158177
<details>
159-
<summary><b> objInstance.hookMethod(method, watchArgs, watchBacktrace, watchRet) </b></summary>
178+
<summary><b> objInstance.hookMethod(method, watchArgs, watchBacktrace, watchRet) </b></summary>
160179

161180
<br>
162181

@@ -167,7 +186,6 @@ Quark Script is now in a beta version. We'll keep releasing practical APIs and a
167186
</details>
168187

169188
### Analyzing real case (InstaStealer) using Quark Script
170-
171189
#### Quark Script that dynamic hooks the method containing urls
172190
The scenario is simple! We'd like to dynamic hooking the methods in the malware that contains urls. We can use APIs above to write Quark Script.
173191

@@ -216,12 +234,11 @@ for behaviorInstance in quarkResult.behaviorOccurList:
216234

217235
print("\nSee the hook results in Objection's terminal.")
218236
```
219-
220-
> __Note:__ Please make sure you have the dynamic analysis environment ready before executing the script.
237+
> Note: Please make sure you have the dynamic analysis environment ready before executing the script.
221238
> 1. Objection installed and running. Check the guideline [here](https://github.com/sensepost/objection/wiki/Installation).
222239
> 2. Android Virtual Machine with frida installed. Check the guideline [here](https://frida.re/docs/android/).
223-
> 3. Or a rooted Android Device (Google Pixel 6) with frida installed.\
224-
Check the root guideline [here](https://forum.xda-developers.com/t/guide-root-pixel-6-with-magisk-android-12-1.4388733/), frida install guideline is the [same](https://frida.re/docs/android/) with Android Virtual Machine.
240+
> 3. Or a rooted Android Device (Google Pixel 6) with frida installed.
241+
> Check the root guideline [here](https://forum.xda-developers.com/t/guide-root-pixel-6-with-magisk-android-12-1.4388733/), frida install guideline is the [same]((https://frida.re/docs/android/)) with Android Virtual Machine.
225242
226243
#### Quark Script Result
227244
![](https://i.imgur.com/elztZdC.png)
@@ -232,6 +249,84 @@ Check the root guideline [here](https://forum.xda-developers.com/t/guide-root-pi
232249
#### Method (callComponentMethod) with urls is detected triggered!
233250
![](https://i.imgur.com/ryV3f57.jpg)
234251

252+
### Quark Script used as a vulnerability finder
253+
254+
#### Detect CWE-798 in Android Application
255+
256+
This scenario seeks to find hard-coded credentials in the APK file. See [CWE-798](https://cwe.mitre.org/data/definitions/798.html) for more details.
257+
258+
Let's use this [APK](https://github.com/oversecured/ovaa) and the above APIs to show how Quark script find this vulnerability.
259+
260+
First, we design a detection rule `findSecretKeySpec.json` to spot on behavior uses method SecretKeySpec. Then, we get all the parameter values that input to this method. From the returned parameter values, we identify it's a AES key and parse the key out of the values. Finally, we dump all strings in the APK file and check if the AES key is in the strings. If the answer is YES, BINGO!!! We find hard-coded credentials in the APK file.
261+
262+
#### Quark Scipt: cwe-798.py
263+
```python
264+
import re
265+
from quark.script import runQuarkAnalysis, Rule
266+
267+
SAMPLE_PATH = "ovaa.apk"
268+
RULE_PATH = "findSecretKeySpec.json"
269+
270+
ruleInstance = Rule(RULE_PATH)
271+
quarkResult = runQuarkAnalysis(SAMPLE_PATH, ruleInstance)
272+
273+
for secretKeySpec in quarkResult.behaviorOccurList:
274+
275+
allStrings = quarkResult.getAllStrings()
276+
277+
firstParam = secretKeySpec.getParamValues()[0]
278+
secondParam = secretKeySpec.getParamValues()[1]
279+
280+
if secondParam == "AES":
281+
AESKey = re.findall(r'\((.*?)\)', firstParam)[1]
282+
283+
if AESKey in allStrings:
284+
print(f"Found hard-coded {secondParam} key {AESKey}")
285+
```
286+
287+
#### Quark Rule: findSecretKeySpec.json
288+
```json
289+
{
290+
"crime": "Detect APK using SecretKeySpec.",
291+
"permission": [],
292+
"api": [
293+
{
294+
"descriptor": "()[B",
295+
"class": "Ljava/lang/String;",
296+
"method": "getBytes"
297+
},
298+
{
299+
"descriptor": "([BLjava/lang/String;)V",
300+
"class": "Ljavax/crypto/spec/SecretKeySpec;",
301+
"method": "<init>"
302+
}
303+
],
304+
"score": 1,
305+
"label": []
306+
}
307+
```
308+
309+
#### Quark Script Result
310+
```bash
311+
$ python3 findSecretKeySpec.py
312+
313+
Found hard-coded AES key 49u5gh249gh24985ghf429gh4ch8f23f
314+
```
315+
316+
#### Hard-Coded AES key in the APK file
317+
```
318+
const-string v2, "49u5gh249gh24985ghf429gh4ch8f23f"
319+
320+
invoke-virtual {v2}, Ljava/lang/String;->getBytes()[B
321+
322+
move-result-object v2
323+
324+
invoke-direct {v1, v2, v0}, Ljavax/crypto/spec/SecretKeySpec;-><init>([BLjava/lang/String;)V
325+
```
326+
327+
328+
329+
235330
## Quark Web Report
236331

237332
With the following command, you can easily analyze the Android sample and output the web report.
14 Bytes
Binary file not shown.
14 Bytes
Binary file not shown.
14 Bytes
Binary file not shown.

docs/build/doctrees/dev.doctree

14 Bytes
Binary file not shown.
14 Bytes
Binary file not shown.
14 KB
Binary file not shown.

docs/build/doctrees/index.doctree

14 Bytes
Binary file not shown.
14 Bytes
Binary file not shown.

docs/build/html/_static/basic.css

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,6 @@ div.body p, div.body dd, div.body li, div.body blockquote {
236236
a.headerlink {
237237
visibility: hidden;
238238
}
239-
240239
a.brackets:before,
241240
span.brackets > a:before{
242241
content: "[";
@@ -247,6 +246,7 @@ span.brackets > a:after {
247246
content: "]";
248247
}
249248

249+
250250
h1:hover > a.headerlink,
251251
h2:hover > a.headerlink,
252252
h3:hover > a.headerlink,
@@ -334,13 +334,11 @@ aside.sidebar {
334334
p.sidebar-title {
335335
font-weight: bold;
336336
}
337-
338337
div.admonition, div.topic, blockquote {
339338
clear: left;
340339
}
341340

342341
/* -- topics ---------------------------------------------------------------- */
343-
344342
div.topic {
345343
border: 1px solid #ccc;
346344
padding: 7px;

0 commit comments

Comments
 (0)