Skip to content

Commit e5ef717

Browse files
authored
Introducing new team member Quark Script Agent (#37)
1 parent bb1689a commit e5ef717

File tree

5 files changed

+209
-22
lines changed

5 files changed

+209
-22
lines changed

README.md

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,53 @@
1-
# Quickstart Quark Script
1+
# Quark Script Agent
22

3-
In this tutorial, we will learn how to install and run Quark Script with a very easy example.
4-
We show how to detect CWE-798 in ovaa.apk.
3+
Introducing Quark's new member, the Quark Script Agent, the first AI assistant in the Quark team. This agent enables users to perform analyses using natural language, without the need for programming or scripting expertise, making the process simple and user-friendly.
54

6-
### STEP 1: Environments Requirements
7-
* Quark Script requires Python 3.8+
5+
The Quark Script Agent integrates with LangChain, which utilizes OpenAI's large language models to act as a bridge between natural language and the Quark Script API. LangChain defines the Quark Script API as a tool that large language models can understand and use. This means that users can easily call new analysis APIs using natural language commands by simply adding new tools as needed.
86

9-
### STEP 2: Install Quark Engine
10-
You can install Quark Engine by running:
11-
```
12-
pip3 install quark-engine
13-
```
7+
## Showcase: Detecting CWE-798 with Quark Script Agent
8+
Here's an example of using the Quark Script Agent with the `quarkScriptAgent.py`. This agent can currently detect [CWE-798](https://cwe.mitre.org/data/definitions/798.html) vulnerability in the [ovaa.apk](https://github.com/oversecured/ovaa). See the details below.
149

15-
### STEP 3: Prepare Quark Script, Detection Rule and the Sample File
16-
1. Get the CWE-798 Quark Script and the detection rule [here](https://quark-engine.readthedocs.io/en/latest/quark_script.html#detect-cwe-798-in-android-application-ovaa-apk).
17-
2. Get the sampe file (ovaa.apk) [here](https://github.com/dark-warlord14/ovaa/releases/tag/1.0).
18-
3. Put the script, detection rule, and sample file in the same directory.
19-
4. Edit accordingly to the file names:
20-
```python
21-
SAMPLE_PATH = "ovaa.apk"
22-
RULE_PATH = "findSecretKeySpec.json"
10+
### Quick Start
11+
12+
1. clone the repository:
13+
```
14+
git clone https://github.com/quark-engine/quark-script.git
15+
```
16+
17+
2. Install the required packages:
18+
```
19+
pip install -r requirements.txt
2320
```
2421

25-
### STEP 4: Run the script
22+
3. Run the script:
2623
```
27-
python3 CWE-798.py
24+
python quarkScriptAgent.py
2825
```
2926

30-
You should now see the detection result in the terminal:
27+
4. Result:
28+
29+
<img width="1440" alt="截圖 2024-07-26 下午3 39 12" src="https://github.com/user-attachments/assets/9c8ba9d3-c8b5-4583-8cb8-750f8c3bf2a7">
30+
31+
### Decode the Prompts
32+
Here are two prompts, each for executing different analysis processes.
33+
3134
```
32-
Found hard-coded AES key 49u5gh249gh24985ghf429gh4ch8f23f
35+
1st Prompt: Initialize the rule instance with the rule path set to "rule.json"
3336
```
37+
Used Quark Script APIs/Tools that LLM used: `Rule()`
38+
39+
```
40+
2nd Prompt: Run Quark Analysis using the rule instance on the apk sample "ovaa.apk",
41+
and Check if the parameters are hard-coded. If yes, display the hard-coded values.
42+
```
43+
Used Quark Script APIs/Tools that LLM used: `runQuarkAnalysis()`, `getParameterValues()` and `isHardCoded()`
44+
45+
The `Rule()`, `runQuarkAnalysis()`, `getParameterValues()`, and `isHardCoded()` functions are treated as **tools** within LangChain, enabling them to be invoked through the `gpt-4o` model to analyze and identify [CWE-798](https://cwe.mitre.org/data/definitions/798.html) vulnerabilities in the [ovaa.apk](https://github.com/oversecured/ovaa) sample.
46+
47+
<img width="829" alt="截圖 2024-07-26 下午9 25 23" src="https://github.com/user-attachments/assets/14de8563-e52e-4bdc-9960-ec73cbd10ada">
48+
49+
50+
* Notes:
51+
1. Since LangChain currently does not support passing Python instances between tools, we are temporarily using global variables to pass parameters between tools in `quarkScriptAgent.py`.
52+
2. Place the rules, samples, and `quarkScriptAgent.py` in the same folder; the LLM will automatically find files with matching names.
53+
3. A web GUI is under construction, please stay tuned!

ovaa.apk

1.64 MB
Binary file not shown.

quarkScriptAgent.py

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
import os
2+
import re
3+
4+
from termcolor import colored
5+
6+
from langchain_openai import ChatOpenAI
7+
from langchain.agents import tool, AgentExecutor
8+
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
9+
from langchain.agents.output_parsers.openai_tools import OpenAIToolsAgentOutputParser
10+
from langchain.agents.format_scratchpad.openai_tools import (
11+
format_to_openai_tool_messages,
12+
)
13+
14+
from quark.script import Rule, _getQuark, QuarkResult
15+
16+
if "OPENAI_API_KEY" not in os.environ:
17+
api_key = input("OpenAI API Key: ")
18+
os.environ["OPENAI_API_KEY"] = api_key
19+
20+
21+
@tool
22+
def loadRule(rulePath: str):
23+
"""
24+
Given a rule path,
25+
this instance loads a rule from the rule path.
26+
"""
27+
28+
global ruleInstance
29+
ruleInstance = Rule(rulePath)
30+
31+
return "Rule defined successfully"
32+
33+
34+
@tool
35+
def runQuarkAnalysis(samplePath: str):
36+
"""
37+
Given detection rule and target sample,
38+
this instance runs the Quark Analysis.
39+
"""
40+
41+
global ruleInstance
42+
global quarkResultInstance
43+
44+
quark = _getQuark(samplePath)
45+
quarkResultInstance = QuarkResult(quark, ruleInstance)
46+
47+
return "Quark analysis completed successfully"
48+
49+
50+
@tool
51+
def getBehaviorOccurList():
52+
"""
53+
Given the Quark analysis result,
54+
this instance extracts the behavior occurrence list.
55+
"""
56+
57+
global quarkResultInstance
58+
global behaviorOccurList
59+
60+
behaviorOccurList = quarkResultInstance.behaviorOccurList
61+
return "Behavior occurrence list extracted successfully"
62+
63+
64+
@tool
65+
def getParameterValues():
66+
"""
67+
Given the behavior occurrence list,
68+
this instance extracts the parameter values.
69+
"""
70+
71+
global behaviorOccurList
72+
global parameters
73+
74+
for behavior in behaviorOccurList:
75+
param = behavior.getParamValues()[1]
76+
77+
parameters = re.findall(r"\((.*?)\)", param)[1]
78+
79+
return "Parameter values extracted successfully"
80+
81+
82+
@tool
83+
def isHardCoded():
84+
"""
85+
Given the parameter values,
86+
this instance checks if the parameter values are hard-coded.
87+
"""
88+
89+
global parameters
90+
global quarkResultInstance
91+
92+
# check parameter values are hard-coded
93+
if parameters in quarkResultInstance.getAllStrings():
94+
return parameters
95+
96+
return False
97+
98+
99+
tools = [
100+
loadRule,
101+
runQuarkAnalysis,
102+
getBehaviorOccurList,
103+
getParameterValues,
104+
isHardCoded,
105+
]
106+
107+
108+
llm = ChatOpenAI(model="gpt-4o", temperature=0.1)
109+
llm_with_tools = llm.bind_tools(tools)
110+
111+
prompt = ChatPromptTemplate.from_messages([
112+
(
113+
"system",
114+
"You are very powerful assistant, but don't know current events",
115+
),
116+
("user", "{input}"),
117+
MessagesPlaceholder(variable_name="agent_scratchpad"),
118+
])
119+
120+
agent = (
121+
{
122+
"input": lambda x: x["input"],
123+
"agent_scratchpad": lambda x: format_to_openai_tool_messages(
124+
x["intermediate_steps"]
125+
),
126+
}
127+
| prompt
128+
| llm_with_tools
129+
| OpenAIToolsAgentOutputParser()
130+
)
131+
132+
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=False)
133+
134+
input_text = input(colored('User Input: ', 'green'))
135+
while input_text.lower() != 'bye':
136+
if input_text:
137+
response = agent_executor.invoke({
138+
'input': input_text,
139+
})
140+
print()
141+
print(colored('Agent: ', "cyan"), response['output'])
142+
print()
143+
144+
input_text = input(colored('User Input: ', 'green'))

requirement.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
termcolor==2.4.0
2+
langchain==0.2.11
3+
langchain-core==0.2.23
4+
langchain-openai==0.1.17
5+
quark-engine==24.7.1

rule.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"crime": "Detect APK using SecretKeySpec.",
3+
"permission": [],
4+
"api": [
5+
{
6+
"descriptor": "()[B",
7+
"class": "Ljava/lang/String;",
8+
"method": "getBytes"
9+
},
10+
{
11+
"descriptor": "([BLjava/lang/String;)V",
12+
"class": "Ljavax/crypto/spec/SecretKeySpec;",
13+
"method": "<init>"
14+
}
15+
],
16+
"score": 1,
17+
"label": []
18+
}

0 commit comments

Comments
 (0)