Skip to content

Commit

Permalink
add support for adding ed25519 keys for ssh + docker support
Browse files Browse the repository at this point in the history
  • Loading branch information
ajinabraham committed Dec 1, 2023
1 parent 19f8ade commit 56492e6
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 5 deletions.
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ RUN apt update -y && apt install -y --no-install-recommends \
curl \
git \
jq \
unzip \
android-tools-adb && \
locale-gen en_US.UTF-8 && \
apt upgrade -y
Expand Down
27 changes: 26 additions & 1 deletion mobsf/DynamicAnalyzer/views/ios/corellium_apis.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
"""Corellium APIs."""
import logging
from copy import deepcopy
from socket import gethostname

import requests


SUCCESS_RESP = (200, 204)
ERROR_RESP = (400, 403, 404, 409)
OK = 'ok'
Expand Down Expand Up @@ -60,6 +60,31 @@ def get_projects(self):
return True
return False

def get_authorized_keys(self):
"""Get SSH public keys associated with a project."""
r = requests.get(
f'{self.api}/projects/{self.project_id}/keys',
headers=self.headers)
if r.status_code in SUCCESS_RESP:
return r.json()
return False

def add_authorized_key(self, key):
"""Add SSH public key to the Project."""
logger.info('Adding SSH public key to Corellium project')
data = {
'kind': 'ssh',
'label': f'MobSF SSH Key - {gethostname()}',
'key': key,
}
r = requests.post(
f'{self.api}/projects/{self.project_id}/keys',
headers=self.headers,
json=data)
if r.status_code in SUCCESS_RESP:
return r.json()['identifier']
return False

def get_instances(self):
"""Get Instances."""
logger.info('Getting iOS instances')
Expand Down
2 changes: 1 addition & 1 deletion mobsf/DynamicAnalyzer/views/ios/corellium_instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
invalid_params,
send_response,
)
from mobsf.DynamicAnalyzer.views.ios.corellium_frida_ssh import (
from mobsf.DynamicAnalyzer.views.ios.corellium_ssh import (
ssh_execute_cmd,
ssh_file_upload,
ssh_jump_host,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,42 @@

import paramiko

from django.conf import settings

from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey


logger = logging.getLogger(__name__)


def generate_keypair_if_not_exists(location):
"""Generate RSA key pair."""
prv = location / 'ssh_key.private'
pub = location / 'ssh_key.public'
if prv.exists() and pub.exists():
# Keys Exists
return prv.read_bytes(), pub.read_bytes()
logger.info('Generating RSA key pair for Corellium SSH')

# Generate private/public key pair
private_key = Ed25519PrivateKey.generate()
public_key = private_key.public_key()

# OpenSSH friendly
private_bytes = private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.OpenSSH,
encryption_algorithm=serialization.NoEncryption())

public_bytes = public_key.public_bytes(
encoding=serialization.Encoding.OpenSSH,
format=serialization.PublicFormat.OpenSSH)
prv.write_bytes(private_bytes)
pub.write_bytes(public_bytes)
return private_bytes, public_bytes


def parse_ssh_string(ssh):
"""Parse SSH connection string."""
ssh_dict = {}
Expand Down Expand Up @@ -124,9 +156,15 @@ def ssh_jump_host(ssh_string):
user = ssh_dict['private_user']
private_ip = ssh_dict['private_ip']

home = Path(settings.UPLD_DIR).parent
generate_keypair_if_not_exists(home)
keyf = home / 'ssh_key.private'
jumpbox = paramiko.SSHClient()
jumpbox.set_missing_host_key_policy(paramiko.AutoAddPolicy())

Check failure

Code scanning / CodeQL

Accepting unknown SSH host keys when using Paramiko High

Setting missing host key policy to AutoAddPolicy may be unsafe.
jumpbox.connect(bastion_host, username=bastion_user)
jumpbox.connect(
bastion_host,
username=bastion_user,
key_filename=keyf.as_posix())

jumpbox_transport = jumpbox.get_transport()
src_addr = (private_ip, 22)
Expand All @@ -136,7 +174,11 @@ def ssh_jump_host(ssh_string):

target = paramiko.SSHClient()
target.set_missing_host_key_policy(paramiko.AutoAddPolicy())

Check failure

Code scanning / CodeQL

Accepting unknown SSH host keys when using Paramiko High

Setting missing host key policy to AutoAddPolicy may be unsafe.
target.connect(private_ip, username=user, sock=jumpbox_channel)
target.connect(
private_ip,
username=user,
sock=jumpbox_channel,
password='alpine')
return target, jumpbox


Expand Down
36 changes: 36 additions & 0 deletions mobsf/DynamicAnalyzer/views/ios/dynamic_analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
)
from mobsf.StaticAnalyzer.models import StaticAnalyzerIOS
from mobsf.DynamicAnalyzer.forms import UploadFileForm
from mobsf.DynamicAnalyzer.views.ios.corellium_ssh import (
generate_keypair_if_not_exists,
)
from mobsf.DynamicAnalyzer.views.ios.corellium_apis import (
CorelliumAPI,
)
Expand Down Expand Up @@ -57,6 +60,7 @@ def dynamic_analysis(request, api=False):
if c.api_ready() and c.api_auth() and c.get_projects():
instances = c.get_instances()
project_id = c.project_id
setup_ssh_keys(c)
context = {'apps': scan_apps,
'dynamic_analyzer': ios_dynamic,
'project_id': project_id,
Expand Down Expand Up @@ -110,3 +114,35 @@ def dynamic_analyzer(request, api=False):
request,
'iOS Dynamic Analysis Failed.',
api)


def setup_ssh_keys(c):
# Get Authorized keys for the project
pkeys = c.get_authorized_keys()
location = Path(settings.UPLD_DIR).parent
_prv, pub = generate_keypair_if_not_exists(location)
add_keys = False
if not pkeys:
# No SSH Keys associated with the project
# let's add one
add_keys = True
else:
# SSH Keys are already associated with the project
# Check if our key is associated
pub_key_exists = False
for pkey in pkeys:
if pkey['project'] == c.project_id:
ckey = get_md5(pkey['key'].encode('utf-8'))
lkey = get_md5(pub)
if ckey == lkey:
pub_key_exists = True
break
# Out key is not asscoiated with the project, let's add it
if not pub_key_exists:
add_keys = True
if add_keys:
iden = c.add_authorized_key(pub)
if not iden:
logger.error('Failed to add SSH Key to Corellium project')
return
logger.info('Added SSH Key to Corellium project')
2 changes: 1 addition & 1 deletion mobsf/DynamicAnalyzer/views/ios/frida_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
string_capture,
string_compare,
)
from mobsf.DynamicAnalyzer.views.ios.corellium_frida_ssh import (
from mobsf.DynamicAnalyzer.views.ios.corellium_ssh import (
ssh_jumphost_port_forward,
)

Expand Down

0 comments on commit 56492e6

Please sign in to comment.