[Cuando la inteligencia artificial se encuentra con la seguridad] 8. Ejemplos detallados de clasificación de familias maliciosas basadas en secuencia API y aprendizaje automático

Como probablemente sepa, el autor compartirá cada vez menos artículos sobre seguridad de redes en el futuro. Pero si quieres aprender la aplicación de la inteligencia artificial y la seguridad, tendrás beneficios: el autor recreará una serie de blogs "Cuando la inteligencia artificial se encuentra con la seguridad", presentará en detalle los artículos y prácticas relacionados con la inteligencia artificial y la seguridad, y comparta varios casos que involucran detección de códigos maliciosos, identificación de solicitudes maliciosas, detección de intrusiones, ejemplos contradictorios, etc. Solo quiero ayudar mejor a los principiantes y compartir nuevos conocimientos de forma más sistemática. Esta serie de artículos será más centrada, más académica y más profunda, y también es la historia de lento crecimiento del autor. De hecho, es difícil cambiar de especialidad y la seguridad del sistema también es un hueso duro de roer, pero intentaré ver cuánto puedo aprender en los próximos cuatro años. Disfruten el proceso, vayamos juntos ~

El artículo anterior presentó conjuntos de datos relacionados con la seguridad para que todos los descarguen y experimenten, incluidas URL maliciosas, análisis de tráfico, detección de nombres de dominio, malware, clasificación de imágenes, spam, etc. Este artículo explicará cómo aprender las características de secuencia API extraídas y crear un algoritmo de aprendizaje automático para clasificar familias maliciosas, que también es una tarea o trabajo típico en el campo de la seguridad. Artículo básico, espero que te sea útil ~

Como novato en seguridad de redes, el autor comparte algunos tutoriales básicos de autoaprendizaje para todos, principalmente notas en línea, espero que les guste. Al mismo tiempo, espero que puedan operar y progresar conmigo. En el futuro, aprenderé más sobre seguridad de IA y conocimientos de seguridad de sistemas y compartiré experimentos relacionados. En resumen, espero que esta serie de artículos sea de ayuda para los bloggers. No es fácil escribir artículos. Si no te gusta, no lo rocíes, ¡gracias! Si el artículo te resulta útil, será la mayor motivación para mi creación. Me gusta, comentarios y chats privados son todos aceptables. ¡Trabajemos juntos!

Recomendación anterior:

Recursos de github del autor:


1. Análisis de malware

El análisis de malware o código malicioso suele incluir análisis estático y análisis dinámico. Los tipos de funciones se pueden dividir en funciones estáticas y funciones dinámicas según si el código malicioso se ejecuta en el entorno del usuario o en el entorno de simulación.

Entonces, ¿cómo extraer características estáticas o dinámicas del malware? Por lo tanto, la primera parte presentará brevemente las características estáticas y dinámicas.

1. Funciones estáticas

Las características que en realidad no funcionan generalmente incluyen:

  • código de bytes: El código binario se convierte en código de bytes, una característica relativamente primitiva sin ningún procesamiento.
  • formulario IAT: La parte más importante de la estructura PE, que declara algunas funciones y sus ubicaciones, que es conveniente para importar cuando se ejecuta el programa. Las tablas y funciones están relativamente relacionadas
  • tabla de permisos de Android: Si su APLICACIÓN declara algunos permisos que las funciones no utilizan, puede haber propósitos maliciosos, como información del teléfono móvil
  • personajes imprimibles: Convierta código binario a código ASCII y realice estadísticas relacionadas
  • IDA desmonta el bloque de salto: El bloque de salto cuando las herramientas IDA están depurando y se procesa como datos de secuencia o datos de gráficos.
  • Funciones API de uso común
  • Imágenes de malware

Método de extracción de características estáticas:


2. Funciones dinámicas

Las funciones equivalentes a estáticas requieren más tiempo y realmente necesitan ejecutar el código. Generalmente incluye:
-Relación de llamada API: Características más obvias, a qué API se llaman y expresan las funciones correspondientes
:gráfico de flujo de control: Comúnmente utilizado en ingeniería de software, el aprendizaje automático lo representa como un vector de clasificación
.diagrama de flujo de datos: Comúnmente utilizado en ingeniería de software, el aprendizaje automático lo representa como un vector de clasificación.

Método de extracción de características dinámicas:


2. Detección de familias maliciosas basada en regresión logística

La serie anterior de artículos detallaba cómo extraer características estáticas y dinámicas del malware, incluidas secuencias API. A continuación, crearemos un modelo de aprendizaje automático para aprender secuencias API para lograr la clasificación. El proceso básico es el siguiente:

inserte la descripción de la imagen aquí

1. Conjunto de datos

El conjunto de datos completo incluye muestras de 5 tipos de familias maliciosas, cada muestra pasó a través de secuencias API dinámicas extraídas con éxito por herramientas CAPE anteriores. La distribución de los conjuntos de datos es la siguiente: (se recomienda a los lectores que extraigan muestras de sus propios conjuntos de datos, incluidos BIG2015, BODMAS, etc.)

familia maliciosa categoría cantidad Conjunto de entrenamiento equipo de prueba
AAAAA clase 1 352 242 110
BBBB clase 2 335 235 100
CCCC clase3 363 243 120
DDDDD clase4 293 163 130
EEEE clase5 548 358 190

El conjunto de datos se divide en conjunto de entrenamiento y conjunto de prueba, como se muestra en la siguiente figura:

inserte la descripción de la imagen aquí

El conjunto de datos incluye principalmente cuatro campos, a saber, número de serie, categoría de familia maliciosa, valor Md5, secuencia API o característica.

inserte la descripción de la imagen aquí

Cabe señalar que el proceso de extracción de características implica una gran cantidad de trabajo de limpieza y preprocesamiento de datos, y los lectores deben completarlo de acuerdo con las necesidades reales. Por ejemplo, filtrar código que extrae características que son valores nulos.

#coding:utf-8
#By:Eastmount CSDN 2023-05-31
import csv
import re
import os

csv.field_size_limit(500 * 1024 * 1024)
filename = "AAAA_result.csv"
writename = "AAAA_result_final.csv"
fw = open(writename, mode="w", newline="")
writer = csv.writer(fw)
writer.writerow(['no', 'type', 'md5', 'api'])
with open(filename,encoding='utf-8') as fr:
    reader = csv.reader(fr)
    no = 1
    for row in reader: #['no','type','md5','api']
        tt = row[1]
        md5 = row[2]
        api = row[3]
        #print(no,tt,md5,api)
        #api空值的过滤
        if api=="" or api=="api":
            continue
        else:
            writer.writerow([str(no),tt,md5,api])
            no += 1
fr.close()

2. Construcción del modelo

Dado que el algoritmo de aprendizaje automático es relativamente simple, aquí solo se proporcionan los códigos clave. Además, las representaciones de características de uso común incluyen TF-IDF y Word2Vec. Aquí, TF-IDF se usa para calcular el vector de características. Los lectores pueden probar Word2Vec para finalmente lograr la clasificación familiar y obtener un valor Acc de 0.6215.

# -*- coding: utf-8 -*-
# By:Eastmount CSDN 2023-06-01
import os
import csv
import time
import numpy as np
import seaborn as sns
from sklearn import metrics
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.preprocessing import LabelEncoder, OneHotEncoder
from sklearn.model_selection import train_test_split
from sklearn.decomposition import PCA
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report

start = time.clock()
csv.field_size_limit(500 * 1024 * 1024)

#---------------------------第一步 加载数据集------------------------
#训练集
file = "train_dataset.csv"
label_train = []
content_train = []
with open(file, "r") as csv_file:
    csv_reader = csv.reader(csv_file)
    header = next(csv_reader)
    for row in csv_reader:
        label_train.append(row[1])
        value = str(row[3])
        content_train.append(value)
print(label_train[:2])
print(content_train[:2])

#测试集
file = "test_dataset.csv"
label_test = []
content_test = []
with open(file, "r") as csv_file:
    csv_reader = csv.reader(csv_file)
    header = next(csv_reader)
    for row in csv_reader:
        label_test.append(row[1])
        value = str(row[3])
        content_test.append(value)
print(len(label_train),len(label_test))
print(len(content_train),len(content_test)) #1241 650

#---------------------------第二步 向量转换------------------------
contents = content_train + content_test
labels = label_train + label_test

#计算词频 min_df max_df
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(contents)
words = vectorizer.get_feature_names()
print(words[:10])
print("特征词数量:",len(words))

#计算TF-IDF
transformer = TfidfTransformer()
tfidf = transformer.fit_transform(X)
weights = tfidf.toarray()

#---------------------------第三步 编码转换------------------------
le = LabelEncoder()
y = le.fit_transform(labels)
X_train, X_test = weights[:1241], weights[1241:]
y_train, y_test = y[:1241], y[1241:]

#---------------------------第四步 分类检测------------------------
clf = LogisticRegression(solver='liblinear')
clf.fit(X_train, y_train)
pre = clf.predict(X_test)
print(clf)
print(classification_report(y_test, pre, digits=4))
print("accuracy:")
print(metrics.accuracy_score(y_test, pre))

#计算时间
elapsed = (time.clock() - start)
print("Time used:", elapsed)

El resultado de salida se muestra en la siguiente figura:

1241 650
1241 650
['__anomaly__', 'accept', 'bind', 'changewindowmessagefilter', 'closesocket', 'clsidfromprogid', 'cocreateinstance', 'cocreateinstanceex', 'cogetclassobject', 'colescript_parsescripttext']
特征词数量: 269
LogisticRegression(solver='liblinear')
              precision    recall  f1-score   support

           0     0.5398    0.5545    0.5471       110
           1     0.6526    0.6200    0.6359       100
           2     0.6596    0.5167    0.5794       120
           3     0.8235    0.5385    0.6512       130
           4     0.5665    0.7842    0.6578       190

    accuracy                         0.6215       650
   macro avg     0.6484    0.6028    0.6143       650
weighted avg     0.6438    0.6215    0.6199       650

accuracy:
0.6215384615384615
Time used: 2.2597622

3. Detección de familias maliciosas basada en SVM

1. modelo SVM

La idea central del algoritmo de clasificación SVM es encontrar un hiperplano que cumpla con los requisitos de clasificación en dimensiones altas mediante el establecimiento de una determinada función central, de modo que los puntos en el conjunto de entrenamiento estén lo más lejos posible de la superficie de clasificación, es decir es decir, encontrar una superficie de clasificación que haga que sus dos lados El espacio en blanco sea el más grande. Como se muestra en la Figura 19.16, las muestras de entrenamiento en el hiperplano más cercano a la superficie de clasificación y paralelo a la superficie de clasificación óptima entre los dos tipos de muestras se denominan vectores de soporte.

inserte la descripción de la imagen aquí

El algoritmo de clasificación SVM se implementa en el paquete de aprendizaje automático Sklearn svm.SVC, a saber, C-Support Vector Classification, que se implementa en función de libsvm. El método de construcción es el siguiente:

SVC(C=1.0, 
	cache_size=200, 
	class_weight=None, 
	coef0=0.0,
	decision_function_shape=None, 
	degree=3, 
	gamma='auto', 
	kernel='rbf',
	max_iter=-1, 
	probability=False, 
	random_state=None, 
	shrinking=True,
	tol=0.001, 
	verbose=False)

El algoritmo SVC incluye principalmente dos pasos:

  • entrenamiento :nbrs.fit(data, target)
  • Pronóstico :pre = clf.predict(data)

2. Implementación del código

A continuación solo se proporciona el código clave de SVM para realizar la clasificación de familias maliciosas. Este algoritmo también es un modelo comúnmente utilizado en diversas tareas de seguridad. Cabe señalar que los resultados de la predicción se guardan en un archivo aquí. En experimentos reales, se recomienda guardar más datos del proceso experimental, para que pueda comparar mejor varios rendimientos y reflejar la contribución del artículo.

# -*- coding: utf-8 -*-
# By:Eastmount CSDN 2023-06-01
import os
import csv
import time
import numpy as np
import seaborn as sns
from sklearn import svm
from sklearn import metrics
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.preprocessing import LabelEncoder, OneHotEncoder
from sklearn.model_selection import train_test_split
from sklearn.decomposition import PCA
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report

start = time.clock()
csv.field_size_limit(500 * 1024 * 1024)

#---------------------------第一步 加载数据集------------------------
#训练集
file = "train_dataset.csv"
label_train = []
content_train = []
with open(file, "r") as csv_file:
    csv_reader = csv.reader(csv_file)
    header = next(csv_reader)
    for row in csv_reader:
        label_train.append(row[1])
        value = str(row[3])
        content_train.append(value)
print(label_train[:2])
print(content_train[:2])

#测试集
file = "test_dataset.csv"
label_test = []
content_test = []
with open(file, "r") as csv_file:
    csv_reader = csv.reader(csv_file)
    header = next(csv_reader)
    for row in csv_reader:
        label_test.append(row[1])
        value = str(row[3])
        content_test.append(value)
print(len(label_train),len(label_test))
print(len(content_train),len(content_test)) #1241 650

#---------------------------第二步 向量转换------------------------
contents = content_train + content_test
labels = label_train + label_test

#计算词频 min_df max_df
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(contents)
words = vectorizer.get_feature_names()
print(words[:10])
print("特征词数量:",len(words))

#计算TF-IDF
transformer = TfidfTransformer()
tfidf = transformer.fit_transform(X)
weights = tfidf.toarray()

#---------------------------第三步 编码转换------------------------
le = LabelEncoder()
y = le.fit_transform(labels)
X_train, X_test = weights[:1241], weights[1241:]
y_train, y_test = y[:1241], y[1241:]

#---------------------------第四步 分类检测------------------------
clf = svm.LinearSVC()
clf.fit(X_train, y_train)
pre = clf.predict(X_test)
print(clf)
print(classification_report(y_test, pre, digits=4))
print("accuracy:")
print(metrics.accuracy_score(y_test, pre))

#结果存储
f1 = open("svm_test_pre.txt", "w")
for n in pre:
    f1.write(str(n) + "\n")
f1.close()

f2 = open("svm_test_y.txt", "w")
for n in y_test:
    f2.write(str(n) + "\n")
f2.close()

#计算时间
elapsed = (time.clock() - start)
print("Time used:", elapsed)

Los resultados experimentales se muestran en la siguiente figura:

inserte la descripción de la imagen aquí

1241 650
1241 650

['__anomaly__', 'accept', 'bind', 'changewindowmessagefilter', 'closesocket', 'clsidfromprogid', 'cocreateinstance', 'cocreateinstanceex', 'cogetclassobject', 'colescript_parsescripttext']
特征词数量: 269
LinearSVC()
              precision    recall  f1-score   support

           0     0.6439    0.7727    0.7025       110
           1     0.8780    0.7200    0.7912       100
           2     0.7315    0.6583    0.6930       120
           3     0.9091    0.6154    0.7339       130
           4     0.6583    0.8316    0.7349       190

    accuracy                         0.7292       650
   macro avg     0.7642    0.7196    0.7311       650
weighted avg     0.7534    0.7292    0.7301       650

accuracy:
0.7292307692307692
Time used: 2.2672032

4. Detección de familias maliciosas basada en bosques aleatorios

El código clave de esta parte es el siguiente y se complementa con el código de análisis visual.

# -*- coding: utf-8 -*-
# By:Eastmount CSDN 2023-06-01
import os
import csv
import time
import numpy as np
import seaborn as sns
from sklearn import svm
from sklearn import metrics
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.preprocessing import LabelEncoder, OneHotEncoder
from sklearn.model_selection import train_test_split
from sklearn.decomposition import PCA
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap

start = time.clock()
csv.field_size_limit(500 * 1024 * 1024)

#---------------------------第一步 加载数据集------------------------
#训练集
file = "train_dataset.csv"
label_train = []
content_train = []
with open(file, "r") as csv_file:
    csv_reader = csv.reader(csv_file)
    header = next(csv_reader)
    for row in csv_reader:
        label_train.append(row[1])
        value = str(row[3])
        content_train.append(value)
print(label_train[:2])
print(content_train[:2])

#测试集
file = "test_dataset.csv"
label_test = []
content_test = []
with open(file, "r") as csv_file:
    csv_reader = csv.reader(csv_file)
    header = next(csv_reader)
    for row in csv_reader:
        label_test.append(row[1])
        value = str(row[3])
        content_test.append(value)
print(len(label_train),len(label_test))
print(len(content_train),len(content_test)) #1241 650

#---------------------------第二步 向量转换------------------------
contents = content_train + content_test
labels = label_train + label_test

#计算词频 min_df max_df
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(contents)
words = vectorizer.get_feature_names()
print(words[:10])
print("特征词数量:",len(words))

#计算TF-IDF
transformer = TfidfTransformer()
tfidf = transformer.fit_transform(X)
weights = tfidf.toarray()

#---------------------------第三步 编码转换------------------------
le = LabelEncoder()
y = le.fit_transform(labels)
X_train, X_test = weights[:1241], weights[1241:]
y_train, y_test = y[:1241], y[1241:]

#---------------------------第四步 分类检测------------------------
clf = RandomForestClassifier(n_estimators=5)
clf.fit(X_train, y_train)
pre = clf.predict(X_test)
print(clf)
print(classification_report(y_test, pre, digits=4))
print("accuracy:")
print(metrics.accuracy_score(y_test, pre))

#结果存储
f1 = open("rf_test_pre.txt", "w")
for n in pre:
    f1.write(str(n) + "\n")
f1.close()

f2 = open("rf_test_y.txt", "w")
for n in y_test:
    f2.write(str(n) + "\n")
f2.close()

#计算时间
elapsed = (time.clock() - start)
print("Time used:", elapsed)

#---------------------------第五步 可视化分析------------------------
#降维
pca = PCA(n_components=2)
pca = pca.fit(X_test)
xx = pca.transform(X_test)

#画图
plt.figure()
plt.scatter(xx[:,0],xx[:,1],c=y_test, s=50)
plt.title("Malware Family Detection")
plt.show()

El resultado de salida es el siguiente, el efecto alcanzó 0,8092, lo que se siente bastante bien.

1241 650
1241 650
['__anomaly__', 'accept', 'bind', 'changewindowmessagefilter', 'closesocket', 'clsidfromprogid', 'cocreateinstance', 'cocreateinstanceex', 'cogetclassobject', 'colescript_parsescripttext']
特征词数量: 269
RandomForestClassifier(n_estimators=5)
              precision    recall  f1-score   support

           0     0.7185    0.8818    0.7918       110
           1     0.9000    0.8100    0.8526       100
           2     0.7963    0.7167    0.7544       120
           3     0.9444    0.7846    0.8571       130
           4     0.7656    0.8421    0.8020       190

    accuracy                         0.8092       650
   macro avg     0.8250    0.8070    0.8116       650
weighted avg     0.8197    0.8092    0.8103       650

accuracy:
0.8092307692307692
Time used: 2.1914324

Al mismo tiempo, se analizan visualmente cinco tipos de familias maliciosas. Sin embargo, el efecto general es mediocre. Es necesario optimizar aún más el código y las dimensiones para distinguir conjuntos de datos o diagramas de dispersión 3D. Se pide a los lectores que piensen por sí mismos.

inserte la descripción de la imagen aquí


5. Resumen

Este es el final de este artículo, espero que te sea de ayuda. Ocupado mayo, muy ocupado, me gradué del proyecto y escribiré algunos blogs de seguridad después de terminar mi trabajo. Gracias por su apoyo y compañía, especialmente el aliento y el apoyo de su familia. ¡Sigan con el buen trabajo!

  • 1. Análisis de malware
    1. Funciones estáticas
    2. Funciones dinámicas
  • 2. Detección de familias maliciosas basada en regresión logística
    1. Conjunto de datos
    2. Construcción del modelo
  • 3. Detección de familias maliciosas basada en SVM
    1. Modelo SVM
    2. Implementación de código
  • 4. Detección de familias maliciosas basada en bosques aleatorios
  • 5. Resumen

El autor hace las siguientes preguntas, bienvenido a agregar:

  • ¿Cuáles son las características comunes del malware o los binarios? Cuales son las ventajas y desventajas de cada uno.
  • El malware para imágenes en escala de grises es un método común de clasificación familiar, ¿cuáles son sus ventajas y desventajas en comparación con el método propuesto en este artículo?
  • ¿Cómo extraer malware CFG e ICFG? ¿Cómo puede aprenderlo el modelo de aprendizaje automático después de la extracción?
  • ¿Cuáles son los métodos comunes de representación vectorial y cuáles son sus características? ¿Puedes implementar el código para Word2Vec?
  • ¿Cuál es la conexión y diferencia entre el aprendizaje automático y el aprendizaje profundo? Si se crea un modelo de aprendizaje profundo para aprender secuencias API, ¿qué tan efectiva es su detección de familias maliciosas?
  • ¿Dónde está el estado actual de la clasificación de familias de malware o la detección de códigos maliciosos? ¿Cuáles son las características y limitaciones de la industria y la academia, y cómo conectarse mejor para promover el desarrollo del campo?
  • ¿Existe una mejor manera de innovar o romper con la dirección binaria? Cómo mejorar su robustez, mejora semántica e interpretabilidad.
  • ¿Cómo detectar malware de familias desconocidas y cómo rastrear el origen del malware de alta amenaza?
  • ¿Cómo se integra mejor la detección de malware con el hardware y los compiladores subyacentes? Y cómo luchar contra las variantes, la ofuscación y la confrontación.
  • ¿Puede la detección de malware generar variantes rápidamente a través de la tecnología chatGPT? Y cómo contrarrestar el desarrollo de esta tecnología.

El camino de la vida se compone de encrucijadas, juego tras juego, enredos y ganancias y pérdidas. Ganancias y pérdidas, ganancias y pérdidas, diferentes elecciones, diferentes emociones. Aunque estoy cansado y ocupado, ver a Xiao Luoluo es bastante satisfactorio y agradezco a mi familia por su compañía.
Xiao Luo: Papá, has vuelto del trabajo
Yo: ¿Lloraste hoy en el supermercado con tu suegra?
Xiao Luo: Sí, quiero tomar el pastelito de cabello yo solo
Yo: Escuché que el abuelo y la abuela se rieron de mí, de ahora en adelante...
Xiao Luo: ¡De qué sirve que se rían!

Sí, jaja, ¿de qué sirve? El pequeño Luoluo ha crecido y la pequeña monada se ha vuelto un poco traviesa. Recientemente, soy reacio a tomar un taxi, cambiar a un autobús y compartir una motocicleta, pero también confío en comprar billetes de lotería. Nuestros 5 millones de palabras, ¿por qué no seguí a la diosa para comprar una casa en nuestra comunidad en 2017? ? Este año, siento que puedo ganar casi 1 millón de yuanes, lo que me basta para enseñar en Guizhou durante diez años. Todo es un juego, todo es una elección, todo es agridulce, espero que Xiaoluo pueda crecer feliz y saludable, te amo, sigue trabajando, vamos.

inserte la descripción de la imagen aquí

(Por: Eastmount 2023-09-06 noche en Guiyang http://blog.csdn.net/eastmount/ )

Supongo que te gusta

Origin blog.csdn.net/Eastmount/article/details/132708001
Recomendado
Clasificación