Skip to content

Commit 22bc792

Browse files
authored
Jclass scanner hotfix (#800)
1 parent e9dc3d1 commit 22bc792

File tree

9 files changed

+110
-17
lines changed

9 files changed

+110
-17
lines changed

.github/workflows/check.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ jobs:
9292
run: |
9393
banner="$(python -m credsweeper --banner | head -1)"
9494
echo "banner = '${banner}'"
95-
if [ "CredSweeper 1.14.1 crc32:5aa3f35d" != "${banner}" ]; then
95+
if [ "CredSweeper 1.14.2 crc32:36ab773c" != "${banner}" ]; then
9696
echo "Update the check for '${banner}'"
9797
exit 1
9898
fi

credsweeper/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,4 @@
2424
"__version__"
2525
]
2626

27-
__version__ = "1.14.1"
27+
__version__ = "1.14.2"

credsweeper/deep_scanner/jclass_scanner.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from abc import ABC
55
from typing import List, Optional
66

7-
from credsweeper.common.constants import MIN_DATA_LEN, UTF_8
7+
from credsweeper.common.constants import UTF_8
88
from credsweeper.credentials.candidate import Candidate
99
from credsweeper.deep_scanner.abstract_scanner import AbstractScanner
1010
from credsweeper.file_handler.data_content_provider import DataContentProvider
@@ -25,24 +25,26 @@ def u2(stream: io.BytesIO) -> int:
2525
def get_utf8_constants(stream: io.BytesIO) -> List[str]:
2626
"""Extracts only Utf8 constants from java ClassFile"""
2727
result = []
28-
item_count = JclassScanner.u2(stream)
29-
while 0 < item_count:
30-
# actual number of items is one less!
31-
item_count -= 1
28+
# actual number of items is one less!
29+
items_counter = JclassScanner.u2(stream) - 1
30+
while 0 < items_counter:
31+
items_counter -= 1
3232
# uint8
3333
tag = int(stream.read(1)[0])
3434
if 1 == tag:
35+
# UTF-8 string in bytes may be bigger than in characters
3536
length = JclassScanner.u2(stream)
3637
data = stream.read(int(length))
37-
if MIN_DATA_LEN <= length:
38-
value = data.decode(encoding=UTF_8, errors="replace")
39-
result.append(value)
38+
value = data.decode(encoding=UTF_8, errors="replace")
39+
result.append(value)
4040
elif tag in (3, 4, 9, 10, 11, 12, 18):
4141
_ = stream.read(4)
4242
elif tag in (7, 8, 16):
4343
_ = stream.read(2)
4444
elif tag in (5, 6):
4545
_ = stream.read(8)
46+
# long and double types use two indexes
47+
items_counter -= 1
4648
elif 15 == tag:
4749
_ = stream.read(3)
4850
else:

tests/data/depth_3_pedantic.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@
124124
"line": "MIIBOgIBAAJBAL1/hJjtuMbjbVXo6wYT1SxiROOvwgffVSvOAk5aN2d4wYTC25k3sklfpdwxvkjh4iGB6/qC+0RbmiLwaXaQT0ECAwEAAQJAeAlQyza6t3HVDnhud/kULftJvBjXhfkYkJj8qPlI40dn/Tnwe6mywfly6hOvAn4TRBsnB/Eln6hJLmCrDvZvyQIhAPf7Uma4/Aqgoz3SfPyz9TaQXyD5JSC3ej7cOH7b3hgTAiEAw6AYhc/UKh8iIAPYGK15ImVmXAlxmhFD6xCWx9bcTdsCIQDiqOayWZaWKCnNEh2H5PzW+LLasp9K/ilQV32UBmdD3QIgbafQFzHoO7Q37Lo655pVzHIKbozcoQAMkjc6TcqiswECIBvXLFj5jkNs4iSqphZo8eISUdol/9Zo/dkrHC41kbYJ",
125125
"line_num": 0,
126126
"path": "./tests/samples/Sample.class",
127-
"info": "FILE:./tests/samples/Sample.class|Java.65.0|STRING:4|BASE64|PKCS_PASSWORD:None",
127+
"info": "FILE:./tests/samples/Sample.class|Java.65.0|STRING:21|BASE64|PKCS_PASSWORD:None",
128128
"variable": null,
129129
"variable_start": -2,
130130
"variable_end": -2,
@@ -145,7 +145,7 @@
145145
"line": "MIIBvTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIT0gWHcAV1rACAggAMAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBBaZ0qE6fJsz9rDPoa2esruBIIBYF9QvKgDLA15MgXR8P73DRdrDJzEEoYe7bDtk+vnTzy6DNVwSfkgQLNLpKfnjPO3b1szG5md06Fai6Tuuc9kKDhaCWfGgw/xAeb4OEjWupyCUvmyWYBNqCC+DDQZb7ccka4cuIRV7Ty0I/3AdGCZ/g4mDBozjtfLkLOvWzRuKXQYvGlPYd0HUWupKn2SgduyrwKt43zq0j+t9UXMMFVYv7RZOzZruVcUkBKHoYDkgOl9OQ5tGE+atfhLZUVUKj4Q7F+o6mlTy0JHxv94oUadDXJCyzivdes2RxabPDJ+1gEfNW8ZRZtselC+Pdy+KBItLn3f3FEWXpWbNPRzhElOUUaNgRNOQrmxoE09QxWLt8L3soArRfWe732Nw7N9izpUuKmL72bzbpetDQu/sn49CEnWcFGCZQ9inSiEogF0e2ncxnKfthRKzpT3K5JGiqcMmbcMoz5WjLks//PgWcZ/l2o=",
146146
"line_num": 0,
147147
"path": "./tests/samples/Sample.class",
148-
"info": "FILE:./tests/samples/Sample.class|Java.65.0|STRING:7|BASE64|PKCS_PASSWORD:b'changeme'",
148+
"info": "FILE:./tests/samples/Sample.class|Java.65.0|STRING:25|BASE64|PKCS_PASSWORD:b'changeme'",
149149
"variable": null,
150150
"variable_start": -2,
151151
"variable_end": -2,
@@ -166,7 +166,7 @@
166166
"line": "MIIBOgIBAAJBAL1/hJjtuMbjbVXo6wYT1SxiROOvwgffVSvOAk5aN2d4wYTC25k3sklfpdwxvkjh4iGB6/qC+0RbmiLwaXaQT0ECAwEAAQJAeAlQyza6t3HVDnhud/kULftJvBjXhfkYkJj8qPlI40dn/Tnwe6mywfly6hOvAn4TRBsnB/Eln6hJLmCrDvZvyQIhAPf7Uma4/Aqgoz3SfPyz9TaQXyD5JSC3ej7cOH7b3hgTAiEAw6AYhc/UKh8iIAPYGK15ImVmXAlxmhFD6xCWx9bcTdsCIQDiqOayWZaWKCnNEh2H5PzW+LLasp9K/ilQV32UBmdD3QIgbafQFzHoO7Q37Lo655pVzHIKbozcoQAMkjc6TcqiswECIBvXLFj5jkNs4iSqphZo8eISUdol/9Zo/dkrHC41kbYJ",
167167
"line_num": 1,
168168
"path": "./tests/samples/Sample.class",
169-
"info": "FILE:./tests/samples/Sample.class|Java.65.0|STRING:4|RAW",
169+
"info": "FILE:./tests/samples/Sample.class|Java.65.0|STRING:21|RAW",
170170
"variable": null,
171171
"variable_start": -2,
172172
"variable_end": -2,

tests/data/no_filters_no_ml.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
"line_data_list": [
5050
{
5151
"line": " final byte [] pkey = Base64.getMimeDecoder().decode(",
52-
"line_num": 4,
52+
"line_num": 35,
5353
"path": "./tests/samples/Sample.java",
5454
"info": "",
5555
"variable": "pkey",
@@ -70,7 +70,7 @@
7070
"line_data_list": [
7171
{
7272
"line": " final byte [] pkey = Base64.getMimeDecoder().decode(text);",
73-
"line_num": 26,
73+
"line_num": 58,
7474
"path": "./tests/samples/Sample.java",
7575
"info": "",
7676
"variable": "pkey",
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import base64
2+
import io
3+
import unittest
4+
5+
from credsweeper.deep_scanner.jclass_scanner import JclassScanner
6+
from tests import AZ_DATA
7+
8+
SAMPLE_B64 = """
9+
yv66vgAAAEEAaQoAAgADBwAEDAAFAAYBABBqYXZhL2xhbmcvT2JqZWN0AQAGPGluaXQ+AQADKClWEgAAAAgMAAkACgEAA3J1bgEAFigpTGphdmEvbGFuZy9S
10+
dW5uYWJsZTsLAAwADQcADgwACQAGAQASamF2YS9sYW5nL1J1bm5hYmxlCQAQABEHABIMABMAFAEAEGphdmEvbGFuZy9TeXN0ZW0BAANvdXQBABVMamF2YS9p
11+
by9QcmludFN0cmVhbTsHABYBAAZTYW1wbGUKABgAGQcAGgwAGwAcAQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4BAAQoWilWCgAYAB4MABsAHwEA
12+
BChDKVYIACEBACRiYWNlNGQxOS1iZWVmLWNhZmUtY29vMS05MTI5NDc0YmNkODEKABgAIwwAGwAkAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWBQAAAAB3NhXZ
13+
CgAYACgMABsAKQEABChKKVYGQBdu4XWCSM4KABgALQwAGwAuAQAEKEQpVgoAFQADCgAVAA0IAAkBAAxKQVZBX0JPT0xFQU4BAAFaAQANQ29uc3RhbnRWYWx1
14+
ZQMAAAABAQAJSkFWQV9DSEFSAQABQwMAAABYAQAJSkFWQV9CWVRFAQABQgMAAAB7AQAKSkFXQV9TSE9SVAEAAVMDAAABXgEACEpBVkFfSU5UAQABSQMAAIAA
15+
AQAJSkFWQV9MT05HAQABSgUAAAAAdzWUAAEACkpBVkFfRkxPQVQBAAFGBEBI9cMBAAtKQVZBX0RPVUJMRQEAAUQGQAW/CosEkZsBAAtKQVZBX1NUUklORwEA
16+
EkxqYXZhL2xhbmcvU3RyaW5nOwEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAANsb2cBAARtYWluAQAWKFtMamF2YS9sYW5nL1N0cmluZzspVgEADGxhbWJk
17+
YSRydW4kMAEAClNvdXJjZUZpbGUBAAtTYW1wbGUuamF2YQEAEEJvb3RzdHJhcE1ldGhvZHMQAAYPBgBaCgAVAFsMAFQABg8GAF0KAF4AXwcAYAwAYQBiAQAi
18+
amF2YS9sYW5nL2ludm9rZS9MYW1iZGFNZXRhZmFjdG9yeQEAC21ldGFmYWN0b3J5AQDMKExqYXZhL2xhbmcvaW52b2tlL01ldGhvZEhhbmRsZXMkTG9va3Vw
19+
O0xqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvaW52b2tlL01ldGhvZFR5cGU7TGphdmEvbGFuZy9pbnZva2UvTWV0aG9kVHlwZTtMamF2YS9sYW5nL2lu
20+
dm9rZS9NZXRob2RIYW5kbGU7TGphdmEvbGFuZy9pbnZva2UvTWV0aG9kVHlwZTspTGphdmEvbGFuZy9pbnZva2UvQ2FsbFNpdGU7AQAMSW5uZXJDbGFzc2Vz
21+
BwBlAQAlamF2YS9sYW5nL2ludm9rZS9NZXRob2RIYW5kbGVzJExvb2t1cAcAZwEAHmphdmEvbGFuZy9pbnZva2UvTWV0aG9kSGFuZGxlcwEABkxvb2t1cAAh
22+
ABUAAgABAAwACQAaADIAMwABADQAAAACADUAGgA2ADcAAQA0AAAAAgA4ABoAOQA6AAEANAAAAAIAOwAaADwAPQABADQAAAACAD4AGgA/AEAAAQA0AAAAAgBB
23+
ABoAQgBDAAEANAAAAAIARAAaAEYARwABADQAAAACAEgAGgBJAEoAAQA0AAAAAgBLABoATQBOAAEANAAAAAIAIAAFAAEABQAGAAEATwAAAB0AAQABAAAABSq3
24+
AAGxAAAAAQBQAAAABgABAAAABAABAAkABgABAE8AAAAtAAEAAgAAAA26AAcAAEwruQALAQCxAAAAAQBQAAAADgADAAAAEgAGABMADAAUAAEAUQAGAAEATwAA
25+
AFYAAwABAAAAKrIADwS2ABeyAA8QWLYAHbIADxIgtgAisgAPFAAltgAnsgAPFAAqtgAssQAAAAEAUAAAABoABgAAABcABwAYAA8AGQAXABoAIAAbACkAHAAJ
26+
AFIAUwABAE8AAAAnAAIAAQAAAAu7ABVZtwAvtgAwsQAAAAEAUAAAAAoAAgAAAB8ACgAgEAoAVAAGAAEATwAAACEAAgAAAAAACbIADxIxtgAisQAAAAEAUAAA
27+
AAYAAQAAABIAAwBVAAAAAgBWAFcAAAAMAAEAXAADAFgAWQBYAGMAAAAKAAEAZABmAGgAGQ==
28+
"""
29+
30+
31+
class TestJclassScanner(unittest.TestCase):
32+
33+
def setUp(self):
34+
self.maxDiff = None
35+
36+
def test_get_utf8_constants_n(self):
37+
with self.assertRaises(AttributeError):
38+
JclassScanner.get_utf8_constants(None)
39+
with self.assertRaises(Exception):
40+
JclassScanner.get_utf8_constants(io.BytesIO(b''))
41+
self.assertListEqual([], JclassScanner.get_utf8_constants(io.BytesIO(AZ_DATA)))
42+
43+
def test_get_utf8_constants_p(self):
44+
data = base64.b64decode(SAMPLE_B64)
45+
self.assertListEqual([
46+
'java/lang/Object', '<init>', '()V', 'run', '()Ljava/lang/Runnable;', 'java/lang/Runnable',
47+
'java/lang/System', 'out', 'Ljava/io/PrintStream;', 'Sample', 'java/io/PrintStream', 'println', '(Z)V',
48+
'(C)V', 'bace4d19-beef-cafe-coo1-9129474bcd81', '(Ljava/lang/String;)V', '(J)V', '(D)V', 'JAVA_BOOLEAN',
49+
'Z', 'ConstantValue', 'JAVA_CHAR', 'C', 'JAVA_BYTE', 'B', 'JAWA_SHORT', 'S', 'JAVA_INT', 'I', 'JAVA_LONG',
50+
'J', 'JAVA_FLOAT', 'F', 'JAVA_DOUBLE', 'D', 'JAVA_STRING', 'Ljava/lang/String;', 'Code', 'LineNumberTable',
51+
'log', 'main', '([Ljava/lang/String;)V', 'lambda$run$0', 'SourceFile', 'Sample.java', 'BootstrapMethods',
52+
'java/lang/invoke/LambdaMetafactory', 'metafactory',
53+
('(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;'
54+
'Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;'
55+
')Ljava/lang/invoke/CallSite;'), 'InnerClasses', 'java/lang/invoke/MethodHandles$Lookup',
56+
'java/lang/invoke/MethodHandles', 'Lookup'
57+
], JclassScanner.get_utf8_constants(io.BytesIO(data[8:])))

tests/samples/Sample.class

1.43 KB
Binary file not shown.

tests/samples/Sample.java

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,36 @@
11
import java.util.Base64;
2-
public class Sample {
2+
import java.util.function.Consumer;
3+
4+
public class Sample implements Runnable {
5+
6+
private static final boolean JAVA_BOOLEAN = true;
7+
private static final char JAVA_CHAR = 'X';
8+
private static final byte JAVA_BYTE = 123;
9+
private static final short JAWA_SHORT = 350;
10+
private static final int JAVA_INT = 32768;
11+
private static final long JAVA_LONG = 2000000000L;
12+
private static final float JAVA_FLOAT = 3.14f;
13+
private static final double JAVA_DOUBLE = 2.718281828;
14+
private static final String JAVA_STRING = "bace4d19-beef-cafe-coo1-9129474bcd81";
15+
16+
@Override
17+
public void run() {
18+
Runnable r = () -> System.out.println("run");
19+
r.run();
20+
}
21+
22+
public void log() {
23+
System.out.println(JAVA_BOOLEAN);
24+
System.out.println(JAVA_CHAR);
25+
System.out.println(JAVA_STRING);
26+
System.out.println(JAVA_BYTE + JAWA_SHORT + JAVA_INT + JAVA_LONG);
27+
System.out.println(JAVA_FLOAT + JAVA_DOUBLE);
28+
}
29+
30+
public static void main(String[] args) {
31+
new Sample().run();
32+
}
33+
334
private static byte [] getPrivateKey1() {
435
final byte [] pkey = Base64.getMimeDecoder().decode(
536
"MIIBOgIBAAJBAL1/hJjtuMbjbVXo6wYT1SxiROOvwgffVSvOAk5aN2d4wYTC25k3"+
@@ -11,6 +42,7 @@ public class Sample {
1142
"LFj5jkNs4iSqphZo8eISUdol/9Zo/dkrHC41kbYJ");
1243
return pkey;
1344
}
45+
1446
private static byte [] getPrivateKey8() {
1547
final String text =
1648
"MIIBvTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIT0gWHcAV1rACAggA\n"+
@@ -26,6 +58,7 @@ public class Sample {
2658
final byte [] pkey = Base64.getMimeDecoder().decode(text);
2759
return pkey;
2860
}
61+
2962
public static byte[] get(boolean encryption){
3063
if (encryption) {
3164
return Sample.getPrivateKey8();
@@ -34,4 +67,5 @@ public static byte[] get(boolean encryption){
3467
}
3568
}
3669
}
70+
3771
/* javac Sample.java && javap -c -l -p -v -s Sample.class */

tests/test_app.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ def test_depth_p(self) -> None:
492492
cvs_checksum = hashlib.md5(f.read()).digest()
493493
checksum = bytes(a ^ b for a, b in zip(checksum, cvs_checksum))
494494
# update the checksum manually and keep line endings in the samples as is (git config core.autocrlf false)
495-
self.assertEqual("bffe4dc7750fc983b31c33fc0f67bbb2", binascii.hexlify(checksum).decode())
495+
self.assertEqual("4a12fce9d4c17e6b3aaef0f4be070225", binascii.hexlify(checksum).decode())
496496
normal_report = []
497497
sorted_report = []
498498
with tempfile.TemporaryDirectory() as tmp_dir:

0 commit comments

Comments
 (0)