A więc tak:
1. Kod modułu by się przydał, gdyż jeśli moduł robi coś w rodzaju:
copy_from_user(buf_od_usera, buf_docelowy, 100000);
A buf_docelowy ma na przykład 4096 bajty, to można shellcode umieścić w buforze i w dodatku nie martwić się o bajty zerwoe występujące w shellcode. Jeśli użyta jset funckja strcpy, to wtedy nie może być bajtów zerowych w shellcodzie.
2. Shellcode nie może być taki jak dla aplikacji user mode. Musi robić coś w rodzaju:
Kod:
current->parent->uid = 0;
current->parent->euid = 0;
current->parent->gid = 0;
current->parent->egid = 0;
Do tego dochodzi problem wersji jądra. W kernelu >= 2.6.29 struktura task_struct(current jest tą strukturą, tak samo jak current->parent) nie ma pól uid, euid itp. Są one w strukturze cred, która jest częścią task_struct. W związku z tym powyżej przedstawiona część shellcode'u nie zadziała. W dodatku aby zmienić wartości tych pól potrzeba funkcji prepare_creds i commit_creds. Przykład:
Kod:
struct cred *new = prepare_creds();
new->uid = new->euid = 0;
new->gid = new->egid = 0;
commit_creds(new);
Funkcja prepare_creds zwraca wskaźnik do struktury creds aktualnego procesu, a trzeba zmienić wartości uid, gid itp. dla rodzica, gdyż proces exploitujący zostanie zabity przez jądro.
Tzn, że aby uzyskać prawa roota exploit musi robić coś takiego:
Shellcode jest przechowywany w pewnym buforze. Proces główny tworzy funkcją fork proces potomny. Proces potomny wykorzystuje buffer overflow "wysyłając" do jądra takie dane, żeby shellcode znalazł się w buforze jądra(buf_docelowy) a kopia EIP została nadpisana adresem tego bufora. W efekcie zostanie wykonany kod shellcode'u. Jądro zabije potomka, ale wcześniej zwiększono przywileje procesu rodzica. Rodzic odpala powłokę - mamy roota. Uff...
Coż, przed tobą niełatwe zadanie. Musisz stworzyć shellcode opierający się na moim fragmencie, w przypadku niemożności występowania bajtów zerowych wyeliminować je z kodu shellcode, wyciągnąć coś sensownego z mojego powyższego bełkotu, poprawić ewentualne błędy merytoryczne powyższego opisu(w końcu nie jestem nieomylny) napisać exploita, uruchomić i modlić się, żeby zadziałał.
Co gorsza nie jestem pewny jak skompilować shellcode tak, żeby jego kod dało się "wstrzyknąć".
Good luck
EDIT:
O, już chyba wiem:
kompilujesz:
Kod:
#include <linux/shed.h>
void shellcode(void)
{
current->parent->uid = 0;
current->parent->euid = 0;
current->parent->gid = 0;
current->parent->egid = 0;
}
Jako moduł jądra. Jak by co MAkefile:
Kod:
obj-m += shellcode.o
all:
make -C /lib/modules/$(shell uname -r)/build M=${PWD} modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=${PWD} clean
objdump -d shellcode.ko
W wyniku znajdują się hexy funkcji shellcode. Kopijuesz je i to one są wstrzykiwanym kodem.