Island, Agent: Fix credential parsing to match pydantic syntax

This commit is contained in:
vakarisz 2022-09-01 14:38:34 +03:00 committed by vakaris_zilius
parent d73cbee591
commit 7149c704a2
6 changed files with 92 additions and 117 deletions

View File

@ -1,7 +1,8 @@
import logging import logging
from typing import Any, Iterable from typing import Any, Iterable
from common.credentials import CredentialComponentType, Credentials, ICredentialComponent from common.credentials import Credentials, LMHash, NTHash, Password, SSHKeypair, Username
from common.credentials.credentials import Identity, Secret
from infection_monkey.custom_types import PropagationCredentials from infection_monkey.custom_types import PropagationCredentials
from infection_monkey.i_control_channel import IControlChannel from infection_monkey.i_control_channel import IControlChannel
from infection_monkey.utils.decorators import request_cache from infection_monkey.utils.decorators import request_cache
@ -43,18 +44,18 @@ class AggregatingPropagationCredentialsRepository(IPropagationCredentialsReposit
if credentials.secret: if credentials.secret:
self._add_secret(credentials.secret) self._add_secret(credentials.secret)
def _add_identity(self, identity: ICredentialComponent): def _add_identity(self, identity: Identity):
if identity.credential_type is CredentialComponentType.USERNAME: if type(identity) == Username:
self._stored_credentials.setdefault("exploit_user_list", set()).add(identity.username) self._stored_credentials.setdefault("exploit_user_list", set()).add(identity.username)
def _add_secret(self, secret: ICredentialComponent): def _add_secret(self, secret: Secret):
if secret.credential_type is CredentialComponentType.PASSWORD: if type(secret) is Password:
self._stored_credentials.setdefault("exploit_password_list", set()).add(secret.password) self._stored_credentials.setdefault("exploit_password_list", set()).add(secret.password)
elif secret.credential_type is CredentialComponentType.LM_HASH: elif type(secret) is LMHash:
self._stored_credentials.setdefault("exploit_lm_hash_list", set()).add(secret.lm_hash) self._stored_credentials.setdefault("exploit_lm_hash_list", set()).add(secret.lm_hash)
elif secret.credential_type is CredentialComponentType.NT_HASH: elif type(secret) is NTHash:
self._stored_credentials.setdefault("exploit_ntlm_hash_list", set()).add(secret.nt_hash) self._stored_credentials.setdefault("exploit_ntlm_hash_list", set()).add(secret.nt_hash)
elif secret.credential_type is CredentialComponentType.SSH_KEYPAIR: elif type(secret) is SSHKeypair:
self._set_attribute( self._set_attribute(
"exploit_ssh_keys", "exploit_ssh_keys",
[{"public_key": secret.public_key, "private_key": secret.private_key}], [{"public_key": secret.public_key, "private_key": secret.private_key}],

View File

@ -1,7 +1,7 @@
import logging import logging
from typing import Mapping, Sequence from typing import Mapping, Sequence
from common.credentials import CredentialComponentType, Credentials from common.credentials import Credentials, LMHash, NTHash, Password, SSHKeypair
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -11,23 +11,22 @@ def format_creds_for_reporting(credentials: Sequence[Credentials]) -> Sequence[M
formatted_creds = [] formatted_creds = []
cred_type_dict = { cred_type_dict = {
CredentialComponentType.PASSWORD: "Clear Password", Password: "Clear Password",
CredentialComponentType.LM_HASH: "LM hash", LMHash: "LM hash",
CredentialComponentType.NT_HASH: "NTLM hash", NTHash: "NTLM hash",
CredentialComponentType.SSH_KEYPAIR: "Clear SSH private key", SSHKeypair: "Clear SSH private key",
} }
for cred in credentials: for cred in credentials:
secret = cred.secret secret = cred.secret
if secret is None: if secret is None:
continue continue
if secret.credential_type not in cred_type_dict: if type(secret) not in cred_type_dict:
continue continue
username = _get_username(cred) username = _get_username(cred)
cred_row = { cred_row = {
"username": username, "username": username,
"_type": secret.credential_type.name, "type": cred_type_dict[type(secret)],
"type": cred_type_dict[secret.credential_type],
} }
if cred_row not in formatted_creds: if cred_row not in formatted_creds:
formatted_creds.append(cred_row) formatted_creds.append(cred_row)

View File

@ -1,4 +1,5 @@
import {defaultCredentials} from '../../services/configuration/propagation/credentials'; import {defaultCredentials} from '../../services/configuration/propagation/credentials';
import {CredentialTypes, SecretTypes} from '../utils/CredentialTypes.js';
import _ from 'lodash'; import _ from 'lodash';
export function reformatConfig(config, reverse = false) { export function reformatConfig(config, reverse = false) {
@ -35,16 +36,16 @@ export function formatCredentialsForForm(credentials) {
let secret = credentials[i]['secret']; let secret = credentials[i]['secret'];
if(secret !== null){ if(secret !== null){
if (secret['credential_type'] === 'PASSWORD') { if (secret.hasOwnProperty(SecretTypes.Password)) {
formattedCredentials['exploit_password_list'].push(secret['password']) formattedCredentials['exploit_password_list'].push(secret['password'])
} }
if (secret['credential_type'] === 'NT_HASH') { if (secret.hasOwnProperty(SecretTypes.NTHash)) {
formattedCredentials['exploit_ntlm_hash_list'].push(secret['nt_hash']) formattedCredentials['exploit_ntlm_hash_list'].push(secret['nt_hash'])
} }
if (secret['credential_type'] === 'LM_HASH') { if (secret.hasOwnProperty(SecretTypes.LMHash)) {
formattedCredentials['exploit_lm_hash_list'].push(secret['lm_hash']) formattedCredentials['exploit_lm_hash_list'].push(secret['lm_hash'])
} }
if (secret['credential_type'] === 'SSH_KEY') { if (secret.hasOwnProperty(SecretTypes.PrivateKey)) {
let keypair = {'public_key': secret['public_key'], 'private_key': secret['private_key']} let keypair = {'public_key': secret['public_key'], 'private_key': secret['private_key']}
formattedCredentials['exploit_ssh_keys'].push(keypair) formattedCredentials['exploit_ssh_keys'].push(keypair)
} }
@ -64,43 +65,34 @@ export function formatCredentialsForIsland(credentials) {
let usernames = credentials['exploit_user_list']; let usernames = credentials['exploit_user_list'];
for (let i = 0; i < usernames.length; i++) { for (let i = 0; i < usernames.length; i++) {
formattedCredentials.push({ formattedCredentials.push({
'identity': {'username': usernames[i], 'credential_type': 'USERNAME'}, 'identity': {'username': usernames[i]},
'secret': null 'secret': null
}) })
} }
let passwords = credentials['exploit_password_list']; formattedCredentials.push(...getFormattedCredentials(credentials['exploit_password_list'], 'password'))
for (let i = 0; i < passwords.length; i++) { formattedCredentials.push(...getFormattedCredentials(credentials['exploit_ntlm_hash_list'], 'nt_hash'))
formattedCredentials.push({ formattedCredentials.push(...getFormattedCredentials(credentials['exploit_lm_hash_list'], 'lm_hash'))
'identity': null,
'secret': {'credential_type': 'PASSWORD', 'password': passwords[i]}
})
}
let nt_hashes = credentials['exploit_ntlm_hash_list'];
for (let i = 0; i < nt_hashes.length; i++) {
formattedCredentials.push({
'identity': null,
'secret': {'credential_type': 'NT_HASH', 'nt_hash': nt_hashes[i]}
})
}
let lm_hashes = credentials['exploit_lm_hash_list'];
for (let i = 0; i < lm_hashes.length; i++) {
formattedCredentials.push({
'identity': null,
'secret': {'credential_type': 'LM_HASH', 'lm_hash': lm_hashes[i]}
})
}
let ssh_keys = credentials['exploit_ssh_keys']; let ssh_keys = credentials['exploit_ssh_keys'];
for (let i = 0; i < ssh_keys.length; i++) { for (let i = 0; i < ssh_keys.length; i++) {
formattedCredentials.push({ formattedCredentials.push({
'identity': null, 'identity': null,
'secret': {'credential_type': 'SSH_KEYPAIR', 'private_key': ssh_keys[i]['private_key'], 'secret': {'private_key': ssh_keys[i]['private_key'],
'public_key': ssh_keys[i]['public_key']} 'public_key': ssh_keys[i]['public_key']}
}) })
} }
return formattedCredentials; return formattedCredentials;
} }
function getFormattedCredentials(credentials, keyOfSecret) {
let formattedCredentials = [];
for (let i = 0; i < credentials.length; i++) {
formattedCredentials.push({
'identity': null,
'secret': {[keyOfSecret]: credentials[i]}
})
}
return formattedCredentials;
}

View File

@ -1,3 +1,5 @@
import {CredentialTypes, SecretTypes} from '../utils/CredentialTypes.js';
export function getAllUsernames(stolen, configured) { export function getAllUsernames(stolen, configured) {
let usernames = []; let usernames = [];
usernames.push(...getCredentialsUsernames(stolen)); usernames.push(...getCredentialsUsernames(stolen));
@ -21,35 +23,37 @@ export function getAllSecrets(stolen, configured){
for (let i = 0; i < stolen.length; i++) { for (let i = 0; i < stolen.length; i++) {
let secret = stolen[i]['secret']; let secret = stolen[i]['secret'];
if (secret !== null) { if (secret !== null) {
secrets.push(getSecretsFromCredential(secret)); secrets.push(reformatSecret(secret));
} }
} }
for (let i = 0; i < configured.length; i++) { for (let i = 0; i < configured.length; i++) {
let secret = configured[i]['secret']; let secret = configured[i]['secret'];
if (secret !== null) { if (secret !== null) {
secrets.push(getSecretsFromCredential(secret)); secrets.push(reformatSecret(secret));
} }
} }
return secrets; return secrets;
} }
function getSecretsFromCredential(credential) { function reformatSecret(secret) {
if(credential['credential_type'] === 'SSH_KEYPAIR'){ if (secret.hasOwnProperty(SecretTypes.Password)) {
return {'type': 'SSH keypair', 'content': credential['private_key']} return {'type': CredentialTypes.Password, 'content': secret[SecretTypes.Password]}
} }
if(credential['credential_type'] === 'NT_HASH'){ if (secret.hasOwnProperty(SecretTypes.NTHash)) {
return {'type': 'NT hash', 'content': credential['nt_hash']} return {'type': CredentialTypes.NTHash, 'content': secret[SecretTypes.NTHash]}
} }
if(credential['credential_type'] === 'LM_HASH'){ if (secret.hasOwnProperty(SecretTypes.LMHash)) {
return {'type': 'LM hash', 'content': credential['lm_hash']} return {'type': CredentialTypes.LMHash, 'content': secret[SecretTypes.LMHash]}
}
if (secret.hasOwnProperty(SecretTypes.PrivateKey)) {
return {
'type': CredentialTypes.SSHKeys,
'content': secret[SecretTypes.PrivateKey]
} }
if(credential['credential_type'] === 'PASSWORD'){
return {'type': 'Password', 'content': credential['password']}
} }
} }
export function getCredentialsTableData(credentials) { export function getCredentialsTableData(credentials) {
let table_data = []; let table_data = [];
let identites = getCredentialsUsernames(credentials); let identites = getCredentialsUsernames(credentials);

View File

@ -0,0 +1,14 @@
export const CredentialTypes = {
Password: 'Clear Password',
SSHKeys: 'Clear SSH private key',
LMHash: 'LM hash',
NTHash: 'NT hash',
Username: 'Username'
}
export const SecretTypes = {
Password: 'password',
PrivateKey: 'private_key',
LMHash: 'lm_hash',
NTHash: 'nt_hash'
}

View File

@ -1,64 +1,29 @@
from common.credentials import ( from tests.data_for_tests.propagation_credentials import FULL_CREDENTIALS, USERNAME
CredentialComponentType,
Credentials,
LMHash,
NTHash,
Password,
SSHKeypair,
Username,
)
from monkey_island.cc.services.reporting import format_creds_for_reporting from monkey_island.cc.services.reporting import format_creds_for_reporting
monkey_hostname = "fake_hostname"
fake_monkey_guid = "abc"
fake_username = Username("m0nk3y_user")
fake_nt_hash = NTHash("AEBD4DE384C7EC43AAD3B435B51404EE")
fake_lm_hash = LMHash("7A21990FCD3D759941E45C490F143D5F")
fake_password = Password("trytostealthis")
fake_ssh_public_key = "RSA_public_key"
fake_ssh_private_key = "RSA_private_key"
fake_ssh_key = SSHKeypair(fake_ssh_private_key, fake_ssh_public_key)
identities = (fake_username,)
secrets = (fake_nt_hash, fake_lm_hash, fake_password, fake_ssh_key)
fake_credentials = [
Credentials(identity=fake_username, secret=fake_nt_hash),
Credentials(identity=fake_username, secret=fake_lm_hash),
Credentials(identity=fake_username, secret=fake_password),
Credentials(identity=fake_username, secret=fake_ssh_key),
Credentials(identity=None, secret=fake_ssh_key),
Credentials(identity=fake_username, secret=None),
]
def test_formatting_credentials_for_report(): def test_formatting_credentials_for_report():
credentials = format_creds_for_reporting(fake_credentials) credentials = format_creds_for_reporting(FULL_CREDENTIALS)
result1 = { result1 = {
"_type": CredentialComponentType.NT_HASH.name,
"type": "NTLM hash", "type": "NTLM hash",
"username": fake_username.username, "username": USERNAME,
} }
result2 = { result2 = {
"_type": CredentialComponentType.LM_HASH.name,
"type": "LM hash", "type": "LM hash",
"username": fake_username.username, "username": USERNAME,
} }
result3 = { result3 = {
"_type": CredentialComponentType.PASSWORD.name,
"type": "Clear Password", "type": "Clear Password",
"username": fake_username.username, "username": USERNAME,
} }
result4 = { result4 = {
"_type": CredentialComponentType.SSH_KEYPAIR.name,
"type": "Clear SSH private key", "type": "Clear SSH private key",
"username": fake_username.username, "username": USERNAME,
} }
result5 = { result5 = {
"_type": CredentialComponentType.SSH_KEYPAIR.name,
"type": "Clear SSH private key", "type": "Clear SSH private key",
"username": "", "username": "",
} }