mirror of
https://github.com/mariocandela/beelzebub.git
synced 2025-07-01 18:47:26 -04:00
Feat: add LMM Honeypot HTTP Server (#110)
* add LMM Honeypot HTTP Server * improve unit test code coverage * integrate LLM plugin into http honeypot strategy * improve code coverage * fix typos * improve OpenAI plugin with gpt-4, adpt new API amd map new object
This commit is contained in:
@ -3,58 +3,63 @@ package plugins
|
||||
import (
|
||||
"github.com/go-resty/resty/v2"
|
||||
"github.com/jarcoal/httpmock"
|
||||
"github.com/mariocandela/beelzebub/v3/tracer"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"net/http"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const SystemPromptLen = 4
|
||||
|
||||
func TestBuildPromptEmptyHistory(t *testing.T) {
|
||||
//Given
|
||||
var histories []History
|
||||
var histories []Message
|
||||
command := "pwd"
|
||||
|
||||
//When
|
||||
prompt := buildPrompt(histories, command)
|
||||
prompt, err := buildPrompt(histories, tracer.SSH, command)
|
||||
|
||||
//Then
|
||||
assert.Equal(t,
|
||||
"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. Do not provide explanations or type commands unless explicitly instructed by the user. Remember previous commands and consider their effects on subsequent outputs.\n\nA:pwd\n\nQ:/home/user\n\nA:pwd\n\nQ:",
|
||||
prompt)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, SystemPromptLen, len(prompt))
|
||||
}
|
||||
|
||||
func TestBuildPromptWithHistory(t *testing.T) {
|
||||
//Given
|
||||
var histories = []History{
|
||||
var histories = []Message{
|
||||
{
|
||||
Input: "cat hello.txt",
|
||||
Output: "world",
|
||||
},
|
||||
{
|
||||
Input: "echo 1234",
|
||||
Output: "1234",
|
||||
Role: "cat hello.txt",
|
||||
Content: "world",
|
||||
},
|
||||
}
|
||||
|
||||
command := "pwd"
|
||||
|
||||
//When
|
||||
prompt := buildPrompt(histories, command)
|
||||
prompt, err := buildPrompt(histories, tracer.SSH, command)
|
||||
|
||||
//Then
|
||||
assert.Equal(t,
|
||||
"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. Do not provide explanations or type commands unless explicitly instructed by the user. Remember previous commands and consider their effects on subsequent outputs.\n\nA:pwd\n\nQ:/home/user\n\nA:cat hello.txt\n\nQ:world\n\nA:echo 1234\n\nQ:1234\n\nA:pwd\n\nQ:",
|
||||
prompt)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, SystemPromptLen+1, len(prompt))
|
||||
}
|
||||
|
||||
func TestBuildGetCompletionsFailValidation(t *testing.T) {
|
||||
openAIGPTVirtualTerminal := Init(make([]History, 0), "")
|
||||
openAIGPTVirtualTerminal := Init(make([]Message, 0), "", tracer.SSH)
|
||||
|
||||
_, err := openAIGPTVirtualTerminal.GetCompletions("test")
|
||||
|
||||
assert.Equal(t, "openAIKey is empty", err.Error())
|
||||
}
|
||||
|
||||
func TestBuildGetCompletionsWithResults(t *testing.T) {
|
||||
func TestBuildGetCompletionsFailValidationStrategyType(t *testing.T) {
|
||||
openAIGPTVirtualTerminal := Init(make([]Message, 0), "", tracer.TCP)
|
||||
|
||||
_, err := openAIGPTVirtualTerminal.GetCompletions("test")
|
||||
|
||||
assert.Equal(t, "no prompt for protocol selected", err.Error())
|
||||
}
|
||||
|
||||
func TestBuildGetCompletionsSSHWithResults(t *testing.T) {
|
||||
client := resty.New()
|
||||
httpmock.ActivateNonDefault(client.GetClient())
|
||||
defer httpmock.DeactivateAndReset()
|
||||
@ -65,7 +70,10 @@ func TestBuildGetCompletionsWithResults(t *testing.T) {
|
||||
resp, err := httpmock.NewJsonResponse(200, &gptResponse{
|
||||
Choices: []Choice{
|
||||
{
|
||||
Text: "prova.txt",
|
||||
Message: Message{
|
||||
Role: SYSTEM.String(),
|
||||
Content: "prova.txt",
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
@ -76,7 +84,7 @@ func TestBuildGetCompletionsWithResults(t *testing.T) {
|
||||
},
|
||||
)
|
||||
|
||||
openAIGPTVirtualTerminal := Init(make([]History, 0), "sdjdnklfjndslkjanfk")
|
||||
openAIGPTVirtualTerminal := Init(make([]Message, 0), "sdjdnklfjndslkjanfk", tracer.SSH)
|
||||
openAIGPTVirtualTerminal.client = client
|
||||
|
||||
//When
|
||||
@ -87,7 +95,7 @@ func TestBuildGetCompletionsWithResults(t *testing.T) {
|
||||
assert.Equal(t, "prova.txt", str)
|
||||
}
|
||||
|
||||
func TestBuildGetCompletionsWithoutResults(t *testing.T) {
|
||||
func TestBuildGetCompletionsSSHWithoutResults(t *testing.T) {
|
||||
client := resty.New()
|
||||
httpmock.ActivateNonDefault(client.GetClient())
|
||||
defer httpmock.DeactivateAndReset()
|
||||
@ -105,7 +113,7 @@ func TestBuildGetCompletionsWithoutResults(t *testing.T) {
|
||||
},
|
||||
)
|
||||
|
||||
openAIGPTVirtualTerminal := Init(make([]History, 0), "sdjdnklfjndslkjanfk")
|
||||
openAIGPTVirtualTerminal := Init(make([]Message, 0), "sdjdnklfjndslkjanfk", tracer.SSH)
|
||||
openAIGPTVirtualTerminal.client = client
|
||||
|
||||
//When
|
||||
@ -114,3 +122,67 @@ func TestBuildGetCompletionsWithoutResults(t *testing.T) {
|
||||
//Then
|
||||
assert.Equal(t, "no choices", err.Error())
|
||||
}
|
||||
|
||||
func TestBuildGetCompletionsHTTPWithResults(t *testing.T) {
|
||||
client := resty.New()
|
||||
httpmock.ActivateNonDefault(client.GetClient())
|
||||
defer httpmock.DeactivateAndReset()
|
||||
|
||||
// Given
|
||||
httpmock.RegisterResponder("POST", openAIGPTEndpoint,
|
||||
func(req *http.Request) (*http.Response, error) {
|
||||
resp, err := httpmock.NewJsonResponse(200, &gptResponse{
|
||||
Choices: []Choice{
|
||||
{
|
||||
Message: Message{
|
||||
Role: SYSTEM.String(),
|
||||
Content: "[default]\nregion = us-west-2\noutput = json",
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return httpmock.NewStringResponse(500, ""), nil
|
||||
}
|
||||
return resp, nil
|
||||
},
|
||||
)
|
||||
|
||||
openAIGPTVirtualTerminal := Init(make([]Message, 0), "sdjdnklfjndslkjanfk", tracer.HTTP)
|
||||
openAIGPTVirtualTerminal.client = client
|
||||
|
||||
//When
|
||||
str, err := openAIGPTVirtualTerminal.GetCompletions("GET /.aws/credentials")
|
||||
|
||||
//Then
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "[default]\nregion = us-west-2\noutput = json", str)
|
||||
}
|
||||
|
||||
func TestBuildGetCompletionsHTTPWithoutResults(t *testing.T) {
|
||||
client := resty.New()
|
||||
httpmock.ActivateNonDefault(client.GetClient())
|
||||
defer httpmock.DeactivateAndReset()
|
||||
|
||||
// Given
|
||||
httpmock.RegisterResponder("POST", openAIGPTEndpoint,
|
||||
func(req *http.Request) (*http.Response, error) {
|
||||
resp, err := httpmock.NewJsonResponse(200, &gptResponse{
|
||||
Choices: []Choice{},
|
||||
})
|
||||
if err != nil {
|
||||
return httpmock.NewStringResponse(500, ""), nil
|
||||
}
|
||||
return resp, nil
|
||||
},
|
||||
)
|
||||
|
||||
openAIGPTVirtualTerminal := Init(make([]Message, 0), "sdjdnklfjndslkjanfk", tracer.HTTP)
|
||||
openAIGPTVirtualTerminal.client = client
|
||||
|
||||
//When
|
||||
_, err := openAIGPTVirtualTerminal.GetCompletions("GET /.aws/credentials")
|
||||
|
||||
//Then
|
||||
assert.Equal(t, "no choices", err.Error())
|
||||
}
|
||||
|
Reference in New Issue
Block a user