rosetta-ce 1.6.4__tar.gz → 1.6.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of rosetta-ce might be problematic. Click here for more details.
- {rosetta-ce-1.6.4/rosetta_ce.egg-info → rosetta_ce-1.6.7}/PKG-INFO +4 -1
- rosetta_ce-1.6.7/rosetta/constants/db.py +92 -0
- {rosetta-ce-1.6.4 → rosetta_ce-1.6.7}/rosetta/rfaker.py +44 -28
- {rosetta-ce-1.6.4 → rosetta_ce-1.6.7/rosetta_ce.egg-info}/PKG-INFO +4 -1
- {rosetta-ce-1.6.4 → rosetta_ce-1.6.7}/rosetta_ce.egg-info/SOURCES.txt +1 -0
- {rosetta-ce-1.6.4 → rosetta_ce-1.6.7}/setup.py +1 -1
- {rosetta-ce-1.6.4 → rosetta_ce-1.6.7}/LICENSE +0 -0
- {rosetta-ce-1.6.4 → rosetta_ce-1.6.7}/README.md +0 -0
- {rosetta-ce-1.6.4 → rosetta_ce-1.6.7}/rosetta/__init__.py +0 -0
- {rosetta-ce-1.6.4 → rosetta_ce-1.6.7}/rosetta/constants/__init__.py +0 -0
- {rosetta-ce-1.6.4 → rosetta_ce-1.6.7}/rosetta/constants/attributes.py +0 -0
- {rosetta-ce-1.6.4 → rosetta_ce-1.6.7}/rosetta/constants/sensors.py +0 -0
- {rosetta-ce-1.6.4 → rosetta_ce-1.6.7}/rosetta/constants/sources.py +0 -0
- {rosetta-ce-1.6.4 → rosetta_ce-1.6.7}/rosetta/constants/systems.py +0 -0
- {rosetta-ce-1.6.4 → rosetta_ce-1.6.7}/rosetta/rconverter.py +0 -0
- {rosetta-ce-1.6.4 → rosetta_ce-1.6.7}/rosetta/rsender.py +0 -0
- {rosetta-ce-1.6.4 → rosetta_ce-1.6.7}/rosetta_ce.egg-info/dependency_links.txt +0 -0
- {rosetta-ce-1.6.4 → rosetta_ce-1.6.7}/rosetta_ce.egg-info/requires.txt +0 -0
- {rosetta-ce-1.6.4 → rosetta_ce-1.6.7}/rosetta_ce.egg-info/top_level.txt +0 -0
- {rosetta-ce-1.6.4 → rosetta_ce-1.6.7}/setup.cfg +0 -0
- {rosetta-ce-1.6.4 → rosetta_ce-1.6.7}/tests/test_rconverter.py +0 -0
- {rosetta-ce-1.6.4 → rosetta_ce-1.6.7}/tests/test_rfaker.py +0 -0
- {rosetta-ce-1.6.4 → rosetta_ce-1.6.7}/tests/test_rsender.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: rosetta-ce
|
|
3
|
-
Version: 1.6.
|
|
3
|
+
Version: 1.6.7
|
|
4
4
|
Summary: Rosetta is a Python package that can be used to fake security logs and alerts for testing different detection and response use cases.
|
|
5
5
|
Home-page: https://github.com/ayman-m/rosetta
|
|
6
6
|
Author: Ayman Mahmoud
|
|
@@ -11,6 +11,9 @@ Classifier: Operating System :: OS Independent
|
|
|
11
11
|
Requires-Python: >=3.6
|
|
12
12
|
Description-Content-Type: text/markdown
|
|
13
13
|
License-File: LICENSE
|
|
14
|
+
Requires-Dist: requests
|
|
15
|
+
Requires-Dist: faker
|
|
16
|
+
Requires-Dist: urllib3
|
|
14
17
|
|
|
15
18
|
[](https://snyk.io/test/github/my-soc/Rosetta)
|
|
16
19
|

|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
QUERY_TYPE = [ "SELECT", "INSERT", "UPDATE", "DELETE", "ALTER", "CREATE", "DROP", "TRUNCATE", "GRANT", "REVOKE", "MERGE", "CALL"]
|
|
2
|
+
DATABASE_NAME = [
|
|
3
|
+
"users_db",
|
|
4
|
+
"products_db",
|
|
5
|
+
"orders_db",
|
|
6
|
+
"inventory_db",
|
|
7
|
+
"payments_db",
|
|
8
|
+
"transactions_db",
|
|
9
|
+
"accounting_db",
|
|
10
|
+
"customers_db",
|
|
11
|
+
"employees_db",
|
|
12
|
+
"payroll_db",
|
|
13
|
+
"recruitment_db",
|
|
14
|
+
"attendance_db",
|
|
15
|
+
"cms_db",
|
|
16
|
+
"blog_db",
|
|
17
|
+
"media_db",
|
|
18
|
+
"articles_db"
|
|
19
|
+
]
|
|
20
|
+
QUERY = [
|
|
21
|
+
# Normal SELECT Queries
|
|
22
|
+
"SELECT * FROM users_db WHERE user_id = 123;",
|
|
23
|
+
"SELECT * FROM payments_db WHERE user_id = 123 ORDER BY transaction_date DESC;",
|
|
24
|
+
"SELECT name, price FROM products_db WHERE product_id = 567;",
|
|
25
|
+
"SELECT * FROM employees_db WHERE department = 'HR';",
|
|
26
|
+
"SELECT * FROM products_db WHERE category = 'Electronics';",
|
|
27
|
+
"SELECT COUNT(*) FROM orders_db WHERE order_date BETWEEN '2024-09-01' AND '2024-09-30';",
|
|
28
|
+
"SELECT product_id, SUM(quantity) FROM orders_db GROUP BY product_id;",
|
|
29
|
+
"SELECT employee_name, salary FROM payroll_db WHERE salary > 5000;",
|
|
30
|
+
"SELECT AVG(transaction_amount) FROM payments_db WHERE user_id = 123;",
|
|
31
|
+
|
|
32
|
+
# Normal INSERT Queries
|
|
33
|
+
"INSERT INTO users_db (user_id, name, email, signup_date) VALUES (124, 'John Doe', 'johndoe@example.com', '2024-09-12');",
|
|
34
|
+
"INSERT INTO orders_db (order_id, user_id, product_id, quantity, order_date) VALUES (999, 123, 567, 2, '2024-09-12');",
|
|
35
|
+
"INSERT INTO payments_db (transaction_id, user_id, amount, transaction_date) VALUES (555, 123, 120.50, '2024-09-12');",
|
|
36
|
+
"INSERT INTO products_db (product_id, name, price, category) VALUES (1001, 'Laptop', 1500.00, 'Electronics');",
|
|
37
|
+
"INSERT INTO employees_db (employee_id, name, department, hire_date) VALUES (200, 'Jane Doe', 'HR', '2024-09-10');",
|
|
38
|
+
"INSERT INTO transactions_db (transaction_id, user_id, amount, transaction_date) VALUES (789, 234, 500.75, '2024-09-11');",
|
|
39
|
+
"INSERT INTO cms_db (post_id, title, content, author) VALUES (12, 'New Blog Post', 'This is the content of the post', 'admin');",
|
|
40
|
+
|
|
41
|
+
# Normal UPDATE Queries
|
|
42
|
+
"UPDATE users_db SET email = 'newemail@example.com' WHERE user_id = 123;",
|
|
43
|
+
"UPDATE inventory_db SET stock = 50 WHERE product_id = 567;",
|
|
44
|
+
"UPDATE payments_db SET status = 'refunded' WHERE transaction_id = 555;",
|
|
45
|
+
"UPDATE orders_db SET status = 'shipped' WHERE order_id = 999;",
|
|
46
|
+
"UPDATE inventory_db SET stock = stock - 1 WHERE product_id = 1001;",
|
|
47
|
+
"UPDATE customers_db SET address = '123 New Street' WHERE customer_id = 567;",
|
|
48
|
+
|
|
49
|
+
# Normal DELETE Queries
|
|
50
|
+
"DELETE FROM users_db WHERE user_id = 999;",
|
|
51
|
+
"DELETE FROM products_db WHERE product_id = 1000;",
|
|
52
|
+
"DELETE FROM attendance_db WHERE employee_id = 101 AND date = '2024-09-11';",
|
|
53
|
+
"DELETE FROM blog_db WHERE post_id = 5;",
|
|
54
|
+
"DELETE FROM transactions_db WHERE transaction_date < '2023-01-01';",
|
|
55
|
+
"DELETE FROM employees_db WHERE hire_date < '2020-01-01';",
|
|
56
|
+
|
|
57
|
+
# Normal ALTER Queries
|
|
58
|
+
"ALTER TABLE users_db ADD COLUMN phone_number VARCHAR(20);",
|
|
59
|
+
"ALTER TABLE products_db MODIFY COLUMN price DECIMAL(10, 2);",
|
|
60
|
+
"ALTER TABLE payments_db ADD COLUMN transaction_status VARCHAR(20);",
|
|
61
|
+
"ALTER TABLE employees_db RENAME COLUMN hire_date TO start_date;",
|
|
62
|
+
|
|
63
|
+
# Normal CREATE Queries
|
|
64
|
+
"CREATE TABLE user_addresses (address_id INT PRIMARY KEY, user_id INT, address_line VARCHAR(255), city VARCHAR(100), postal_code VARCHAR(20));",
|
|
65
|
+
"CREATE INDEX idx_user_email ON users_db (email);",
|
|
66
|
+
|
|
67
|
+
# Normal DROP Queries
|
|
68
|
+
"DROP TABLE archived_orders;",
|
|
69
|
+
"DROP INDEX idx_product_sku ON products_db;",
|
|
70
|
+
|
|
71
|
+
# Malicious SQL Injection Queries
|
|
72
|
+
"SELECT * FROM users_db WHERE user_id = '1' OR '1'='1';",
|
|
73
|
+
"SELECT * FROM payments_db WHERE transaction_id = '1'; DROP TABLE payments_db;",
|
|
74
|
+
"SELECT * FROM users_db WHERE username = 'admin' AND password = '' OR '1'='1';",
|
|
75
|
+
"SELECT * FROM users_db WHERE password LIKE '%'; -- or '1'='1';",
|
|
76
|
+
|
|
77
|
+
# Malicious Unauthorized Data Manipulation
|
|
78
|
+
"UPDATE users_db SET password = 'hacked_password' WHERE username = 'admin';",
|
|
79
|
+
"DELETE FROM payments_db WHERE '1'='1';",
|
|
80
|
+
"INSERT INTO users_db (user_id, username, password, role) VALUES (999, 'attacker', 'password123', 'admin');",
|
|
81
|
+
|
|
82
|
+
# Malicious Privilege Escalation Queries
|
|
83
|
+
"GRANT ALL PRIVILEGES ON *.* TO 'attacker'@'%' IDENTIFIED BY 'password';",
|
|
84
|
+
"CREATE USER 'hacker'@'localhost' IDENTIFIED BY 'password';",
|
|
85
|
+
"GRANT ALL PRIVILEGES ON *.* TO 'hacker'@'localhost';",
|
|
86
|
+
|
|
87
|
+
# Additional Malicious Queries
|
|
88
|
+
"UPDATE employees_db SET salary = 10000 WHERE employee_id = 200 AND '1'='1';",
|
|
89
|
+
"DROP TABLE users_db; -- Malicious query to drop a table",
|
|
90
|
+
"SELECT * FROM users_db WHERE email = 'admin@example.com' AND '1'='1';"
|
|
91
|
+
]
|
|
92
|
+
|
|
@@ -15,6 +15,7 @@ from rosetta.constants.sources import BAD_IP_SOURCES, GOOD_IP_SOURCES, BAD_URL_S
|
|
|
15
15
|
from rosetta.constants.systems import UNIX_CMD, WINDOWS_CMD, WIN_PROCESSES, WIN_EVENTS
|
|
16
16
|
from rosetta.constants.attributes import INCIDENTS_TYPES, SEVERITIES
|
|
17
17
|
from rosetta.constants.sensors import ACTIONS, PROTOCOLS, TECHNIQUES, ERROR_CODE
|
|
18
|
+
from rosetta.constants.db import QUERY_TYPE, DATABASE_NAME, QUERY
|
|
18
19
|
|
|
19
20
|
|
|
20
21
|
class ObservableType(Enum):
|
|
@@ -32,22 +33,23 @@ class ObservableKnown(Enum):
|
|
|
32
33
|
|
|
33
34
|
class Observables:
|
|
34
35
|
def __init__(self, local_ip: list = None, remote_ip: Optional[list] = None, local_ip_v6: list = None,
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
36
|
+
remote_ip_v6: Optional[list] = None, src_host: Optional[list] = None,
|
|
37
|
+
dst_host: Optional[list] = None, src_domain: Optional[list] = None, dst_domain: Optional[list] = None,
|
|
38
|
+
sender_email: Optional[list] = None, recipient_email: Optional[list] = None,
|
|
39
|
+
email_subject: Optional[list] = None, email_body: Optional[list] = None,
|
|
40
|
+
url: Optional[list] = None, source_port: Optional[list] = None, remote_port: Optional[list] = None,
|
|
41
|
+
protocol: Optional[list] = None, inbound_bytes: Optional[list] = None,
|
|
42
|
+
outbound_bytes: Optional[list] = None, app: Optional[list] = None, os: Optional[list] = None,
|
|
43
|
+
user: Optional[list] = None, cve: Optional[list] = None, file_name: Optional[list] = None,
|
|
44
|
+
file_hash: Optional[list] = None, win_cmd: Optional[list] = None, unix_cmd: Optional[list] = None,
|
|
45
|
+
win_process: Optional[list] = None, win_child_process: Optional[list] = None,
|
|
46
|
+
unix_process: Optional[list] = None, unix_child_process: Optional[list] = None,
|
|
47
|
+
technique: Optional[list] = None, entry_type: Optional[list] = None, severity: Optional[list] = None,
|
|
48
|
+
sensor: Optional[list] = None, action: Optional[list] = None, event_id: Optional[list] = None,
|
|
49
|
+
error_code: Optional[list] = None, terms: Optional[list] = None, alert_types: Optional[list] = None,
|
|
50
|
+
alert_name: Optional[list] = None, incident_types: Optional[list] = None,
|
|
51
|
+
analysts: Optional[list] = None, action_status: Optional[list] = None, query_type: Optional[list] = None,
|
|
52
|
+
database_name: Optional[list] = None, query: Optional[list] = None):
|
|
51
53
|
self.local_ip = local_ip
|
|
52
54
|
self.remote_ip = remote_ip
|
|
53
55
|
self.local_ip_v6 = local_ip_v6
|
|
@@ -91,7 +93,9 @@ class Observables:
|
|
|
91
93
|
self.alert_types = alert_types
|
|
92
94
|
self.alert_name = alert_name
|
|
93
95
|
self.action_status = action_status
|
|
94
|
-
|
|
96
|
+
self.query_type = query_type
|
|
97
|
+
self.database_name = database_name
|
|
98
|
+
self.query = query
|
|
95
99
|
@staticmethod
|
|
96
100
|
def _get_observables_from_source(source: dict) -> list:
|
|
97
101
|
"""
|
|
@@ -99,7 +103,7 @@ class Observables:
|
|
|
99
103
|
|
|
100
104
|
Args:
|
|
101
105
|
- source: A dictionary containing information about the source, including its type, URL, structure, and value
|
|
102
|
-
|
|
106
|
+
column or key.
|
|
103
107
|
|
|
104
108
|
Returns:
|
|
105
109
|
- A list of observables fetched from the source.
|
|
@@ -116,13 +120,13 @@ class Observables:
|
|
|
116
120
|
results = [line.strip() for line in response.text.strip().split("\n") if not line.startswith("#")]
|
|
117
121
|
elif source['structure'] == 'csv':
|
|
118
122
|
rows = csv.reader(filter(lambda line: not line.startswith('#'), response.text.strip().split('\n')),
|
|
119
|
-
|
|
123
|
+
delimiter=source['delimiter'])
|
|
120
124
|
for row in rows:
|
|
121
125
|
results.append(row[source['value_column']])
|
|
122
126
|
elif source['structure'] == 'json':
|
|
123
127
|
results = reduce(lambda d, key: d[key] if key != source['value_key'].split('.')[-1] else [i[key]
|
|
124
|
-
|
|
125
|
-
|
|
128
|
+
for i in d],
|
|
129
|
+
source['value_key'].split('.'), response.json())
|
|
126
130
|
random.shuffle(results)
|
|
127
131
|
if source_type == 'subnet':
|
|
128
132
|
ip_addresses = []
|
|
@@ -144,7 +148,7 @@ class Observables:
|
|
|
144
148
|
|
|
145
149
|
@classmethod
|
|
146
150
|
def generator(cls, count: int, observable_type: ObservableType,
|
|
147
|
-
|
|
151
|
+
known: ObservableKnown = ObservableKnown.BAD) -> List[str]:
|
|
148
152
|
"""
|
|
149
153
|
Generates a list of observable values based on the given observable type and known status, with a desired count.
|
|
150
154
|
The function attempts to obtain the values from sources defined in configuration files. If the function fails to
|
|
@@ -297,6 +301,9 @@ class Events:
|
|
|
297
301
|
if field == "src_host":
|
|
298
302
|
field_value = random.choice(observables.src_host) if observables and observables.src_host \
|
|
299
303
|
else faker.hostname()
|
|
304
|
+
if field == "dst_host":
|
|
305
|
+
field_value = random.choice(observables.dst_host) if observables and observables.dst_host \
|
|
306
|
+
else faker.hostname()
|
|
300
307
|
if field == "user":
|
|
301
308
|
field_value = random.choice(observables.user) if observables and observables.user \
|
|
302
309
|
else faker.user_name()
|
|
@@ -305,7 +312,7 @@ class Events:
|
|
|
305
312
|
else "sudo"
|
|
306
313
|
if field == "unix_child_process":
|
|
307
314
|
field_value = random.choice(observables.unix_child_process) if observables and \
|
|
308
|
-
|
|
315
|
+
observables.unix_child_process else "sudo"
|
|
309
316
|
if field == "unix_cmd":
|
|
310
317
|
field_value = random.choice(observables.unix_cmd) if observables and observables.unix_cmd \
|
|
311
318
|
else random.choice(UNIX_CMD)
|
|
@@ -359,7 +366,7 @@ class Events:
|
|
|
359
366
|
if field == "attachment_hash":
|
|
360
367
|
field_value = random.choice(observables.file_hash) if observables and observables.file_hash \
|
|
361
368
|
else Observables.generator(observable_type=ObservableType.SHA256, known=ObservableKnown.BAD,
|
|
362
|
-
|
|
369
|
+
count=1)
|
|
363
370
|
if field == "spam_score":
|
|
364
371
|
field_value = faker.random_int(min=1, max=5)
|
|
365
372
|
if field == "method":
|
|
@@ -427,7 +434,7 @@ class Events:
|
|
|
427
434
|
if field == "file_hash":
|
|
428
435
|
field_value = random.choice(observables.file_hash) if observables and observables.file_hash \
|
|
429
436
|
else Observables.generator(observable_type=ObservableType.SHA256, known=ObservableKnown.BAD,
|
|
430
|
-
|
|
437
|
+
count=1)
|
|
431
438
|
if field == "incident_types":
|
|
432
439
|
field_value = random.choice(observables.incident_types) if observables and observables.incident_types \
|
|
433
440
|
else INCIDENTS_TYPES
|
|
@@ -441,6 +448,15 @@ class Events:
|
|
|
441
448
|
if field == "alert_name":
|
|
442
449
|
field_value = random.choice(observables.alert_name) if observables and observables.alert_name \
|
|
443
450
|
else faker.sentence(nb_words=4)
|
|
451
|
+
if field == "query_type":
|
|
452
|
+
field_value = random.choice(observables.query_type) if \
|
|
453
|
+
observables and observables.query_type else random.choice(QUERY_TYPE)
|
|
454
|
+
if field == "database_name":
|
|
455
|
+
field_value = random.choice(observables.database_name) if \
|
|
456
|
+
observables and observables.database_name else random.choice(DATABASE_NAME)
|
|
457
|
+
if field == "query":
|
|
458
|
+
field_value = random.choice(observables.query) if \
|
|
459
|
+
observables and observables.query else random.choice(QUERY)
|
|
444
460
|
return field_value
|
|
445
461
|
|
|
446
462
|
@classmethod
|
|
@@ -606,13 +622,13 @@ class Events:
|
|
|
606
622
|
for i in range(count):
|
|
607
623
|
datetime_iso += timedelta(seconds=1)
|
|
608
624
|
leef_message = f"LEEF:1.0|{vendor}|{product}|{version}|{event_id}|" \
|
|
609
|
-
f"severity={cls.set_field('severity', observables)}
|
|
625
|
+
f"severity={cls.set_field('severity', observables)} devtime={datetime_iso}"
|
|
610
626
|
for field in required_fields.split(","):
|
|
611
|
-
leef_message += f"
|
|
627
|
+
leef_message += f" {field}={cls.set_field(field, observables)}"
|
|
612
628
|
if observables:
|
|
613
629
|
for observable, observable_value in vars(observables).items():
|
|
614
630
|
if observable_value and observable not in required_fields.split(","):
|
|
615
|
-
leef_message += f"
|
|
631
|
+
leef_message += f" {observable}={random.choice(observable_value)}"
|
|
616
632
|
leef_messages.append(leef_message)
|
|
617
633
|
return leef_messages
|
|
618
634
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: rosetta-ce
|
|
3
|
-
Version: 1.6.
|
|
3
|
+
Version: 1.6.7
|
|
4
4
|
Summary: Rosetta is a Python package that can be used to fake security logs and alerts for testing different detection and response use cases.
|
|
5
5
|
Home-page: https://github.com/ayman-m/rosetta
|
|
6
6
|
Author: Ayman Mahmoud
|
|
@@ -11,6 +11,9 @@ Classifier: Operating System :: OS Independent
|
|
|
11
11
|
Requires-Python: >=3.6
|
|
12
12
|
Description-Content-Type: text/markdown
|
|
13
13
|
License-File: LICENSE
|
|
14
|
+
Requires-Dist: requests
|
|
15
|
+
Requires-Dist: faker
|
|
16
|
+
Requires-Dist: urllib3
|
|
14
17
|
|
|
15
18
|
[](https://snyk.io/test/github/my-soc/Rosetta)
|
|
16
19
|

|
|
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
|
|
|
5
5
|
|
|
6
6
|
setuptools.setup(
|
|
7
7
|
name="rosetta-ce",
|
|
8
|
-
version="1.6.
|
|
8
|
+
version="1.6.7",
|
|
9
9
|
author="Ayman Mahmoud",
|
|
10
10
|
author_email="content@ayman.online",
|
|
11
11
|
description="Rosetta is a Python package that can be used to fake security logs and alerts for testing different "
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|