El grupo OceanLotus (también conocido como APT32 y APT-C-00) es conocido por sus ataques en el este de Asia. El año pasado, se publicaron varios estudios sobre el trabajo del grupo, incluidos los documentos de
CyberReason , una revisión de
FireEye y una descripción del ataque a los
pozos de
agua de
Volexity . Como podemos ver, el grupo actualiza las puertas traseras, la infraestructura y los vectores de infección.
OceanLotus continúa apuntando a empresas y agencias gubernamentales en el este de Asia. Según la telemetría de ESET, los objetivos prioritarios de OceanLotus están en Vietnam, Laos, Camboya y Filipinas.
Hace unos meses, descubrimos y analizamos una de sus últimas puertas traseras. Implementa varias herramientas que dificultan el análisis y evitan la detección; las discutiremos en una publicación.

Distribución
Los atacantes usan diferentes métodos para convencer a la víctima de lanzar un cuentagotas malicioso.
Extensiones duales e iconos de aplicaciones falsas (Word, PDF, etc.)
Es probable que los goteros se propaguen a través de archivos adjuntos de correo electrónico. Observamos los siguientes nombres de archivo:
-
Mi17 Technical issues - Phonesack Grp.exe
(Mi-17 - Modelo de helicóptero ruso)
-
Chi tiet don khieu nai gui saigontel.exe
(traducido del vietnamita - "detalles del reclamo enviados a Saigontel", Saigontel - compañía de telecomunicaciones vietnamita)
-
Updated AF MOD contract - Jan 2018.exe
-
remove_pw_Reschedule of CISD Regular Meeting.exe
-
Sorchornor_with_PM_-_Sep_2017.exe
-
20170905-Evaluation Table.xls.exe
-
CV_LeHoangThing.doc.exe
(también se encontraron currículums falsos en Canadá)
Todos estos archivos tienen algo en común: lanzar un documento de cebo protegido con contraseña. No está claro si la contraseña está contenida en algún lugar de los datos de la carta transmitida, o si el documento no debe abrirse.
Instaladores falsos
Varios instaladores falsos que se hacen pasar por instaladores o actualizaciones de software han sido vistos en campañas de abrevaderos. Un ejemplo es el instalador de Firefox reempaquetado descrito por 360 Labs en
Freebuf (en chino).
Otra muestra que vimos se llamaba
RobototFontUpdate.exe
. Probablemente se propagó a través de sitios comprometidos, pero no tenemos evidencia suficiente de esto.
Todos los archivos descritos, ya sea que se distribuyeron por correo o se descargaron al visitar un sitio comprometido, entregaron el mismo componente de puerta trasera. En una publicación, analizaremos una muestra de
RobototFontUpdate.exe
y mostraremos cómo se las arregla para ejecutar una carga maliciosa en el sistema.
Análisis técnico
El proceso de instalación y ejecución depende de la ofuscación de múltiples capas, a saber, el cifrado de componentes, la reconstrucción de archivos PE, la carga de código de shell y las técnicas de carga lateral. Este último se describió en el
estudio Korplug anterior de ESET .
Revisión de progreso
El ataque consta de dos partes: un gotero y un vehículo de lanzamiento. Cada paso de cada parte del proceso se explicará en detalle en la sección correspondiente. Los dos diagramas a continuación dan una breve idea del progreso general del malware.
Figura 1. El progreso del cuentagotas
Figura 2. Progreso de la puerta traseraCasi todos estos componentes están ofuscados. La ofuscación se basa en comandos de transición de pares condicionales complementarios. Para cada una de las formas: JZ / JNZ, JP / JNP, JO / JNO, etc., cada par realiza una transición hacia el mismo objetivo. La secuencia se intercala con código basura que usa el puntero de la pila pero no cambia el valor del indicador condicional. Resulta que la transición ocurre dentro de la misma rama. Esto lleva a problemas durante el proceso de descompilación debido al uso de valores de puntero de pila positivos.
Figura 3. Transición condicional complementariaAdemás, algunos elementos básicos del programa agregan una dirección a la pila, después de lo cual terminan en JMP / CALL, mientras que otros elementos básicos agregan dos direcciones y terminan con el comando RET. La segunda adición del elemento es la función llamada, y la primera es la dirección del siguiente elemento básico del programa donde se realizará la transición. Por lo tanto, los elementos básicos del programa se crean sin objetos primarios.
Figura 4. Técnica PUSH / JMPComo resultado de una combinación de dos técnicas de ofuscación, se obtienen gráficos "hermosos":
Figura 5. Ofuscando una secuencia de ejecuciónNotar código basura es bastante simple. Puede ignorarse en el análisis de muestras, si conoce el esquema de la aplicación.
Cuentagotas
Paso 1. Documento de cebo
En los últimos meses, OceanLotus ha utilizado varios señuelos. Uno de ellos es un software falso para actualizar la fuente TrueType
Roboto Slab regular
. Elegir una fuente parece un poco extraño, ya que no admite muchos idiomas de Asia Oriental.
Figura 6. Icono de actualización de fuente RobototFontUpdateCuando se ejecuta, el archivo binario descifra sus recursos (XOR, 128 bytes, clave codificada) y restaura los datos descifrados (LZMA). Archivo legítimo RobotoSlab-Regular.ttf
(SHA1:
912895e6bb9e05af3a1e58a1da417e992a71a324
) se escribe en la carpeta
%temp%
y se inicia utilizando la función Win32 API
ShellExecute
.
Se ejecuta el código de shell descifrado de los recursos. Después de la ejecución, una actualización de fuente falsa implementa otra aplicación cuyo único propósito es eliminar el cuentagotas. Esta aplicación de borrado se
%temp%\[0-9].tmp.exe
como
%temp%\[0-9].tmp.exe
.
Etapa 2. Código de shell
En cada etapa, se usa el mismo shellcode.
El shellcode es un cargador PE personalizado. Restaura el archivo ejecutable en la memoria: descifra todas las secciones y calcula los movimientos necesarios y otras sangrías. El
RtlMoveMemory
usa las tres funciones de la API de Windows:
VirtualAlloc
,
RtlMoveMemory
y
RtlZeroMemory
.
La función
RtlZeroMemory
usa para
RtlZeroMemory
campos en el encabezado PE. Confiar en un volcado de memoria automático fallará, ya que los encabezados MZ / PE están dañados.
El código de shell llama a la función de inicio de sesión PE descifrada y luego a la
DLLEntry
exportación
DLLEntry
.
Etapa 3. El verdadero gotero
{103004A5-829C-418E-ACE9-A7615D30E125}.dll
Este ejecutable descifra recursos utilizando el algoritmo AES en modo CBC a través de la API de Windows. La clave codificada tiene un tamaño de 256 bits. Después del descifrado, los datos comprimidos se descomprimen (algoritmo LZMA).
Si el proceso se inicia con derechos de administrador, el malware proporciona persistencia al crear un servicio. De lo contrario, se usa la clave de registro Run clásica (
HKCU\SOFTWARE\Microsoft\ Windows\CurrentVersion\Run;DeviceAssociationService;rastlsc.exe
).
Si el código del cuentagotas se ejecuta con derechos de administrador, intenta escribir los archivos enumerados a continuación en la carpeta
C:\Program Files\Symantec\Symantec Endpoint Protection\12.1.671.4971.104a\DeviceAssociationService\
, si no, los escribe en la
%APPDATA%\Symantec\Symantec Endpoint Protection\12.1.671.4971.104a\DeviceAssociationService\
:
-
rastlsc.exe
(SHA1:
2616da1697f7c764ee7fb558887a6a3279861fac
, copia de la aplicación legítima Symantec Network Access Control,
dot1xtra.exe
)
-
SyLog.bin
(SHA1:
5689448b4b6260ec9c35f129df8b8f2622c66a45
, puerta trasera encriptada)
-
rastls.dll
(SHA1:
82e579bd49d69845133c9aa8585f8bd26736437b
, un archivo DLL malicioso que
rastlsc.exe
)
La ruta varía de una muestra a otra, pero el diseño es similar. Dependiendo de los derechos, el malware volca los archivos en
%ProgramFiles%
o
%appdata%
. También observamos:
-
\Symantec\CNG Key Isolation\
-
\Symantec\Connected User Experiences and Telemetry\
-
\Symantec\DevQuery Background Discovery Broker Tasks\
Estas rutas son utilizadas por varios productos de Symantec.
Después de lograr la persistencia e implementar el archivo ejecutable en un archivo legítimo,
rastlsc.exe
, se ejecuta utilizando
CreateProcessW
.
También observamos una versión (
{BB7BDEC9-B59D-492E-A4AF-4C7B1C9E646B}.dll
) que ejecuta
rastlsc.exe
con el parámetro
krv
. Discutiremos con más detalle a continuación.
Componente de puerta trasera: relleno de rastlsc.exe
El equipo de OceanLotus utiliza una técnica antigua y conocida en uno de los ejecutables del producto Symantec. La conclusión es utilizar el proceso de cargar una biblioteca de un archivo .exe legítimo y firmado escribiendo una biblioteca maliciosa en la misma carpeta. Esto hará que el comportamiento malicioso parezca legítimo ya que estas acciones se realizan mientras se ejecuta el ejecutable de confianza.
Como se mencionó anteriormente, el archivo legítimo
rastlsc.exe
se restablece y ejecuta.
Importa el archivo
rastls.dll
, que en este caso tiene contenido malicioso.
Figura 7. rastlsc.exe firmado digitalmente de SymantecTambién vimos un relleno usando otros ejecutables legítimos y firmados, incluido
mcoemcpy.exe
de McAfee, que carga
McUtil.dll
. Esta técnica fue utilizada previamente por PlugX, que atrajo la atención de
Vietnam CERT (en vietnamita).
Etapa 1. Llenar la biblioteca, rastls.dll
El nombre interno del archivo dll es
{7032F494-0562-4422-9C39-14230E095C52}.dll
, pero hemos visto otras versiones, por ejemplo,
{5248F13C-85F0-42DF-860D-1723EEAA4F90}.dll
. Todas las funciones exportadas conducen a la ejecución de la misma función.
Figura 8. Todas las exportaciones de rasltls.dll conducen a una única funciónExport intenta leer el archivo
SyLog.bin
ubicado en la misma carpeta. Otras versiones han intentado abrir el archivo
OUTLFLTR.DAT
. Si el archivo existe, se descifrará utilizando el algoritmo AES en modo CBC con una clave codificada de 256 bits, y luego los datos comprimidos recibidos se descomprimirán (compresión LZMA).
La variante
McUtil.dll
utiliza una técnica diferente. A primera vista, la función principal no hace nada malicioso, pero de hecho reemplaza la sección
.text
del archivo legítimo
mcoemcpy.exe
, un archivo binario. Genera un shellcode cuya tarea es llamar a una función para leer el shellcode cifrado de la segunda etapa del archivo
mcscentr.adf
.
El siguiente pseudocódigo se usa para crear código de shell:
x = False i = 0
buff = genRandom()
opc1 = [0x58,0x59,0x5a,0x5b]
opc2 = [0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57]
opc3 = [0x90,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,
0x49,0x4a,0x4b]
while i < len(buff):
currentChar = buff[i] if currentChar < 0xc8:
buff[i] = opc1[currentChar % len(opc1)]
else:
if x:
buff[i] = opc2[currentChar % len(opc2)]
else:
buff[i] = opc3[currentChar % len(opc3)] x = x == False
i+=1
A continuación, en la figura, puede ver una lista del resultado del ensamblador:
Figura 9. Shellcode generadoPasos 2–4. Shellcode, launcher y shellcode nuevamente
El
{E1E4CBED-5690-4749-819D-24FB660DF55F}.dll
descifra y descarga la
{E1E4CBED-5690-4749-819D-24FB660DF55F}.dll
. La biblioteca carga recursos e intenta iniciar el servicio DeviceAssociationService. La información descifrada también contiene un código shell. Este último descifra la etapa final: una puerta trasera.
La variante
{92BA1818-0119-4F79-874E-E3BF79C355B8}.dll
comprueba si
rastlsc.exe
ejecutó con
krv
como primer parámetro. Si es así, se crea una tarea y
rastlsc.exe
se ejecuta nuevamente, pero sin este parámetro.
Etapa 5. Puerta trasera
{A96B020F-0000-466F-A96D-A91BBF8EAC96}.dll
Primero, el malware intenta descargar sus recursos y descifrarlos usando el algoritmo RC4. Los recursos resultantes contienen datos utilizados para configurar la puerta trasera. El formato de configuración no es difícil de encontrar. Usando Kaitai struct y su estructura damper, obtenemos lo siguiente:
Figura 10. Estructura de configuraciónNota : con la excepción de la línea domain_encoding_str y la biblioteca httpprov, los datos cambian de muestra a muestra. Las claves de registro son casi las mismas, pero tienen un esquema similar:
\HKCU\SOFTWARE\Classes\AppX[a-f0-9]{32}
, nada notable.
El programa malicioso recibe los primeros 10 bytes del nombre de usuario (UTF-16), los codifica con la cadena de tres letras
mutex_encoding_str
en UTF-16 y los codifica en hexadecimal. El resultado se usa como el nombre del mutex. Por ejemplo, para un usuario cuyo nombre comienza con
abc
y una clave en forma de
vwx
, el mutex será
\Sessions\1\BaseNamedObjects\170015001b
.
La puerta trasera incluye un cargador PE que carga la biblioteca
HTTPProv.dll
en la memoria, llama al punto de entrada y luego llama a la función de exportación
CreateInstance
.
Comunicación
La puerta trasera utiliza el protocolo de comunicación TCP estándar a través del puerto
25123
. Para obtener la dirección IP del servidor, la puerta trasera primero crea una consulta DNS específica.
El programa malicioso selecciona uno de los tres dominios de la configuración y agrega un subdominio especial que se genera utilizando dos valores. El primer valor es el nombre de la computadora con una longitud de 16 bytes. El segundo es una ID de versión de cuatro bytes. El siguiente código de Python 2 es un algoritmo de codificación:
letters=domain_encoding_str # “ghijklmnop” hex_pc_name=pc_name.encode(“UTF-16LE”).encode(“hex”) s=''
for c in hex_pc_name:
if 0x2f < ord(c) < 0x3a:
s+=letters[ord(c) - 0x30]
else:
s+=c
Por ejemplo, si el nombre de la computadora es
random-pc
y la ID de la versión es 0x0a841523, se genera el siguiente dominio:
niggmhggmeggmkggmfggmdggidggngggmjgg.ijhlokga.dwarduong[.]com
La siguiente expresión regular se puede utilizar para etiquetar el servidor C&C de esta puerta trasera:
[ghijklmnopabcdef]{4-60}\.[ghijklmnopabcdef]{8}\.[az]+\.[az]+
Si la dirección IP pertenece a un dominio específico, el malware intenta establecer una conexión TCP a través del puerto
25123
. Cada una de las muestras tiene tres nombres de dominio diferentes que se utilizan para encontrar el servidor de C&C.
El proceso de comunicación se cifra mediante RC4 y se comprime con LZMA. Es posible descifrar el tráfico, ya que la clave se agrega al comienzo de los paquetes. El formato es el siguiente:
[ RC4 (4 )][ ]
Cada byte clave es generado por la función
rand
. Después de descifrar y desempaquetar el paquete, los datos tienen el siguiente formato:
[dw:][dw:][dw: ][dw: ][dw:] [dw:]
La primera vez que el cliente se conecta al servidor, se transmite el UUID, que se utiliza como identificador de sesión. Este último se almacena en la clave de registro como datos binarios:
HKCU\SOFTWARE\Classes\ AppXc52346ec40fb4061ad96be0e6cb7d16a\DefaultIcon
Como dijimos anteriormente, la puerta trasera también contiene una biblioteca llamada
HTTPprov
. Se utiliza como una forma alternativa de comunicarse con el servidor. El archivo DLL envía una solicitud POST a través de HTTP. También es compatible con HTTPS y proxies con SOCKS5, SOCKS4a y SOCKS4. La biblioteca está estáticamente vinculada con
libcurl
.
Después de la inicialización, se creará una entrada en el registro: un comando para que la puerta trasera use más HTTP para comunicarse con el servidor de comandos:
HKCU\SOFTWARE\Classes\ CLSID{E3517E26-8E93-458D-A6DF-8030BC80528B}
.
Se utiliza la aplicación cliente estándar:
Mozilla/4.0 ( ; MSIE 8.0; Windows NT 6.0; Trident/4.0)
.
La característica principal de esta biblioteca es un algoritmo de cifrado especial para un identificador universal de recursos. La parte de recursos del URI se crea utilizando el siguiente pseudocódigo:
buffEnd = ((DWORD)genRand(4) % 20) + 10 + buff; while (buff < buffEnd){
b=genRand(16);
if (b[0] - 0x50 > 0x50)
t=0;
else
*buf++= UPPER(vowels[b[1] % 5]);
v=consonants[b[1]%21]); if (!t)
v=UPPER(v);
*buff++= v;
if (v!='h' && b[2] - 0x50 < 0x50)
*buff++= 'h';
*buff++= vowels[b[4] % 5];
if (b[5] < 0x60)
*buff++= vowels[b[6] % 5];
*buff++= consonants[b[7] % 21];
if (b[8] < 0x50)
*buff++= vowels[b[9] % 5];
*buff++= '-';
};
*buff='\0';
Nota : para mayor claridad, la parte responsable de verificar la longitud de la cadena se ha eliminado del código.
Para obtener el identificador de la cadena generada, se agregan dos números usando un algoritmo especial de verificación de suma:
checksum=crc32(buff)
num2=(checksum >> 16) + (checksum & 0xffff) * 2
num1=(num2 ^ 1) & 0xf
URL=GENERATED_DOMAIN+ “/” + num1 + “/” + num2 + “-” + buff
Al agregar el generador de URI de la biblioteca
HTTPprov
, obtenemos la siguiente URL:
hXXp://niggmhggmeggmkggmfggmdggidggngggmjgg.ijhlokga.aisicoin[.]com/ 13/139756-Ses-Ufali-L
Equipos
Después de recibir el identificador de sesión SESSIONID, la puerta trasera crea una huella digital del sistema. El paquete se construye de la siguiente manera (sangría en el paquete - descripción):
0x000 - bytes: el valor cambia en cada versión
0x001 - 0x01: byte codificado
0x002 - bool: privilegios elevados
0x003 - dword: ID de versión
0x007 - cadena (UTF-16), nombre de la computadora (máx. 0x20)
0x027 - cadena (UTF-16), nombre de usuario
0x079 : el resultado de una consulta de registro en
HKLM\SOFTWARE\Microsoft\Windows NT\ CurrentVersion
valores:
ProductName
,
CSDVersion
,
CurrentVersion
,
ReleaseId
,
CurrentBuildNumber
y el resultado de llamar a
IsWow64Process (x86|x64)
0x179 : el formato posterior de la cadena% s (% s); reemplazado por (
GetVolumeInformationW:VolumeNameBuffer
),
VolumePathNames
0x279 - Disco físico, control de E / S Dispositivo PhysicalDriveIOControl 0x2D1400 (IOCTL_STORAGE_QUERY_ PROPERTY) (VolSerialNumber)
0x379 - wmi
SELECT SerialNumber FROM Win32_BaseBoard
0x3f9 :
obtenga la fecha y hora actuales GetSystemTimeAsFileTime
0x400 - bool: desconocido
0x401 - dword: recibido después de descifrar el recurso
Aquí hay un ejemplo de una huella digital del sistema:
Figura 11. Huella digital del sistemaEsta es una puerta trasera completa que proporciona a sus operadores una serie de características: manipulación del archivo, registro y procesos, descarga de componentes adicionales, obtención de una huella digital del sistema. A continuación se muestran los números y las descripciones de los comandos compatibles:
0 - huella digital
1: establece la ID de sesión
2 - creando un proceso y obteniendo un resultado (usando canales de programa)
3 - establece el contador de intentos de conexión
4 - pospone el tiempo de votación
5 - lee un archivo o clave de registro y considera MD5
6 - creando un proceso
7 - crea un archivo, entrada de registro o transmisión en memoria
8 - escribe en el registro
9 - sondea el registro
10 - busca archivos en el sistema
11 - transfiere archivos a otro directorio
12 - elimina archivos del disco
13 - obtener una lista de discos marcados en el sistema usando la función
GetLogicalDriveStringW
14 - crea un directorio
15 - elimina el directorio
16 - lee el archivo desde el desplazamiento
17 - llama al cargador PE (cambiar a comunicación a través de
HTTPprov
)
18 - [desconocido]
19-0: sondeo del valor en el registro; 1: implementación e implementación del programa
20 - establece la variable de entorno
21 - lanza shellcode en un nuevo hilo
22 - devuelve la variable de entorno
23 en la nueva versión: se reinicia si la variable de entorno APPL no existe
Conclusión
OceanLotus permanece altamente activo y continúa actualizando el kit de herramientas.
El grupo busca ocultar sus actividades, para esto los atacantes seleccionan cuidadosamente a las víctimas, limitan la propagación de malware, usan varios servidores para no llamar la atención sobre el mismo dominio o dirección IP. El descifrado del componente que se está implementando y la técnica de carga lateral, a pesar de su popularidad generalizada, hacen posible evitar la detección, ya que el trabajo de los atacantes en este caso se disfraza como una aplicación legítima.
Indicadores de compromiso (IoC)
Muestras
Tabla 1: cuentagotas

Tabla 2: Bibliotecas

Red
Direcciones IP
46.183.220.81
46.183.220.82
46.183.222.82
46.183.222.83
46.183.222.84
46.183.223.106
46.183.223.107
74.121.190.130
74.121.190.150
79.143.87.230