Skip to content

Commit 308de96

Browse files
committed
fix(parser): replace packet size rejection with warning on receive
Server parser no longer rejects large packets from implants. Instead it logs a warning and accepts the data. This prevents session disconnection when exec output or other task results exceed the configured packet_length. The packet_length limit remains meaningful for the sending side (implant controls its own packet size), but the receiving side should accept whatever arrives successfully over the wire. Also adds xor_bytes builtin function for Lua scripts (used by onedrive pull XOR decryption).
1 parent 63b33da commit 308de96

3 files changed

Lines changed: 40 additions & 9 deletions

File tree

helper/intermediate/builtin.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,4 +530,30 @@ format_path("C:\\Windows\\System32\\calc.exe")
530530
},
531531
Example: `parse_hex("0x1f04")`,
532532
})
533+
534+
RegisterFunction("xor_bytes", func(data string, key string) (string, error) {
535+
if len(key) == 0 {
536+
return data, nil
537+
}
538+
buf := []byte(data)
539+
keyBytes := []byte(key)
540+
for i := range buf {
541+
buf[i] ^= keyBytes[i%len(keyBytes)]
542+
}
543+
return string(buf), nil
544+
})
545+
AddHelper(
546+
"xor_bytes",
547+
&mals.Helper{
548+
Group: EncodeGroup,
549+
Short: "XOR data with a repeating key",
550+
Input: []string{
551+
"data: raw bytes as string",
552+
"key: XOR key",
553+
},
554+
Output: []string{
555+
"string",
556+
},
557+
Example: `xor_bytes(data, "mykey")`,
558+
})
533559
}

server/internal/parser/malefic/parser.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,10 @@ func (parser *MaleficParser) readHeader(conn io.ReadWriteCloser) (uint32, uint32
104104
}
105105
sessionId := ParseSid(header)
106106
length := binary.LittleEndian.Uint32(header[MsgSessionEnd:])
107-
if length > parser.maxPacketLen()+consts.KB*16 {
108-
return 0, 0, fmt.Errorf("%w,expect: %d, recv: %d", types.ErrPacketTooLarge, parser.maxPacketLen(), length)
107+
maxLen := parser.maxPacketLen()
108+
if maxLen > 0 && length > maxLen+consts.KB*16 {
109+
logs.Log.Warnf("[parser] large packet from session %x: %d bytes (limit %d), accepting anyway",
110+
sessionId, length, maxLen)
109111
}
110112

111113
return sessionId, length + 1, nil
@@ -116,10 +118,6 @@ func (parser *MaleficParser) ReadHeader(conn io.ReadWriteCloser) (uint32, uint32
116118
if err != nil {
117119
return 0, 0, err
118120
}
119-
//logs.Log.Debugf("%v read packet from %s , %d bytes", sid, conn.RemoteAddr(), length)
120-
if length > parser.maxPacketLen()+consts.KB*16+1 {
121-
return 0, 0, fmt.Errorf("%w,expect: %d, recv: %d", types.ErrPacketTooLarge, parser.maxPacketLen(), length)
122-
}
123121
return sid, length, nil
124122
}
125123

server/internal/parser/malefic/parser_test.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,16 @@ func TestMaleficParser_ReadHeader_PacketTooLarge(t *testing.T) {
7878
header := buildHeader(DefaultStartDelimiter, 1, hugeLen)
7979

8080
buf := &rwcBuf{bytes.NewBuffer(header)}
81-
_, _, err := p.ReadHeader(buf)
82-
if !errors.Is(err, types.ErrPacketTooLarge) {
83-
t.Fatalf("expected ErrPacketTooLarge, got %v", err)
81+
sid, length, err := p.ReadHeader(buf)
82+
// Large packets are now accepted with a warning, not rejected
83+
if err != nil {
84+
t.Fatalf("expected large packet to be accepted, got error: %v", err)
85+
}
86+
if sid != 1 {
87+
t.Fatalf("expected session_id=1, got %d", sid)
88+
}
89+
if length == 0 {
90+
t.Fatal("expected non-zero length")
8491
}
8592
}
8693

0 commit comments

Comments
 (0)