Размер шрифта
-
+

Защита от хакеров корпоративных сетей - стр. 93


>read(4, “hello\n”, 512) = 6

>write(1, “hello\n”, 6) = 6

>read(4, “”, 512) = 0

>close(4) = 0

>close(1) = 0

>_exit(0) = ?


В заключение cat пытается прочитать 512 байтов из файла (читает 6) и выводит их на экран (который описан STDOUT с дескриптором файла 1). При повторной попытке прочитать очередные 512 байтов файла читается 0 байт, что свидетельствует о достижении конца файла. В результате файл закрывается, дескриптор файла освобождается и выполняется нормальный выход (признаком нормального выхода является нулевой код завершения).

Для демонстрации читателю представляем очень простой пример. Логика работы команды cat очень проста и легко восстанавливается. На псевдокоде команду cat можно записать следующим образом:


>int count, handle

>string contents

>handle = open (argv[1])

>while (count = read (handle, contents, 512))

>write (STDOUT, contents, count)

>exit (0)


Для сравнения приведем результат выполнения утилиты truss для той же самой команды, выполненной в системе Solaris 7 на машине (x86):


>execve(“/usr/bin/cat”, 0x08047E50, 0x08047E5C) argc = 2

>open(“/dev/zero”, O_RDONLY) = 3

>mmap(0x00000000, 4096, PROT_READ|PROT_WRITE|PROT_EXEC,

>MAP_PRIVATE, 3, 0) = 0xDFBE1000

>xstat(2, “/usr/bin/cat”, 0x08047BCC) = 0

>sysconfig(_CONFIG_PAGESIZE) = 4096

>open(“/usr/lib/libc.so.1”, O_RDONLY) = 4

>fxstat(2, 4, 0x08047A0C) = 0

>mmap(0x00000000, 4096, PROT_READ|PROT_EXEC, MAP_PRIVATE, 4,

>0) = 0xDFBDF000

>mmap(0x00000000, 598016, PROT_READ|PROT_EXEC, MAP_PRIVATE,

>4, 0) = 0xDFB4C000

>mmap(0xDFBD6000, 24392, PROT_READ|PROT_WRITE|PROT_EXEC,

>MAP_PRIVATE|MAP_FIXED, 4, 561152) = 0xDFBD6000

>mmap(0xDFBDC000, 6356, PROT_READ|PROT_WRITE|PROT_EXEC,

>MAP_PRIVATE|MAP_FIXED, 3, 0) = 0xDFBDC000

>close(4) = 0

>open(“/usr/lib/libdl.so.1”, O_RDONLY) = 4

>fxstat(2, 4, 0x08047A0C) = 0

>mmap(0xDFBDF000, 4096, PROT_READ|PROT_EXEC,

>MAP_PRIVATE|MAP_FIXED, 4, 0) = 0xDFBDF000

>close(4) = 0

>close(3) = 0

>sysi86(SI86FPHW, 0xDFBDD8C0, 0x08047E0C, 0xDFBFCEA0)

>= 0x00000000

>fstat64(1, 0x08047D80) = 0

>open64(“test”, O_RDONLY) = 3

>fstat64(3, 0x08047CF0) = 0

>llseek(3, 0, SEEK_CUR) = 0

>mmap64(0x00000000, 6, PROT_READ, MAP_SHARED, 3, 0)

>= 0xDFB4A000

>read(3, “ h”, 1) = 1

>memcntl(0xDFB4A000, 6, MC_ADVISE, 0x0002, 0, 0) = 0

>write(1, “ h e l l o\n”, 6) = 6

>llseek(3, 6, SEEK_SET) = 6

>munmap(0xDFB4A000, 6) = 0

>llseek(3, 0, SEEK_CUR) = 6

>close(3) = 0

>close(1) = 0

>llseek(0, 0, SEEK_CUR) = 296569

>_exit(0)


Проанализировав конец протокола, можно заметить, что в Solaris команда cat выполняется несколько по-другому. Различие проявляется в том, что в Solaris ош использует проецируемый в память файл для передачи диапазона адресов непосредственно вызову функции write. Эксперимент с большим файлом (результаты которого здесь не приведены) выявил цикл запросов между вызовами функций

Страница 93