SlideShare a Scribd company logo
3
Most read
4
Most read
5
Most read
PHP LFI to arbitratry code
execution via rfc1867 file upload
temporary files
by Gynvael Coldwind
18 March 2011
Prologue
This article describes a method of taking advantage of a .php script Local File
Inclusion vulnerability. It does not describe any vulnerability in the PHP engine
itself, nor does it describe any new vulnerability class.
LFI to code execution, common methods
One of the problems commonly encountered during security audits of PHP
applications is proving that a Local File Inclusion indeed leads to arbitrary code
execution, which may not be the case if the attacker cannot inject code to any file
on the server.
Several methods are commonly used to prove that arbitrary code execution is
possible:
● including uploaded files - straight forward method; this requires existence
of an upload functionality in the tested website (e.g. photo upload, or
document upload), access to upload functionality and storage of uploaded
files in a place accessible by the PHP script
● include data:// or php://input pseudo protocols - these protocols must
be enabled and accessible via include (allow_url_include set to on); also,
php://filter pseudo protocol is usable in some cases
● including logs - this required PHP script to be able to access certain types
of logs, e.g. httpd server error logs or access logs; also, size of these logs
might make the attack harder (e.g. if error log has 2GB)
● including /proc/self/environ - this requires PHP to be run as CGI on a
system that has the /proc pseudo-filesystem and PHP script is required to
have access to the aforementioned pseudo-file
● include session files - this requires the attacker to be able to influence
the value of any string in a session (to inject code, e.g. <?php phpinfo(); ?
>), the sessions must be stored in a serialized session file (as e.g. x|
s:19:"<?php phpinfo(); ?>"; - this is the default setting for PHP) and the
PHP script must be able to access the session file (usually names /tmp/
sess_SESSIONID)
● include other files created by PHP application - this is very application
and system specific, but it basically describes any other file that is created
the websites functionality and the way it works, e.g. database files, cache
files, application-level logs, etc
Additional tools included both the poison nul byte (addressed in PHP 5.3.4[1]
released 2010-12-09) and excessive slash (/) suffix into path truncation bug[2]
(patched in 2009).
Temporary upload file inclusion
One other option is to take advantage of the way PHP handles file uploads via
HTTP. This method is far less known and not really usable on platforms other
than Windows (see Exploiting on Linux for details). Actually when I started writing
this paper I believed that this method is not known at all, but after few days of
searching and asking around I found a person (hi phunk ;>) that stumbled on this
method before. Nevertheless I couldn't find any other proof of this being common
knowledge, hence I decided to publish this article.
PHP engine, upon receiving a POST packet with RFC 1867 coded file(s), creates
one or more temporary files which are used to store the uploaded files data. A PHP
script handling file uploads is required to use the move_uploaded_file function to
move the uploaded temporary file to a place of it's desire (if the script requires the
file to exists after it terminates that is).
When the script ends PHP engine removes all temporary files for files that were
uploaded (if any are left after the script ends that is).
The image below shows the timeline of this behaviour:
The important fact here is that PHP engine creates the temporary files even if the
PHP script does not expect them (i.e. is not an upload handling script).
Hence, it is possible to send a file with arbitrary code to any PHP script, and
include the temporary file that the PHP engine has created.
Pros and cons
Good news is that it's common for a PHP script to have access to the directory (see
upload_tmp_dir in php.ini) where the temporary files are created (i.e. can include
files from this directory). On the default PHP installation the upload_tmp_dir is
not set - in this case either /tmp on Linux-based systems or C:WindowsTemp on
Windows are used.
The bad news is that the name of the temporary file is random, which renders this
method unusable in most cases - it is fully exploitable on Windows and exploitable
in some cases on other systems.
Exploitation on Windows
To generate the random name on Windows PHP uses the GetTempFileName
function. Looking into documentation we can find the following explanation:
The GetTempFileName function creates a temporary file name of the following form:
<path><pre><uuuu>.TMP
In case of PHP <path> is upload_tmp_dir (normally it's just C:WindowsTemp) and
<pre> is "php" (without the quotes). The last part is described as:
<uuuu> Hexadecimal value of uUnique
uUnique is one the arguments of GetTempFileName and in case of PHP, it's set to
0, which is a special value telling the function to use the current system time. The
important part here can be found in the remarks section:
Only the lower 16 bits of the uUnique parameter are used. This limits GetTempFileName
to a maximum of 65,535 unique file names if the lpPathName and lpPrefixStringparameters
remain the same.
Only 65k unique names makes a brute force possible, and using current system
time (number of milliseconds) makes things even simpler.
However, brute force is not needed here, thanks to a certain FindFirstFile quirk [3]
which allows using masks (<< as * and > as ?) in LFI paths on Windows. Thanks to
this, one can form an include path like this:
http://site/vuln.php?inc=c:windowstempphp<<
Commonly there are other files with "php" prefix in this directory, so narrowing the
mask might be required. In this case it's best to choose the widest possible mask
that does not include any file (e.g. php1<< or phpA<<, in worse case php11<<,
etc) and send upload-packets until the PHP engine will create a temporary file that
will match the mask.
Exploitation on GNU/Linux
For temporary name generation PHP engine on GNU/Linux uses mkstemp from
GNU libc. This function, depending on the way glibc is compiled, uses either (in
pseudocode; variables are uint64_t):
1. random_value = (seed += time() ^ PID)
2. random_value = (seed += (gettimeofday().sec << 32 | gettimeofday().usec)
^ PID)
3. random_value = (seed += rdtsc ^ PID)
The random_value is later written as 6 digits of k=62 (A-Za-z0-9 charset) numeric
system, and appended to the "/tmp/php" prefix (unless another directory is set),
e.g. /tmp/phpUs7MxA.
From the aforementioned random_value generation methods, the 3rd is most
commonly used nowadays.
According to initial tests I made, the random value is unpredictable enough to be
considered safe against remote attacker.
This leads to the assumption that using this exploitation path is possible only in
these specific cases:
● When the tester is able to list the files in the upload (/tmp) directory
(presumably by another PHP script) - this would require a race condition
method where the tester uploads one file to a slow script (i.e. a script that
runs for a relatively long time) and lists the files in the upload directory
in another script, acquires the file temporary file name, and fires the LFI
exploit.
● When the tester is able to list the $_FILES array in a script - this requires an
even more tight race condition and is not always possible, since the attacker
must obtain the $_FILES array content during upload and send another
packet before the previous script ends and the temporary file is removed.
This is not possible in case of buffering of PHP output (e.g. if mod_gzip is
enabled in Apache).
Hence, this method is usable only in some specific cases and should not be
considered a generic method.
See also: part 2 of "A note on research done" section.
A note on research done
One of the ideas I had to widen the exploitation window (i.e. the time window
during which the temporary file exist) was to create an HTTP packet with e.g. 20
files (this is the default file-per-HTTP-packet limit in PHP) and send the first 19
files normally, but the last file in a slow manner (byte, sleep, byte, sleep, repeat).
In theory, the previous uploaded files from the same packet should still exist until
the upload will finish and the time window closes. However, it turns out that the
PHP engine's upload parsing function is not executed until the whole HTTP packet
arrives, thus, these files won't be yet created.
Also, in some cases, when httpd has access to /proc/self/fd (commonly httpd works
with privileges dropped to www-data, while /proc/self/fd has root as it's owner,
hence requires root privileges to access), this method is easier to exploit by trying
to upload files (in one thread) and include /proc/self/fd/XYZ in the other (e.g. start
with XYZ=10). However, the temporary file fd handle exists only between opening
the temp file and closing it, so it's a very narrow time window. Uploading large files
might widen this window a little though.
Future work
There is some room for improvements and additional research related to this
method:
● test mktemp and mkstemp on other systems (*BSD, Solaris, etc) / in other
libc implementations
● do proper research on mkstemp on GNU/Linux and it's predictability for both
a local and a remote attacker, that has both no knowledge and knowledge of
previous generated temporary names
● the FindFirstFile << quirk works now, but it may be removed later, hence
doing proper research on remotly predicting the temporary file name on
Windows might also be worth doing
References
[1] PHP 5.3 Changelog. http://php.net/ChangeLog-5.php
[2] Francesco "ascii" Ongaro, Giovanni "evilaliv3" Pellerano. PHP filesystem attack
vectors. http://www.evilaliv3.org/articles/php-filesystem-attack-vectors/
[3] Vladimir Vorontsov, Arthur Gerkis. Oddities of PHP file access in Windows®.
Cheat-sheet, 2011. http://onsec.ru/onsec.whitepaper-02.eng.pdf
Thanks to
Felix Gröbert for the interesting discussion that led to this article :)
Disclaimer
The views expressed here are mine alone and not those of my employer.

More Related Content

What's hot (18)

PPT
Unix Basics 04sp
Dr.Ravi
 
PDF
Python - basics
Jéferson Machado
 
PDF
WEB PROGRAMMING UNIT VI BY BHAVSINGH MALOTH
Bhavsingh Maloth
 
PPT
Unit 7
siddr
 
PDF
Development and deployment with composer and kite
Christian Opitz
 
PDF
Delphi L05 Files and Dialogs
Mohammad Shaker
 
PPTX
Threat Modeling: Applied on a Publish-Subscribe Architectural Style
Dharmalingam Ganesan
 
PPT
IPC mechanisms in windows
Vinoth Raj
 
PDF
parenscript-tutorial
tutorialsruby
 
PDF
Kerberos : The network authentification protocol
Open Source School
 
PDF
Introduction To Embedding The PH7 PHP Engine in a C/C++ Host Application.
Chems Mrad
 
PDF
PASTE: A Network Programming Interface for Non-Volatile Main Memory
micchie
 
ODP
Nguyễn Vũ Hưng: Basic Linux Power Tools
Vu Hung Nguyen
 
PDF
Unit VI
Bhavsingh Maloth
 
PPTX
Tribal Nova Docker feedback
Nicolas Degardin
 
PDF
Tips and Tricks for Increased Development Efficiency
Olivier Bourgeois
 
PDF
Volatile memory analysis
Himanshu0734
 
PDF
Remote file path traversal attacks for fun and profit
Dharmalingam Ganesan
 
Unix Basics 04sp
Dr.Ravi
 
Python - basics
Jéferson Machado
 
WEB PROGRAMMING UNIT VI BY BHAVSINGH MALOTH
Bhavsingh Maloth
 
Unit 7
siddr
 
Development and deployment with composer and kite
Christian Opitz
 
Delphi L05 Files and Dialogs
Mohammad Shaker
 
Threat Modeling: Applied on a Publish-Subscribe Architectural Style
Dharmalingam Ganesan
 
IPC mechanisms in windows
Vinoth Raj
 
parenscript-tutorial
tutorialsruby
 
Kerberos : The network authentification protocol
Open Source School
 
Introduction To Embedding The PH7 PHP Engine in a C/C++ Host Application.
Chems Mrad
 
PASTE: A Network Programming Interface for Non-Volatile Main Memory
micchie
 
Nguyễn Vũ Hưng: Basic Linux Power Tools
Vu Hung Nguyen
 
Tribal Nova Docker feedback
Nicolas Degardin
 
Tips and Tricks for Increased Development Efficiency
Olivier Bourgeois
 
Volatile memory analysis
Himanshu0734
 
Remote file path traversal attacks for fun and profit
Dharmalingam Ganesan
 

Similar to PHP LFI to Arbitrary Code Execution via rfc1867 file upload temporary files (20)

PPTX
4-chapter-File & Directores.pptx debre CTABOUR UNIversit
alemunuruhak9
 
ODP
PHP {in}security
Michael Clark
 
PPT
John's Top PECL Picks
John Coggeshall
 
PPTX
File upload php
sana mateen
 
PDF
15955 state-of-the-art-post-exploitation-in-hardened-php-environments
Attaporn Ninsuwan
 
PPT
Download It
webhostingguy
 
PPT
Php basics
sagaroceanic11
 
PPTX
Phalcon 2 - PHP Brazil Conference
Jackson F. de A. Mafra
 
PDF
Php Conference Brazil - Phalcon Giant Killer
Jackson F. de A. Mafra
 
PDF
"15 Technique to Exploit File Upload Pages", Ebrahim Hegazy
HackIT Ukraine
 
PPTX
Information on PHP Handlers
HTS Hosting
 
PDF
Secure PHP environment
SpeedPartner GmbH
 
PPTX
Composer namespacing
Deepak Chandani
 
PDF
File handling C program
Thesis Scientist Private Limited
 
PDF
Piattaforma Web Linux completa dai sorgenti
Giulio Destri
 
4-chapter-File & Directores.pptx debre CTABOUR UNIversit
alemunuruhak9
 
PHP {in}security
Michael Clark
 
John's Top PECL Picks
John Coggeshall
 
File upload php
sana mateen
 
15955 state-of-the-art-post-exploitation-in-hardened-php-environments
Attaporn Ninsuwan
 
Download It
webhostingguy
 
Php basics
sagaroceanic11
 
Phalcon 2 - PHP Brazil Conference
Jackson F. de A. Mafra
 
Php Conference Brazil - Phalcon Giant Killer
Jackson F. de A. Mafra
 
"15 Technique to Exploit File Upload Pages", Ebrahim Hegazy
HackIT Ukraine
 
Information on PHP Handlers
HTS Hosting
 
Secure PHP environment
SpeedPartner GmbH
 
Composer namespacing
Deepak Chandani
 
File handling C program
Thesis Scientist Private Limited
 
Piattaforma Web Linux completa dai sorgenti
Giulio Destri
 
Ad

More from Attaporn Ninsuwan (20)

PDF
J query fundamentals
Attaporn Ninsuwan
 
PDF
Jquery enlightenment
Attaporn Ninsuwan
 
PDF
Jquery-Begining
Attaporn Ninsuwan
 
PDF
Br ainfocom94
Attaporn Ninsuwan
 
PDF
Chapter 12 - Computer Forensics
Attaporn Ninsuwan
 
PDF
Techniques for data hiding p
Attaporn Ninsuwan
 
PDF
Stop badware infected_sites_report_062408
Attaporn Ninsuwan
 
PDF
Steganography past-present-future 552
Attaporn Ninsuwan
 
PDF
Ch03-Computer Security
Attaporn Ninsuwan
 
PDF
Ch02-Computer Security
Attaporn Ninsuwan
 
PDF
Ch01-Computer Security
Attaporn Ninsuwan
 
PDF
Ch8-Computer Security
Attaporn Ninsuwan
 
PDF
Ch7-Computer Security
Attaporn Ninsuwan
 
PDF
Ch6-Computer Security
Attaporn Ninsuwan
 
PDF
Ch06b-Computer Security
Attaporn Ninsuwan
 
PDF
Ch5-Computer Security
Attaporn Ninsuwan
 
PDF
Ch04-Computer Security
Attaporn Ninsuwan
 
PDF
Chapter5 - The Discrete-Time Fourier Transform
Attaporn Ninsuwan
 
PDF
Chapter4 - The Continuous-Time Fourier Transform
Attaporn Ninsuwan
 
PDF
Chapter3 - Fourier Series Representation of Periodic Signals
Attaporn Ninsuwan
 
J query fundamentals
Attaporn Ninsuwan
 
Jquery enlightenment
Attaporn Ninsuwan
 
Jquery-Begining
Attaporn Ninsuwan
 
Br ainfocom94
Attaporn Ninsuwan
 
Chapter 12 - Computer Forensics
Attaporn Ninsuwan
 
Techniques for data hiding p
Attaporn Ninsuwan
 
Stop badware infected_sites_report_062408
Attaporn Ninsuwan
 
Steganography past-present-future 552
Attaporn Ninsuwan
 
Ch03-Computer Security
Attaporn Ninsuwan
 
Ch02-Computer Security
Attaporn Ninsuwan
 
Ch01-Computer Security
Attaporn Ninsuwan
 
Ch8-Computer Security
Attaporn Ninsuwan
 
Ch7-Computer Security
Attaporn Ninsuwan
 
Ch6-Computer Security
Attaporn Ninsuwan
 
Ch06b-Computer Security
Attaporn Ninsuwan
 
Ch5-Computer Security
Attaporn Ninsuwan
 
Ch04-Computer Security
Attaporn Ninsuwan
 
Chapter5 - The Discrete-Time Fourier Transform
Attaporn Ninsuwan
 
Chapter4 - The Continuous-Time Fourier Transform
Attaporn Ninsuwan
 
Chapter3 - Fourier Series Representation of Periodic Signals
Attaporn Ninsuwan
 
Ad

Recently uploaded (20)

PDF
NewMind AI - Journal 100 Insights After The 100th Issue
NewMind AI
 
PPTX
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 
PDF
Blockchain Transactions Explained For Everyone
CIFDAQ
 
PDF
SWEBOK Guide and Software Services Engineering Education
Hironori Washizaki
 
PDF
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
PDF
[Newgen] NewgenONE Marvin Brochure 1.pdf
darshakparmar
 
PDF
Using FME to Develop Self-Service CAD Applications for a Major UK Police Force
Safe Software
 
PDF
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
PPTX
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 
PPTX
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
PDF
Fl Studio 24.2.2 Build 4597 Crack for Windows Free Download 2025
faizk77g
 
PPTX
UiPath Academic Alliance Educator Panels: Session 2 - Business Analyst Content
DianaGray10
 
PPTX
From Sci-Fi to Reality: Exploring AI Evolution
Svetlana Meissner
 
PDF
DevBcn - Building 10x Organizations Using Modern Productivity Metrics
Justin Reock
 
PDF
Log-Based Anomaly Detection: Enhancing System Reliability with Machine Learning
Mohammed BEKKOUCHE
 
PDF
Python basic programing language for automation
DanialHabibi2
 
PDF
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
PPTX
Q2 FY26 Tableau User Group Leader Quarterly Call
lward7
 
PDF
Newgen 2022-Forrester Newgen TEI_13 05 2022-The-Total-Economic-Impact-Newgen-...
darshakparmar
 
PDF
The Builder’s Playbook - 2025 State of AI Report.pdf
jeroen339954
 
NewMind AI - Journal 100 Insights After The 100th Issue
NewMind AI
 
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 
Blockchain Transactions Explained For Everyone
CIFDAQ
 
SWEBOK Guide and Software Services Engineering Education
Hironori Washizaki
 
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
[Newgen] NewgenONE Marvin Brochure 1.pdf
darshakparmar
 
Using FME to Develop Self-Service CAD Applications for a Major UK Police Force
Safe Software
 
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
Fl Studio 24.2.2 Build 4597 Crack for Windows Free Download 2025
faizk77g
 
UiPath Academic Alliance Educator Panels: Session 2 - Business Analyst Content
DianaGray10
 
From Sci-Fi to Reality: Exploring AI Evolution
Svetlana Meissner
 
DevBcn - Building 10x Organizations Using Modern Productivity Metrics
Justin Reock
 
Log-Based Anomaly Detection: Enhancing System Reliability with Machine Learning
Mohammed BEKKOUCHE
 
Python basic programing language for automation
DanialHabibi2
 
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
Q2 FY26 Tableau User Group Leader Quarterly Call
lward7
 
Newgen 2022-Forrester Newgen TEI_13 05 2022-The-Total-Economic-Impact-Newgen-...
darshakparmar
 
The Builder’s Playbook - 2025 State of AI Report.pdf
jeroen339954
 

PHP LFI to Arbitrary Code Execution via rfc1867 file upload temporary files

  • 1. PHP LFI to arbitratry code execution via rfc1867 file upload temporary files by Gynvael Coldwind 18 March 2011 Prologue This article describes a method of taking advantage of a .php script Local File Inclusion vulnerability. It does not describe any vulnerability in the PHP engine itself, nor does it describe any new vulnerability class. LFI to code execution, common methods One of the problems commonly encountered during security audits of PHP applications is proving that a Local File Inclusion indeed leads to arbitrary code execution, which may not be the case if the attacker cannot inject code to any file on the server. Several methods are commonly used to prove that arbitrary code execution is possible: ● including uploaded files - straight forward method; this requires existence of an upload functionality in the tested website (e.g. photo upload, or document upload), access to upload functionality and storage of uploaded files in a place accessible by the PHP script ● include data:// or php://input pseudo protocols - these protocols must be enabled and accessible via include (allow_url_include set to on); also, php://filter pseudo protocol is usable in some cases ● including logs - this required PHP script to be able to access certain types of logs, e.g. httpd server error logs or access logs; also, size of these logs might make the attack harder (e.g. if error log has 2GB) ● including /proc/self/environ - this requires PHP to be run as CGI on a
  • 2. system that has the /proc pseudo-filesystem and PHP script is required to have access to the aforementioned pseudo-file ● include session files - this requires the attacker to be able to influence the value of any string in a session (to inject code, e.g. <?php phpinfo(); ? >), the sessions must be stored in a serialized session file (as e.g. x| s:19:"<?php phpinfo(); ?>"; - this is the default setting for PHP) and the PHP script must be able to access the session file (usually names /tmp/ sess_SESSIONID) ● include other files created by PHP application - this is very application and system specific, but it basically describes any other file that is created the websites functionality and the way it works, e.g. database files, cache files, application-level logs, etc Additional tools included both the poison nul byte (addressed in PHP 5.3.4[1] released 2010-12-09) and excessive slash (/) suffix into path truncation bug[2] (patched in 2009). Temporary upload file inclusion One other option is to take advantage of the way PHP handles file uploads via HTTP. This method is far less known and not really usable on platforms other than Windows (see Exploiting on Linux for details). Actually when I started writing this paper I believed that this method is not known at all, but after few days of searching and asking around I found a person (hi phunk ;>) that stumbled on this method before. Nevertheless I couldn't find any other proof of this being common knowledge, hence I decided to publish this article. PHP engine, upon receiving a POST packet with RFC 1867 coded file(s), creates one or more temporary files which are used to store the uploaded files data. A PHP script handling file uploads is required to use the move_uploaded_file function to move the uploaded temporary file to a place of it's desire (if the script requires the file to exists after it terminates that is). When the script ends PHP engine removes all temporary files for files that were uploaded (if any are left after the script ends that is). The image below shows the timeline of this behaviour:
  • 3. The important fact here is that PHP engine creates the temporary files even if the PHP script does not expect them (i.e. is not an upload handling script). Hence, it is possible to send a file with arbitrary code to any PHP script, and include the temporary file that the PHP engine has created. Pros and cons Good news is that it's common for a PHP script to have access to the directory (see upload_tmp_dir in php.ini) where the temporary files are created (i.e. can include files from this directory). On the default PHP installation the upload_tmp_dir is not set - in this case either /tmp on Linux-based systems or C:WindowsTemp on Windows are used. The bad news is that the name of the temporary file is random, which renders this method unusable in most cases - it is fully exploitable on Windows and exploitable in some cases on other systems. Exploitation on Windows To generate the random name on Windows PHP uses the GetTempFileName function. Looking into documentation we can find the following explanation: The GetTempFileName function creates a temporary file name of the following form: <path><pre><uuuu>.TMP In case of PHP <path> is upload_tmp_dir (normally it's just C:WindowsTemp) and <pre> is "php" (without the quotes). The last part is described as:
  • 4. <uuuu> Hexadecimal value of uUnique uUnique is one the arguments of GetTempFileName and in case of PHP, it's set to 0, which is a special value telling the function to use the current system time. The important part here can be found in the remarks section: Only the lower 16 bits of the uUnique parameter are used. This limits GetTempFileName to a maximum of 65,535 unique file names if the lpPathName and lpPrefixStringparameters remain the same. Only 65k unique names makes a brute force possible, and using current system time (number of milliseconds) makes things even simpler. However, brute force is not needed here, thanks to a certain FindFirstFile quirk [3] which allows using masks (<< as * and > as ?) in LFI paths on Windows. Thanks to this, one can form an include path like this: http://site/vuln.php?inc=c:windowstempphp<< Commonly there are other files with "php" prefix in this directory, so narrowing the mask might be required. In this case it's best to choose the widest possible mask that does not include any file (e.g. php1<< or phpA<<, in worse case php11<<, etc) and send upload-packets until the PHP engine will create a temporary file that will match the mask. Exploitation on GNU/Linux For temporary name generation PHP engine on GNU/Linux uses mkstemp from GNU libc. This function, depending on the way glibc is compiled, uses either (in pseudocode; variables are uint64_t): 1. random_value = (seed += time() ^ PID) 2. random_value = (seed += (gettimeofday().sec << 32 | gettimeofday().usec) ^ PID) 3. random_value = (seed += rdtsc ^ PID) The random_value is later written as 6 digits of k=62 (A-Za-z0-9 charset) numeric system, and appended to the "/tmp/php" prefix (unless another directory is set), e.g. /tmp/phpUs7MxA.
  • 5. From the aforementioned random_value generation methods, the 3rd is most commonly used nowadays. According to initial tests I made, the random value is unpredictable enough to be considered safe against remote attacker. This leads to the assumption that using this exploitation path is possible only in these specific cases: ● When the tester is able to list the files in the upload (/tmp) directory (presumably by another PHP script) - this would require a race condition method where the tester uploads one file to a slow script (i.e. a script that runs for a relatively long time) and lists the files in the upload directory in another script, acquires the file temporary file name, and fires the LFI exploit. ● When the tester is able to list the $_FILES array in a script - this requires an even more tight race condition and is not always possible, since the attacker must obtain the $_FILES array content during upload and send another packet before the previous script ends and the temporary file is removed. This is not possible in case of buffering of PHP output (e.g. if mod_gzip is enabled in Apache). Hence, this method is usable only in some specific cases and should not be considered a generic method. See also: part 2 of "A note on research done" section. A note on research done One of the ideas I had to widen the exploitation window (i.e. the time window during which the temporary file exist) was to create an HTTP packet with e.g. 20 files (this is the default file-per-HTTP-packet limit in PHP) and send the first 19 files normally, but the last file in a slow manner (byte, sleep, byte, sleep, repeat). In theory, the previous uploaded files from the same packet should still exist until the upload will finish and the time window closes. However, it turns out that the PHP engine's upload parsing function is not executed until the whole HTTP packet arrives, thus, these files won't be yet created. Also, in some cases, when httpd has access to /proc/self/fd (commonly httpd works with privileges dropped to www-data, while /proc/self/fd has root as it's owner, hence requires root privileges to access), this method is easier to exploit by trying
  • 6. to upload files (in one thread) and include /proc/self/fd/XYZ in the other (e.g. start with XYZ=10). However, the temporary file fd handle exists only between opening the temp file and closing it, so it's a very narrow time window. Uploading large files might widen this window a little though. Future work There is some room for improvements and additional research related to this method: ● test mktemp and mkstemp on other systems (*BSD, Solaris, etc) / in other libc implementations ● do proper research on mkstemp on GNU/Linux and it's predictability for both a local and a remote attacker, that has both no knowledge and knowledge of previous generated temporary names ● the FindFirstFile << quirk works now, but it may be removed later, hence doing proper research on remotly predicting the temporary file name on Windows might also be worth doing References [1] PHP 5.3 Changelog. http://php.net/ChangeLog-5.php [2] Francesco "ascii" Ongaro, Giovanni "evilaliv3" Pellerano. PHP filesystem attack vectors. http://www.evilaliv3.org/articles/php-filesystem-attack-vectors/ [3] Vladimir Vorontsov, Arthur Gerkis. Oddities of PHP file access in Windows®. Cheat-sheet, 2011. http://onsec.ru/onsec.whitepaper-02.eng.pdf Thanks to Felix Gröbert for the interesting discussion that led to this article :) Disclaimer The views expressed here are mine alone and not those of my employer.