Skip to content

Commit c3d2ff8

Browse files
authored
Feat: LLM Honeypot allow specifying the custom prompt #152 (#153)
* implement new feature, custom prompt * Add doc for custom prompt
1 parent f1b35e9 commit c3d2ff8

File tree

7 files changed

+105
-22
lines changed

7 files changed

+105
-22
lines changed

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,25 @@ plugin:
250250
llmModel: "llama3"
251251
host: "http://example.com/api/chat" #default http://localhost:11434/api/chat
252252
```
253+
Example with custom prompt:
254+
255+
```yaml
256+
apiVersion: "v1"
257+
protocol: "ssh"
258+
address: ":2222"
259+
description: "SSH interactive OpenAI GPT-4"
260+
commands:
261+
- regex: "^(.+)$"
262+
plugin: "LLMHoneypot"
263+
serverVersion: "OpenSSH"
264+
serverName: "ubuntu"
265+
passwordRegex: "^(root|qwerty|Smoker666|123456|jenkins|minecraft|sinus|alex|postgres|Ly123456)$"
266+
deadlineTimeoutSeconds: 60
267+
plugin:
268+
llmModel: "gpt4-o"
269+
openAISecretKey: "sk-proj-123456"
270+
prompt: "You will act as an Ubuntu Linux terminal. The user will type commands, and you are to reply with what the terminal should show. Your responses must be contained within a single code block."
271+
```
253272
254273
###### SSH Honeypot on Port 22
255274

parser/configurations_parser.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ type Plugin struct {
5252
OpenAISecretKey string `yaml:"openAISecretKey"`
5353
Host string `yaml:"host"`
5454
LLMModel string `yaml:"llmModel"`
55+
Prompt string `yaml:"prompt"`
5556
}
5657

5758
// BeelzebubServiceConfiguration is the struct that contains the configurations of the honeypot service

parser/configurations_parser_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ plugin:
5858
openAISecretKey: "qwerty"
5959
llmModel: "llama3"
6060
host: "localhost:1563"
61+
prompt: "hello world"
6162
`)
6263
return beelzebubServiceConfiguration, nil
6364
}
@@ -133,6 +134,7 @@ func TestReadConfigurationsServicesValid(t *testing.T) {
133134
assert.Equal(t, firstBeelzebubServiceConfiguration.Plugin.OpenAISecretKey, "qwerty")
134135
assert.Equal(t, firstBeelzebubServiceConfiguration.Plugin.LLMModel, "llama3")
135136
assert.Equal(t, firstBeelzebubServiceConfiguration.Plugin.Host, "localhost:1563")
137+
assert.Equal(t, firstBeelzebubServiceConfiguration.Plugin.Prompt, "hello world")
136138
}
137139

138140
func TestGelAllFilesNameByDirName(t *testing.T) {

plugins/llm-integration.go

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,13 @@ const (
1919
)
2020

2121
type LLMHoneypot struct {
22-
Histories []Message
23-
OpenAIKey string
24-
client *resty.Client
25-
Protocol tracer.Protocol
26-
Model LLMModel
27-
Host string
22+
Histories []Message
23+
OpenAIKey string
24+
client *resty.Client
25+
Protocol tracer.Protocol
26+
Model LLMModel
27+
Host string
28+
CustomPrompt string
2829
}
2930

3031
type Choice struct {
@@ -211,8 +212,20 @@ func (llmHoneypot *LLMHoneypot) ollamaCaller(messages []Message) (string, error)
211212

212213
func (llmHoneypot *LLMHoneypot) ExecuteModel(command string) (string, error) {
213214
var err error
215+
var prompt []Message
214216

215-
prompt, err := buildPrompt(llmHoneypot.Histories, llmHoneypot.Protocol, command)
217+
if llmHoneypot.CustomPrompt != "" {
218+
prompt = append(prompt, Message{
219+
Role: SYSTEM.String(),
220+
Content: llmHoneypot.CustomPrompt,
221+
})
222+
prompt = append(prompt, Message{
223+
Role: USER.String(),
224+
Content: command,
225+
})
226+
} else {
227+
prompt, err = buildPrompt(llmHoneypot.Histories, llmHoneypot.Protocol, command)
228+
}
216229

217230
if err != nil {
218231
return "", err

plugins/llm-integration_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,51 @@ func TestBuildExecuteModelFailValidation(t *testing.T) {
5959
assert.Equal(t, "openAIKey is empty", err.Error())
6060
}
6161

62+
func TestBuildExecuteModelWithCustomPrompt(t *testing.T) {
63+
client := resty.New()
64+
httpmock.ActivateNonDefault(client.GetClient())
65+
defer httpmock.DeactivateAndReset()
66+
67+
// Given
68+
httpmock.RegisterMatcherResponder("POST", openAIGPTEndpoint,
69+
httpmock.BodyContainsString("hello world"),
70+
func(req *http.Request) (*http.Response, error) {
71+
resp, err := httpmock.NewJsonResponse(200, &Response{
72+
Choices: []Choice{
73+
{
74+
Message: Message{
75+
Role: SYSTEM.String(),
76+
Content: "[default]\nregion = us-west-2\noutput = json",
77+
},
78+
},
79+
},
80+
})
81+
if err != nil {
82+
return httpmock.NewStringResponse(500, ""), nil
83+
}
84+
return resp, nil
85+
},
86+
)
87+
88+
llmHoneypot := LLMHoneypot{
89+
Histories: make([]Message, 0),
90+
OpenAIKey: "sdjdnklfjndslkjanfk",
91+
Protocol: tracer.HTTP,
92+
Model: GPT4O,
93+
CustomPrompt: "hello world",
94+
}
95+
96+
openAIGPTVirtualTerminal := InitLLMHoneypot(llmHoneypot)
97+
openAIGPTVirtualTerminal.client = client
98+
99+
//When
100+
str, err := openAIGPTVirtualTerminal.ExecuteModel("GET /.aws/credentials")
101+
102+
//Then
103+
assert.Nil(t, err)
104+
assert.Equal(t, "[default]\nregion = us-west-2\noutput = json", str)
105+
}
106+
62107
func TestBuildExecuteModelFailValidationStrategyType(t *testing.T) {
63108

64109
llmHoneypot := LLMHoneypot{

protocols/strategies/http.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,12 @@ func (httpStrategy HTTPStrategy) Init(beelzebubServiceConfiguration parser.Beelz
4545
}
4646

4747
llmHoneypot := plugins.LLMHoneypot{
48-
Histories: make([]plugins.Message, 0),
49-
OpenAIKey: beelzebubServiceConfiguration.Plugin.OpenAISecretKey,
50-
Protocol: tracer.HTTP,
51-
Host: beelzebubServiceConfiguration.Plugin.Host,
52-
Model: llmModel,
48+
Histories: make([]plugins.Message, 0),
49+
OpenAIKey: beelzebubServiceConfiguration.Plugin.OpenAISecretKey,
50+
Protocol: tracer.HTTP,
51+
Host: beelzebubServiceConfiguration.Plugin.Host,
52+
Model: llmModel,
53+
CustomPrompt: beelzebubServiceConfiguration.Plugin.Prompt,
5354
}
5455

5556
llmHoneypotInstance := plugins.InitLLMHoneypot(llmHoneypot)

protocols/strategies/ssh.go

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,12 @@ func (sshStrategy *SSHStrategy) Init(beelzebubServiceConfiguration parser.Beelze
5252
}
5353

5454
llmHoneypot := plugins.LLMHoneypot{
55-
Histories: make([]plugins.Message, 0),
56-
OpenAIKey: beelzebubServiceConfiguration.Plugin.OpenAISecretKey,
57-
Protocol: tracer.SSH,
58-
Host: beelzebubServiceConfiguration.Plugin.Host,
59-
Model: llmModel,
55+
Histories: make([]plugins.Message, 0),
56+
OpenAIKey: beelzebubServiceConfiguration.Plugin.OpenAISecretKey,
57+
Protocol: tracer.SSH,
58+
Host: beelzebubServiceConfiguration.Plugin.Host,
59+
Model: llmModel,
60+
CustomPrompt: beelzebubServiceConfiguration.Plugin.Prompt,
6061
}
6162

6263
llmHoneypotInstance := plugins.InitLLMHoneypot(llmHoneypot)
@@ -137,11 +138,12 @@ func (sshStrategy *SSHStrategy) Init(beelzebubServiceConfiguration parser.Beelze
137138
}
138139

139140
llmHoneypot := plugins.LLMHoneypot{
140-
Histories: histories,
141-
OpenAIKey: beelzebubServiceConfiguration.Plugin.OpenAISecretKey,
142-
Protocol: tracer.SSH,
143-
Host: beelzebubServiceConfiguration.Plugin.Host,
144-
Model: llmModel,
141+
Histories: histories,
142+
OpenAIKey: beelzebubServiceConfiguration.Plugin.OpenAISecretKey,
143+
Protocol: tracer.SSH,
144+
Host: beelzebubServiceConfiguration.Plugin.Host,
145+
Model: llmModel,
146+
CustomPrompt: beelzebubServiceConfiguration.Plugin.Prompt,
145147
}
146148

147149
llmHoneypotInstance := plugins.InitLLMHoneypot(llmHoneypot)

0 commit comments

Comments
 (0)