А сколько нам отличий чудных
От: Vamp Россия  
Дата: 03.02.10 14:49
Оценка:
Обнаружил, что под Solaris и Linux вызов ldd реально вызывает анализируемый процесс. Таким образом, нарушается концепция защиты, что не может не огорчать.
Доказательство под Солярис:


truss -t "fork, exec, setuid" -f ldd /db/bin/ls

3339:   execve("/usr/bin/ldd", 0xFFBED824, 0xFFBED830)  argc = 2
3339:   fork()                                          = 3340
3340:   fork()          (returning as child ...)        = 3339
3340:   execve("/db/bin/ls", 0xFFBED5F8, 0x000254D8)  argc = 1
        libgen.so.1 =>   /usr/lib/libgen.so.1
        libc.so.1 =>     /usr/lib/libc.so.1
        libdl.so.1 =>    /usr/lib/libdl.so.1
        /usr/platform/SUNW,Ultra-Enterprise/lib/libc_psr.so.1


Я опечален.
Да здравствует мыло душистое и веревка пушистая.
Re: А сколько нам отличий чудных
От: SergH Россия  
Дата: 03.02.10 15:09
Оценка:
Здравствуйте, Vamp, Вы писали:

V>Обнаружил, что под Solaris и Linux вызов ldd реально вызывает анализируемый процесс. Таким образом, нарушается концепция защиты, что не может не огорчать.


FreeBSD 7.2

$ truss -fa -o truss.txt ldd /bin/sh 
/bin/ls:
        libutil.so.7 => /lib/libutil.so.7 (0xbbe38000)
        libncurses.so.7 => /lib/libncurses.so.7 (0xbbf47000)
        libc.so.7 => /lib/libc.so.7 (0xbc093000)
truss: can not attach to target process: No such process

$ cat trs.txt
41390: __sysctl(0x7fffffffe730,0x2,0x7fffffffe74c,0x7fffffffe740,0x0,0x0) = 0 (0x0)
41390: mmap(0x0,608,PROT_READ|PROT_WRITE,MAP_ANON,-1,0x0) = 3151130624 (0xbbd27000)
41390: munmap(0xbbd27000,608)                    = 0 (0x0)
41390: __sysctl(0x7fffffffe7a0,0x2,0xbbe2f3c8,0x7fffffffe798,0x0,0x0) = 0 (0x0)
41390: mmap(0x0,32768,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON,-1,0x0) = 3151130624 (0xbbd27000)
41390: issetugid(0xbbd28015,0xbbd22b18,0xbbe32d10,0xbbe32ce0,0x54fd,0x7fffffffe798) = 0 (0x0)
41390: open("/etc/libmap.conf",O_RDONLY,0666)    ERR#2 'No such file or directory'
41390: open("/var/run/ld-elf.so.hints",O_RDONLY,057) = 4 (0x4)
41390: read(4,"Ehnt\^A\0\0\0\M^@\0\0\0\M-Z\0\0"...,128) = 128 (0x80)
41390: lseek(4,0x80,SEEK_SET)                    = 128 (0x80)
41390: read(4,"/lib:/usr/lib:/usr/lib/compat:/u"...,218) = 218 (0xda)
41390: close(4)                                  = 0 (0x0)
41390: access("/lib/libc.so.7",0)                = 0 (0x0)
41390: open("/lib/libc.so.7",O_RDONLY,027370571240) = 4 (0x4)
41390: fstat(4,{ mode=-r--r--r-- ,inode=212933,size=1134904,blksize=4096 }) = 0 (0x0)
41390: read(4,"\^?ELF\^B\^A\^A\t\0\0\0\0\0\0\0"...,4096) = 4096 (0x1000)
41390: mmap(0x0,2244608,PROT_READ|PROT_EXEC,MAP_PRIVATE|MAP_NOCORE,4,0x0) = 3152228352 (0xbbe33000)
41390: mprotect(0xbbf23000,4096,PROT_READ|PROT_WRITE|PROT_EXEC) = 0 (0x0)
41390: mprotect(0xbbf23000,4096,PROT_READ|PROT_EXEC) = 0 (0x0)
41390: mmap(0xbc023000,118784,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_FIXED,4,0xf0000) = 3154259968 (0xbc023000)
41390: mmap(0xbc040000,94208,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_FIXED|MAP_ANON,-1,0x0) = 3154378752 (0xbc040000)
41390: close(4)                                  = 0 (0x0)
41390: sysarch(0x81,0x7fffffffe820,0xbbd2d088,0x0,0xffffffffffd037f0,0x8080808080808080) = 0 (0x0)
41390: mmap(0x0,576,PROT_READ|PROT_WRITE,MAP_ANON,-1,0x0) = 3151163392 (0xbbd2f000)
41390: munmap(0xbbd2f000,576)                    = 0 (0x0)
41390: mmap(0x0,42288,PROT_READ|PROT_WRITE,MAP_ANON,-1,0x0) = 3151163392 (0xbbd2f000)
41390: munmap(0xbbd2f000,42288)                  = 0 (0x0)
41390: sigprocmask(SIG_BLOCK,SIGHUP|SIGINT|SIGQUIT|SIGKILL|SIGPIPE|SIGALRM|SIGTERM|SIGURG|SIGSTOP|SIGTSTP|SIGCONT|SIGCHLD|SIGTTIN|SIGTTOU|SIGIO|SIGXCPU|SIGXFSZ|SIGVTALRM|SIGPROF|SIGWINCH|SIGINFO|SIGUSR1|SIGUSR2,0x0) = 0 (0x0)
41390: sigprocmask(SIG_SETMASK,0x0,0x0)          = 0 (0x0)
41390: __sysctl(0x7fffffffe7c0,0x2,0xbc040a80,0x7fffffffe7b8,0x0,0x0) = 0 (0x0)
41390: sigprocmask(SIG_BLOCK,SIGHUP|SIGINT|SIGQUIT|SIGKILL|SIGPIPE|SIGALRM|SIGTERM|SIGURG|SIGSTOP|SIGTSTP|SIGCONT|SIGCHLD|SIGTTIN|SIGTTOU|SIGIO|SIGXCPU|SIGXFSZ|SIGVTALRM|SIGPROF|SIGWINCH|SIGINFO|SIGUSR1|SIGUSR2,0x0) = 0 (0x0)
41390: sigprocmask(SIG_SETMASK,0x0,0x0)          = 0 (0x0)
41390: open("/bin/ls",O_RDONLY,00)               = 4 (0x4)
41390: read(4,"\^?ELF\^B\^A\^A\t\0\0\0\0\0\0\0"...,64) = 64 (0x40)
41390: __sysctl(0x7fffffffe9c0,0x2,0x7fffffffe9dc,0x7fffffffe9d0,0x0,0x0) = 0 (0x0)
41390: lseek(4,0x40,SEEK_SET)                    = 64 (0x40)
41390: read(4,"\^F\0\0\0\^E\0\0\0@\0\0\0\0\0\0"...,56) = 56 (0x38)
41390: read(4,"\^C\0\0\0\^D\0\0\0\M-H\^A\0\0\0"...,56) = 56 (0x38)
41390: read(4,"\^A\0\0\0\^E\0\0\0\0\0\0\0\0\0\0"...,56) = 56 (0x38)
41390: read(4,"\^A\0\0\0\^F\0\0\0\0`\0\0\0\0\0"...,56) = 56 (0x38)
41390: read(4,"\^B\0\0\0\^F\0\0\0\M-8e\0\0\0\0"...,56) = 56 (0x38)
41390: close(4)                                  = 0 (0x0)
41390: __sysctl(0x7fffffffe8d0,0x2,0xbc044ae8,0x7fffffffe8e8,0x0,0x0) = 0 (0x0)
41390: __sysctl(0x7fffffffe420,0x2,0xbc053778,0x7fffffffe418,0x0,0x0) = 0 (0x0)
41390: __sysctl(0x7fffffffe460,0x2,0x7fffffffe47c,0x7fffffffe470,0x0,0x0) = 0 (0x0)
41390: readlink("/etc/malloc.conf",0x7fffffffe4c0,1024) ERR#2 'No such file or directory'
41390: issetugid(0xbbf1b00a,0x7fffffffe4c0,0xffffffffffffffff,0x0,0xffffff000c28f720,0x7fffffffe498) = 0 (0x0)
41390: break(0x600000)                           = 0 (0x0)
41390: mmap(0x0,1048576,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON,-1,0x0) = 3154472960 (0xbc057000)
41390: mmap(0xbc157000,692224,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON,-1,0x0) = 3155521536 (0xbc157000)
41390: munmap(0xbc057000,692224)                 = 0 (0x0)
41390: fstat(1,{ mode=crw--w---- ,inode=112,size=0,blksize=4096 }) = 0 (0x0)
41390: ioctl(1,TIOCGETA,0xffffe0a0)              = 0 (0x0)
41390: write(1,"/bin/ls:\n",9)                   = 9 (0x9)
41390: fork(0xbc02a478,0x0,0x1,0x0,0xffffff000c28f720,0x7fffffffe058) = 41391 (0xa1af)
41390: wait4(0xffffffff,0x7fffffffeabc,0x0,0x0,0xffffff000c28f720,0x7fffffffea08) = 41391 (0xa1af)
41390: sigprocmask(SIG_BLOCK,SIGHUP|SIGINT|SIGQUIT|SIGKILL|SIGPIPE|SIGALRM|SIGTERM|SIGURG|SIGSTOP|SIGTSTP|SIGCONT|SIGCHLD|SIGTTIN|SIGTTOU|SIGIO|SIGXCPU|SIGXFSZ|SIGVTALRM|SIGPROF|SIGWINCH|SIGINFO|SIGUSR1|SIGUSR2,0x0) = 0 (0x0)
41390: sigprocmask(SIG_SETMASK,0x0,0x0)          = 0 (0x0)
41390: sigprocmask(SIG_BLOCK,SIGHUP|SIGINT|SIGQUIT|SIGKILL|SIGPIPE|SIGALRM|SIGTERM|SIGURG|SIGSTOP|SIGTSTP|SIGCONT|SIGCHLD|SIGTTIN|SIGTTOU|SIGIO|SIGXCPU|SIGXFSZ|SIGVTALRM|SIGPROF|SIGWINCH|SIGINFO|SIGUSR1|SIGUSR2,0x0) = 0 (0x0)
41390: sigprocmask(SIG_SETMASK,0x0,0x0)          = 0 (0x0)
41390: process exit, rval = 0
 = 41391 (0xa1af)


Выделение моё. Видимо, работает так же, только ещё и не справляется.
Делай что должно, и будь что будет
Re[2]: А сколько нам отличий чудных
От: Vamp Россия  
Дата: 03.02.10 15:14
Оценка:
SH>FreeBSD 7.2
Интересно, а зачем он ls зовет?
Да здравствует мыло душистое и веревка пушистая.
Re[3]: А сколько нам отличий чудных
От: SergH Россия  
Дата: 03.02.10 15:19
Оценка:
Здравствуйте, Vamp, Вы писали:

V>Интересно, а зачем он ls зовет?


В смысле, как запуск процесса помогает определить, список модулей?

Возможно, родителя пинают при загрузке. Точнее, скорее, не родителя, а отладчик. Я недостаточно знаю unix, чтобы быстренько разобраться по этому трейсу в том, что делает ldd, так что на уровне гипотезы.
Делай что должно, и будь что будет
Re[4]: А сколько нам отличий чудных
От: Vamp Россия  
Дата: 03.02.10 15:22
Оценка:
SH>В смысле, как запуск процесса помогает определить, список модулей?
Нет, в смысле, что ты трассил /bin/sh:

$ truss -fa -o truss.txt ldd /bin/sh



SH>Возможно, родителя пинают при загрузке.

В Linux (там ldd — скрипт, все видно глазами) выставляется переменная окружения. Возможно, что солярка и фри делают то же самое.
Да здравствует мыло душистое и веревка пушистая.
Re[5]: А сколько нам отличий чудных
От: SergH Россия  
Дата: 03.02.10 15:26
Оценка:
Здравствуйте, Vamp, Вы писали:

V>Нет, в смысле, что ты трассил /bin/sh:


Артефакт копипаста.

V>В Linux (там ldd — скрипт, все видно глазами) выставляется переменная окружения. Возможно, что солярка и фри делают то же самое.


А что за переменная? Почему от неё такой интересный эффект?
Делай что должно, и будь что будет
Re[6]: А сколько нам отличий чудных
От: Vamp Россия  
Дата: 03.02.10 15:36
Оценка: 16 (1)
SH>А что за переменная? Почему от неё такой интересный эффект?
LD_TRACE_LOADED_OBJECTS.
Вызывает особое поведение загрузчика по умолчанию, который, однако можно и поменять. В солярке та же самая, я проверил только что.
Да здравствует мыло душистое и веревка пушистая.
Re[7]: А сколько нам отличий чудных
От: SergH Россия  
Дата: 03.02.10 15:40
Оценка:
Здравствуйте, Vamp, Вы писали:

SH>>А что за переменная? Почему от неё такой интересный эффект?

V>LD_TRACE_LOADED_OBJECTS.
V>Вызывает особое поведение загрузчика по умолчанию, который, однако можно и поменять. В солярке та же самая, я проверил только что.

Ага

$ LD_TRACE_LOADED_OBJECTS=1 /usr/bin/grep
        libgnuregex.so.4 => /usr/lib/libgnuregex.so.4 (0xbbe45000)
        libbz2.so.3 => /usr/lib/libbz2.so.3 (0xbbf56000)
        libz.so.4 => /lib/libz.so.4 (0xbc066000)
        libc.so.7 => /lib/libc.so.7 (0xbc17a000)
Делай что должно, и будь что будет
Re[8]: А сколько нам отличий чудных
От: Vamp Россия  
Дата: 03.02.10 15:41
Оценка:
SH>Ага
Ну скажи уродцы, а?
Да здравствует мыло душистое и веревка пушистая.
Re: А сколько нам отличий чудных
От: zaufi Земля  
Дата: 03.02.10 15:48
Оценка:
Здравствуйте, Vamp, Вы писали:

V>Обнаружил, что под Solaris и Linux вызов ldd реально вызывает анализируемый процесс. Таким образом, нарушается концепция защиты, что не может не огорчать.

V>Доказательство под Солярис:


V>
V>truss -t "fork, exec, setuid" -f ldd /db/bin/ls

V>3339:   execve("/usr/bin/ldd", 0xFFBED824, 0xFFBED830)  argc = 2
V>3339:   fork()                                          = 3340
V>3340:   fork()          (returning as child ...)        = 3339
V>3340:   execve("/db/bin/ls", 0xFFBED5F8, 0x000254D8)  argc = 1
V>        libgen.so.1 =>   /usr/lib/libgen.so.1
V>        libc.so.1 =>     /usr/lib/libc.so.1
V>        libdl.so.1 =>    /usr/lib/libdl.so.1
V>        /usr/platform/SUNW,Ultra-Enterprise/lib/libc_psr.so.1
V>


V>Я опечален.


чем это? а как ты думал он работает?
фтыкать первый абзац здесь например (статейка тоже не оч радостная но по кр мере развеит твою печаль относительно того что `ldd` якобы кавота запускает...
Re[9]: А сколько нам отличий чудных
От: SergH Россия  
Дата: 03.02.10 15:49
Оценка:
Здравствуйте, Vamp, Вы писали:

V>Ну скажи уродцы, а?


Подумать надо.

Механизм, конечно, кривой ужасно. Это с одной стороны. С другой -- универсальный способ настройки загрузчика вместо специального инструмента. С третьей -- не должен загрузчик этим заниматься, ну, это очень необычно для него. С четвёртой -- за у него это хорошо получается и добавить было несложно, и гарантируется аналогичное поведение.
Делай что должно, и будь что будет
Re[2]: А сколько нам отличий чудных
От: zaufi Земля  
Дата: 03.02.10 15:51
Оценка:
Z>чем это? а как ты думал он работает?
Z>фтыкать первый абзац здесь например (статейка тоже не оч радостная но по кр мере развеит твою печаль относительно того что `ldd` якобы кавота запускает...

s/абзац/параграф/

... ну вот пока искал пруфлинки тебе уже раскрыли тайну
Re[2]: А сколько нам отличий чудных
От: Vamp Россия  
Дата: 03.02.10 15:51
Оценка:
Z>чем это?
Неконтроллируемое исполнение произвольного кода. Особенно прекрасно, если ldd запустит рут, но даже и под обычным пользователем тоже несладко.

Z>а как ты думал он работает?

Я думал, что он анализирует заголовок файла.


Z>фтыкать первый абзац здесь например (статейка тоже не оч радостная но по кр мере развеит твою печаль относительно того что `ldd` якобы кавота запускает...

С чего бы она ее развеяла? Она только подтверждает мою правоту.
Да здравствует мыло душистое и веревка пушистая.
Re[10]: А сколько нам отличий чудных
От: Vamp Россия  
Дата: 03.02.10 15:53
Оценка:
SH>Подумать надо.

SH>Механизм, конечно, кривой ужасно...

Дело не в кривости, а в неявном исполнении произвольного кода.
Да здравствует мыло душистое и веревка пушистая.
Re: А сколько нам отличий чудных
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 03.02.10 16:41
Оценка:
Здравствуйте, Vamp, Вы писали:

V>Обнаружил, что под Solaris и Linux вызов ldd реально вызывает анализируемый процесс. Таким образом, нарушается концепция защиты, что не может не огорчать.


И почему ты думаешь, что она нарушается?
Если загрузчику сказано не делать реальный запуск, этого вполне достаточно. Заметь, что sugid запрещает такие действия вместе с запуском в этом случае.
The God is real, unless declared integer.
Re[3]: А сколько нам отличий чудных
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 03.02.10 16:45
Оценка:
Здравствуйте, Vamp, Вы писали:

Z>>чем это?

V>Неконтроллируемое исполнение произвольного кода. Особенно прекрасно, если ldd запустит рут, но даже и под обычным пользователем тоже несладко.

ldd проверяет, что у бинарника надлежащий загрузчик.
Подмена, конечно, возможна, но не считается существенной проблемой.
The God is real, unless declared integer.
Re[2]: А сколько нам отличий чудных
От: Vamp Россия  
Дата: 03.02.10 16:46
Оценка:
N>Если загрузчику сказано не делать реальный запуск, этого вполне достаточно.
Загрузчик может быть нестандартным.
Да здравствует мыло душистое и веревка пушистая.
Re[4]: А сколько нам отличий чудных
От: Vamp Россия  
Дата: 03.02.10 16:47
Оценка:
N>ldd проверяет, что у бинарника надлежащий загрузчик.
В какой системе? Как именно он это делает? В Linux скрипт, там я вижу, что он ничего не проверяет.
Да здравствует мыло душистое и веревка пушистая.
Re[5]: А сколько нам отличий чудных
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 03.02.10 19:30
Оценка:
Здравствуйте, Vamp, Вы писали:

N>>ldd проверяет, что у бинарника надлежащий загрузчик.

V>В какой системе? Как именно он это делает? В Linux скрипт, там я вижу, что он ничего не проверяет.

RTLDLIST="/lib/ld-linux.so.2 /lib64/ld-linux-x86-64.so.2"
[...]
    ret=1
    for rtld in ${RTLDLIST}; do
      if test -x $rtld; then
        verify_out=`${rtld} --verify "$file"`
        ret=$?
        case $ret in
        [02]) RTLD=${rtld}; break;;
        esac
      fi
    done
    case $ret in
    [02])
      try_trace "$RTLD" "$file" || result=1
      ;;
    1)
      # This can be a non-ELF binary or no binary at all.
      nonelf "$file" || {
        echo $" not a dynamic executable"
        result=1
      }
      ;;


по-моему, всё просто и ясно.
У меня Alt сизифовый конца прошлого года (между бранчами 5.0 и 5.1)
The God is real, unless declared integer.
Re[3]: А сколько нам отличий чудных
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 03.02.10 19:30
Оценка:
Здравствуйте, Vamp, Вы писали:

N>>Если загрузчику сказано не делать реальный запуск, этого вполне достаточно.

V>Загрузчик может быть нестандартным.

В том ldd, что мне доступен, в этом случае оно отказывается проверять.
См. соседний комментарий.
The God is real, unless declared integer.
Re[6]: А сколько нам отличий чудных
От: Vamp Россия  
Дата: 03.02.10 19:37
Оценка:
N>У меня Alt сизифовый конца прошлого года (между бранчами 5.0 и 5.1)
А там выше по ветке есть ссылка, из которой следует, что ничего он не проверяет? Кому верить?

Кроме того, из твоего кода не вполне очевидно, как он может проверить намеренно испорченный загрузчик. Сдается мне, он просто проверяет валидность сигнатур. Ты можешь проверить пример из ссылки? Интересно узнать, как это сработает у тебя.
Да здравствует мыло душистое и веревка пушистая.
Re: А сколько нам отличий чудных
От: Аноним  
Дата: 04.02.10 08:27
Оценка:
Здравствуйте, Vamp, Вы писали:

V>Обнаружил, что под Solaris и Linux вызов ldd реально вызывает анализируемый процесс. Таким образом, нарушается концепция защиты, что не может не огорчать.


"Реально вызывает" — что это? Можете развёрнуто написать?

Ну-ка, попробуйте запустить под ldd файл main() { return system("touch /tmp/ldd"); } и после ls /tmp/ldd

V>Я опечален.


Прежде чем печалиться, советую почитать man elf (в линуксе) и обратить внимание на секцию, описывающую INTERP хедер.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.