Je voudrais récupérer le rapport d'analyse des logiciels malveillants de Joe Sandbox avec BeautifulSoup + Python pour obtenir la ** ligne de commande PowerShell **.
C'est un site qui analyse les logiciels malveillants et produit un rapport. https://www.joesandbox.com
Il existe différentes versions de JoeSandbox, mais la version appelée Cloud Basic vous permet d'analyser gratuitement les logiciels malveillants. De plus, les rapports analysés par Cloud Basic seront publiés afin que vous puissiez voir les rapports de résultats d'analyse d'autres personnes. À propos, l'API Web peut être utilisée avec des versions autres que Cloud Basic, mais il semble qu'elle ne puisse pas être utilisée avec Cloud Basic.
Si vous souhaitez en savoir plus, veuillez vous référer à ce qui suit.
Comment faire une analyse dynamique des malwares avec Joe Sandbox * https://qiita.com/hanzawak/items/ec665e0f96dc65f3def3
Web scraping à partir d'un site d'analyse dynamique de malwares avec BeautifulSoup + Python * https://qiita.com/hanzawak/items/0a8a26d1ebe62b84f847
Obtenez la ligne de commande PowerShell à partir du rapport d'analyse JoeSandbox Cloud Basic.
Si vous l'obtenez normalement, la ligne de commande PowerShell exécutée par le logiciel malveillant et la ligne de commande PowerShell exécutée par le fichier légitime seront mélangées. Par conséquent, le score indiquant le degré de malware jugé par Joe Sandbox est également acquis.
Le score est obtenu à partir de ce qui suit.
Extrayez la ligne de commande PowerShell à partir de:
Dans les cas suivants, C: \\ WINDOWS \\ System32 \\ WindowsPowerShell \\ v1.0 \\ powershell.exe -noP -sta -w 1 -enc abréviation
est extrait.
La sortie écrira les informations dans un fichier texte comme suit. L'ordre est "numéro de rapport, score, commande PowerShell" séparés par des virgules.
ReportNumber,DetectionScore,PowerShellCommandLine
236546,56,C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -noP -sta -w 1 -abréviation enc
236547,99,C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -NoP -NonI -W Hiden -Abréviation Exec Bypass
236548,10,C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.abréviation exe
J'essaye de le faire fonctionner si je connecte le contenu décrit ci-dessous.
En plus de BeautifulSoup, importez les requêtes, os et re.
import requests
from bs4 import BeautifulSoup
import os
import re
Préparez-vous à entrer de et à pour extraire des informations de plusieurs rapports. Un seul est spécifié ici pour les tests.
report_num_from = 236543
report_num_to = 236543
L'URL du rapport est la suivante. Cette partie "236543" semble être le numéro du rapport, je voudrais donc boucler ce numéro. https://www.joesandbox.com/analysis/236543/0/html
def extract_powershell_command(report_num_from, report_num_to):
for reoprt_num in range(report_num_from, report_num_to + 1):
ps_cmdline = []
try:
target_url = 'https://www.joesandbox.com/analysis/' + str(reoprt_num) + '/0/html'
response = requests.get(target_url)
soup = BeautifulSoup(response.text, 'lxml')
Le score est écrit en haut de l'écran. Dans ce cas, le score est de 56, mais nous obtiendrons ce nombre.
Le code correspondant était ci-dessous.
C'est un peu difficile, mais vous pouvez obtenir un score en procédant comme suit.
detection_score = 0
table = soup.findAll("table", {"id":"detection-details-overview-table"})[0]
rows = table.findAll("tr")
detection_score = re.sub(r'.+>(.+)</td></tr>', r'\1', str(rows[0]))
Voici un exemple d'écran qui inclut une ligne de commande PowerShell.
Je vais récupérer la partie arrière de la cmdline après powershell.exe. Le code correspondant était ci-dessous.
Je vais vérifier le contenu.
Apparemment, il est stocké dans la table.
Je vais obtenir celui qui contient powershell.exe
séparé par li
, le formater et obtenir les informations derrière cmdline
.
Il y a peut-être un moyen plus intelligent, mais j'ai fait ce qui suit:
startup = soup.find('div', id='startup1')
for line in startup.findAll('li'):
if 'powershell.exe' in str(line):
tmp = str(line).replace('<wbr>', '').replace('</wbr>', '')
cmdline = re.sub(r'.+ cmdline: (.*) MD5: <span.+', r'\1', tmp)
ps_cmdline.append(str(reoprt_num) + ',' + detection_score + ',' + cmdline)
Le traitement des exceptions est également inclus pour le moment.
À la fin du processus, appelez la fonction save_file
(décrite plus loin).
except IndexError as e:
ps_cmdline.append('{},ERROR:{}'.format(reoprt_num,e))
except Exception as e:
ps_cmdline.append('{},ERROR:{}'.format(reoprt_num,e))
finally:
save_file(ps_cmdline)
Il s'agit du processus d'écriture dans un fichier. Il n'est pas nécessaire d'en faire une fonction distincte, mais je le changerai en un processus autre que l'écriture de fichiers à l'avenir, donc j'en ai fait une fonction afin qu'il puisse être facilement réécrit. Créez et écrivez ʻoutput.txt` dans le même dossier.
def save_file(ps_cmdline):
with open('./output.txt', 'a') as f:
if os.stat('./output.txt').st_size == 0:
f.write('ReportNumber,DetectionScore,PowerShellCommandLine\n')
for x in ps_cmdline:
f.write(str(x) + "\n")
J'ai ajouté un commentaire en connectant le code jusqu'à présent. De toute évidence, la plage spécifiée par de et à doit être modérée. Depuis qu'il a été créé et exécuté avec Jupyter Notebook, il a le format suivant.
import requests
from bs4 import BeautifulSoup
import os
import re
report_num_from = 236547
report_num_to = 236547
def extract_powershell_command(report_num_from, report_num_to):
"""
Extract PowerShell Command from JoeSandbox analysis result.
Parameters
----------
report_num_from : int
First report number to analyze
report_num_to : int
Last report number to analyze
"""
for reoprt_num in range(report_num_from, report_num_to + 1):
ps_cmdline = []
try:
target_url = 'https://www.joesandbox.com/analysis/' + str(reoprt_num) + '/0/html'
response = requests.get(target_url)
soup = BeautifulSoup(response.text, 'lxml')
# Check JoeSandbox Detection Score (Maybe score above 40 is malicious)
detection_score = 0
table = soup.findAll("table", {"id":"detection-details-overview-table"})[0]
rows = table.findAll("tr")
detection_score = re.sub(r'.+>(.+)</td></tr>', r'\1', str(rows[0]))
startup = soup.find('div', id='startup1') # 'startup1' is a table with ProcessName & CommandLine
for line in startup.findAll('li'):
if 'powershell.exe' in str(line):
tmp = str(line).replace('<wbr>', '').replace('</wbr>', '')
cmdline = re.sub(r'.+ cmdline: (.*) MD5: <span.+', r'\1', tmp)
ps_cmdline.append(str(reoprt_num) + ',' + detection_score + ',' + cmdline)
# Report number does not exist
except IndexError as e:
ps_cmdline.append('{},ERROR:{}'.format(reoprt_num,e))
except Exception as e:
ps_cmdline.append('{},ERROR:{}'.format(reoprt_num,e))
finally:
save_file(ps_cmdline)
def save_file(ps_cmdline):
"""
Save the extraction results to a file.
File I/O is a function because it may change.
Parameters
----------
ps_cmdline : list of str
List containing process names.
"""
with open('./output.txt', 'a') as f:
if os.stat('./output.txt').st_size == 0:
f.write('ReportNumber,DetectionScore,PowerShellCommandLine\n')
for x in ps_cmdline:
f.write(str(x) + "\n")
extract_powershell_command(report_num_from, report_num_to)
L'exécution du code ci-dessus vous donnera les résultats suivants:
ReportNumber,DetectionScore,PowerShellCommandLine
236547,56,C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -noP -sta -w 1 -enc SQBmACgAJABQAFMAVgBFAFIAcwBJAG8AbgBUAGEAYgBMAGUALgBQA Abréviation
Recommended Posts