0day?Nday!

写在前面🖊 写完MCP后,花了两周时间通关了33号远征队和霍格沃兹之遗。👍 百无聊赖的时候,最近读到Claude code的skills功能的文章,觉得很爽。无奈Claude code到处锁区。于是下载了OpenCode。然后不出意料地安装失败了。。。 算了,反正都是ai agent,还能有什么区别?于是乎开始捣鼓ai agent。您别说,还真让我捣鼓出好东西来 这里不多讲,见上一篇 挖洞😎 交给ai跑🤖🤖,我在下面玩手机📱。过了十分钟,跑完了。。。 我去,有SQL注入!🎉 我去,有目录穿越!🎉 那我可不无聊了,马上上环境验证一下: 我去,真是SQL注入!🎉 我去,真是目录穿越!🎉 初见端倪🤡 为什么没人提issue 打开漏洞库。。 啊?😅怎么全都有人交了,还是2025年交的 尼玛,浪费我时间呢。明天再说吧。😅

January 20, 2026 · 1 min · 21 words · huarui

AI agent + SAST = 躺着挖洞

写在前面📕 挖洞,轻而易举啊。 准备 🙌 cherry studio SAST工具 MCP(可选) 快速开始 💕 Cherry Studio🍒 准备你的ai agent。请注意限定它的工作目录以及权限。我这里直接开放所有权限。 提示词如下: 现在你是网络安全专家。请你辅助我完成代码审计工作 MCP ai agent在读doc文件这一块显得很吃力。我配置了一个方便ai agent读文件的MCP工具: 主要代码如下: @expose_tool( name="read_docx_file", description="读取本地 .docx 文件的文本内容。支持读取段落文本,不包含复杂的格式信息。" ) def read_docx_file(file_path: str) -> str: """ 参数: file_path (str): .docx 文件的绝对路径或相对路径。 返回: str: 文件中的所有文本内容,按段落换行。 """ try: # 1. 检查文件是否存在 if not os.path.exists(file_path): return f"错误: 文件不存在 - {file_path}" # 2. 检查是否为 docx 后缀 (简单的检查,防止误读二进制文件) if not file_path.lower().endswith(".docx"): return "警告: 文件扩展名不是 .docx,本工具仅支持 .docx 格式。如果是旧版 .doc 文件,请先在 Word 中另存为 .docx。" # 3. 读取文档 doc = Document(file_path) # 4. 提取所有段落的文本 full_text = [] for para in doc.paragraphs: if para.text.strip(): # 忽略空行,也可以改为保留空行 full_text.append(para.text) # 5. 如果没有内容 if not full_text: return "该文档似乎是空的,或者内容无法提取(例如内容全在表格或图片中)。" return "\n".join(full_text) except Exception as e: # 捕获特定的错误,比如如果不是有效的 zip/docx 文件 error_msg = str(e) if "BadZipFile" in error_msg or "not a zip file" in error_msg: return "错误: 文件损坏或不是有效的 .docx 格式。如果是 .doc 文件,请先转换为 .docx。" return f"读取文件时发生错误: {error_msg}" 具体的MCP服务器框架见上一篇文章 ...

January 20, 2026 · 1 min · 149 words · huarui

LipMCP项目

写在前面 前段时间电脑的显卡烧坏了,没了。害得我打了几天的王者荣耀 拿去给b站上的百万up的店看,他都说没救了。。 没招了求爸妈破费买了一台七彩虹隐星… 这段没电脑的时间里面看了几篇有关MCP的文章。我觉得mcp这种东西大有用途,比如物联网 于是就有了这篇博客和项目:LipMCP github.com/54huarui/LipMCP LipMcp Server 简易上手的python MCP物联网服务器框架 基于python mcp构建的mcp服务器框架,让你的智能家居能够通过AI控制! 自定义:你可以直接接入任何你想要自动化实现的python代码(不仅仅是物联网 自动注册mcp:无需修改server,只需要在function中添加你想要的函数即可让ai调用 示例:米家灯泡控制作为示例代码 主要环境: python 3.11 python mcp python-miio 快速开始 这里以米家灯泡作为示例,通过ai控制灯泡开关灯以及颜色,亮度变化 1) 获取你的米家设备信息: 推荐使用Xiaomi-cloud-tokens-extractor获取所需的设备信息 示例 “ip”:“192.168.137.2” “token”:“32861a8b84d97b6d0c63efed6276f6d6” 2) mcp客户端连接mcp服务器 准备你的mcp客户端: 推荐使用Cherry Studio/Cherry Studio官方网站 安装环境: 在项目路径下执行 pip install -r requirements.txt 推荐使用python3.11 导入MCP服务器: 在设置->MCP服务器->添加->从json导入 请替换你的server.py路径 { "mcpServers": { "LipMCP": { "command": "python", "args": ["C:\\Users\\huarui\\Documents\\GitHub\\LipMCP\\server.py"] } } } ...

January 14, 2026 · 1 min · 204 words · huarui

Say Hello to 2026 New Years

Say Hello to 2026 New Years 这是一个基于github actions和hugo的静态博客网站重构的博客。新年新气象!

January 1, 2026 · 1 min · 8 words · huarui

年终总结

写在前面 大约几个月的时间都没有写过博客,其实并不是因为我懒,为了履历更丰富一些,最近开始审计一些开源的java项目。没想到第一周就审出有不少的项目。最离谱的是。。。 跑题了。。。现在还是好好写一下今年2025年的年终总结吧 上半年 上半年对我来说是最迷茫的一段时间。我却时常感到力不从心。老师出的题目很难,考试安排又很密集,学习压力很大。但是将视线从成绩中移开,翻看了一下照片,我还是找到了一些属于那段日子的记忆:雾蒙蒙的校园远山、厚重外套下匆匆行走的身影,还有在十六教五楼下楼梯时思考人生的自己。 很多时候,我们无法在当下意识到某个瞬间的价值,只有经过时间沉淀之后,那些瞬间才真正显现出它的分量。 上半年参加学校的个人比赛,获得了人生第一个个人赛的一等奖,也是为我的努力正名了吧。我能感受得出来,没人能理解我,大家也都觉得我就是那种不努力摆摆烂,差不多就行的人。无论是老师还是和学长说话我都能够感觉一个讯息:就这样了。 这个比赛对我的意义远超过后面拿了国奖一等奖,省奖一等奖的意义。原来自己的努力不是白费的,原来你可以做到比他们预期的更好。 六月 老师找到我,去搞护网 妈的,从这里开始我才明白,我在黑盒挖洞这一块就是个垃圾 不虚此行,至少有机会去住个五星级酒店,还认识了个大佬。嚯嚯,我们学校还有这种高手。 有一说一,这地方好爽啊。上次去北海还是2023年,那个时候我刚刚高中毕业。 想起那段时光真是糟糕透了,高考失败的阴影,每天在无尽的自责和低落的心情中醒来,看着朋友每天发的消息,不敢多说,也不敢参与讨论。生怕又伤到自己。经历过糟糕的日子,才有资格谈论未来的精彩 十月 请输入文本 这个比赛的名字,我一点都记不住了。但没关系,记住全国一等奖就够了 对了,还有北京动物园的动物 早安,天安门广场 小巷子 下午好,颐和园 最好的结局达成了。多谢hzy和ljj,真幸运,最好的时光遇到你们一起战斗。 十一月 省赛 省一。。 其他 开始我的代码审计实战之旅。同时深度结识猫哥。 和猫哥很早就认识了。上半年开始学习代码审计的时候,就和猫哥一起聊过,也探讨过题目。猫哥真是本质高手。 最后也是拉上猫哥一起战斗ciscn了,目前还不知道结果,还是未知结局。 然后就是审计代码。看了几天,发现了个挺爆的洞,已申请cnvd cnvd,怎么这么久啊,好逆天。 同时还有个ssrf,挺简单的,可以在我的github参与项目中看到。 上面两个都申请cve了。有一说一这个cve更是石沉大海。除了一个自动回复的邮件,完全是杳无音讯。 寒假打算继续搞这个。希望能做的更好。我相信。 写在最后 如果有什么想写的后面会补充的。今年好像要去实习了啊。希望新的一年我不再为过去困扰,同时更上一层楼吧。 完成于2026年1月1日 最后修改于1月2日

January 1, 2026 · 1 min · 38 words · huarui

网页雷达:如何将web和逆向结合了

网页雷达 写在前面 本项目完成于2025年9月,但是由于某些原因没有写成博客发不出来。现在风头过去了可以发了,所以把这篇文章发出来,也是记录一下学习。今后可能会回归web安全相关内容,暂时不搞逆向了。 项目 这里用一个前几年比较火的游戏————荒野行动 作为例子 效果图: 目录 |—–GameMaps |–ConnectController.py |–hy_web.e |–XLC.html |–XLC.png hy_web.e 本地端:hy_web.e 本地端用e语言,主要是有现成的驱动,本人也是很早学过的,正好能熟练运用 这里主要是两个额外线程:读取数据线程和矩阵线程 数据读取模块: .版本 2 PlayerControler = 读长整数 (读长整数 (读长整数 (读长整数 (读长整数 (读长整数 (读长整数 (读长整数 (模块地址 + #PlayerAddr) + 88) + 192) + 984) + 96) + 56) + 984) + 96) ' 调试输出 (“playcontroler”, PlayerControler, 进制_十到十六 (PlayerControler)) .判断循环首 (真) count = 读整数型 (读长整数 (读长整数 (读长整数 (读长整数 (读长整数 (读长整数 (读长整数 (模块地址 + #PlayerAddr) + 88) + 192) + 984) + 96) + 56) + 984) + 104) ' 调试输出 (“count”, count, PlayerControler) .计次循环首 (count, i) playerOffset = 读长整数 (读长整数 (读长整数 (读长整数 (读长整数 (读长整数 (读长整数 (PlayerControler + 0 + (i - 1) × 8) + 224) + 48) + 64) + 64) + 8) + 208) ' 调试输出 (“player”, playerOffset, 进制_十到十六 (playerOffset)) playerPos = GetPos (playerOffset) ' 调试输出 (“playerpos”, playerPos.x, playerPos.y, playerPos.z) 加入成员 (临时数组, playerOffset) .计次循环尾 () 全_对象数组 = 临时数组 ' 调试输出 (全_对象数组) 清除数组 (临时数组) 延时 (1000) .判断循环尾 () 矩阵读取: ...

October 29, 2025 · 4 min · 733 words · huarui

记一次UE逆向--三角洲行动

记一次UE逆向–三角洲行动 关于 本文章仅供学习交流,请勿用于非法用途 信息获取 通往罗马的路不止一条。 三角洲行动这个游戏可以说是市面上反作弊部署最为完善的游戏,上到服务器端,下到内存cr3都有严苛的反作弊措施。严密的检测下几乎不可能直接上手调试。如果只会公式化逆向或者喜欢单刷ACE,只能说死路一条 但是哥们有社会工程学 只要我能获取我想要的信息,那我就可以绕过调试阶段,直接写脚本了 Offset BV1EigWzGEaj 大佬的dll直接注入即可GetOffset( /* Create by ShaHen */ /* QQ:750144893 */ inline static const uint64_t OwningGameInstance = 0x00000000000001B0 inline static const uint64_t LocalPlayers = 0x0000000000000048 inline static const uint64_t PlayerController = 0x0000000000000038 inline static const uint64_t ControlRotation = 0x00000000000003E8 inline static const uint64_t AcknowledgedPawn = 0x0000000000000410 inline static const uint64_t PlayerCameraManager = 0x0000000000000430 inline static const uint64_t CameraCachePrivate = 0x000000000002F300 inline static const uint64_t POV = 0x0000000000000010 inline static const uint64_t RootComponent = 0x0000000000000188 inline static const uint64_t RelativeLocation = 0x000000000000016C inline static const uint64_t RelativeRotation = 0x0000000000000178 inline static const uint64_t Mesh = 0x00000000000003E8 inline static const uint64_t MasterPoseComponent = 0x0000000000000718 inline static const uint64_t PlayerState = 0x00000000000003A0 inline static const uint64_t PlayerNamePrivate = 0x0000000000000488 inline static const uint64_t bFinishGame = 0x00000000000004D8 inline static const uint64_t TeamId = 0x000000000000067C inline static const uint64_t CampID = 0x0000000000000680 inline static const uint64_t LoginInfo = 0x0000000000000690 inline static const uint64_t LoginNumber = 0x0000000000000008 inline static const uint64_t CacheCurWeapon = 0x0000000000001560 inline static const uint64_t WeaponID = 0x0000000000000828 inline static const uint64_t HealthComp = 0x0000000000000F00 inline static const uint64_t HealthSet = 0x0000000000000250 inline static const uint64_t Health = 0x0000000000000048 inline static const uint64_t MaxHealth = 0x0000000000000068 inline static const uint64_t CharacterEquipComponentCache = 0x0000000000001F50 inline static const uint64_t EquipmentInfoArray = 0x00000000000001E0 inline static const uint64_t PoolChosenName = 0x0000000000002620 inline static const uint64_t RepItemArray = 0x00000000000017C8 inline static const uint64_t Items = 0x0000000000000108 inline static const uint64_t MarkingItemType = 0x000000000000072A inline static const uint64_t bLooted = 0x0000000000001E60 inline static const uint64_t bHasOpened = 0x0000000000001C54 inline static const uint64_t TipsText = 0x0000000000001D00 inline static const uint64_t Password = 0x0000000000000D44 inline static const uint64_t PwdSum = 0x0000000000000DA0 inline static const uint64_t GWorld = 0x000000015264C588 inline static const uint64_t Gname = 0x0000000152F50400 inline static const uint64_t Matrix = 0x000000015263C520 inline static const uint64_t Object = 0x0000000152F69D88 值得一提的是,三角洲行动的基址固定为5368709120 (0x140000000) ...

August 22, 2025 · 3 min · 638 words · huarui

记一次UE逆向--远光84

记一次UE逆向–远光84 关于 本文章仅供学习交流,请勿用于非法用途 很难想象这是2025年的游戏 反调试 拿到游戏上手,CE xdbg启动,结果啥都搜不到。。全是打问号的数据。 尝试scylla将游戏内存dump下来,没有入口点,IAT表找不到,dump下来的内存全是打问号的数据。 这种情况很奇怪,如果是藤子游戏的反作弊也不至于等你ce或者xdbg附加了才发现。你一启动就被特征提示警告了。。这款游戏的反作弊更像是一种进程保护。 静态分析这一块还是蛮重要的,这个问题不解决没法干活 所以我花了大半天的时间去寻找能过这种奇怪的反调试的工具,没找到。。(程序快写完的时候确实找到了) 就在我万念俱灰的时候,我把游戏重启了一下,CE突然就找到了内容,然后没过几秒钟就变成????? 啊? 这下搞懂了 这游戏进程保护在刚开游戏的时候没加载,大概过了三十秒才加载 所以打开游戏的前三十秒是无敌时间,只需要抢在这三十秒做逆向分析(或者挂起进程),就可以正常分析游戏内容。 结果真尼玛成功了。IAT表,程序入口点都找到了。。。dump下来的内容完全正常。。。 开搞 众所周知UE的逆向全是公式化 Gworld: 搜SeamlessTravel Flushlevelstreaming找Uworld赋值Gworld的地方 得到偏移0x09F379B0 Gname: 搜ByteProperty找交叉引用 这里的继续找交叉引用,F5进去看函数 黄标文字就是Gname,得到偏移0x09DC01C0 其他的不用多说了,都是直接推的,算法大概就是这样: Uworld = DR.读写_读长整数 (进程ID, 模块地址 + 166951344) Gname = 模块地址 + 165413312 Ulevel = DR.读写_读长整数 (进程ID, Uworld + 48) Actor = DR.读写_读长整数 (进程ID, Ulevel + 168) Count = DR.读写_读整数型 (进程ID, Ulevel + 176) GameInstance = DR.读写_读长整数 (进程ID, Uworld + 496) LocalPlayer = DR.读写_读长整数 (进程ID, DR.读写_读长整数 (进程ID, GameInstance + 56)) PlayerController = DR.读写_读长整数 (进程ID, LocalPlayer + 48) APawn = DR.读写_读长整数 (进程ID, PlayerController + 880) 算法 这里提供部分参考代码 ...

August 13, 2025 · 4 min · 765 words · huarui

ue4逆向-ida寻找Gworld到Uworld

ue4-ida寻找Gworld 关于Gworld和Uworld 在虚幻引擎(UE)中,‌GWorld‌是全局变量,指向当前激活的‌ UWorld ‌实例。UWorld代表游戏世界,是游戏的核心容器,负责管理关卡、对象生命周期、物理行为、光照渲染及逻辑执行。 GWorld的作用 GWorld通过指针直接关联到当前活跃的UWorld实例,主要用于存储和切换游戏世界的上下文。在引擎代码中,GWorld通常在初始化时被设置为新加载的游戏世界实例,并负责协调不同世界实例之间的资源管理和状态更新。 与UWorld的关系 UWorld是游戏世界的核心类,包含多个关卡、动态元素(如Actor)的管理以及物理渲染逻辑。GWorld作为全局指针,指向当前正在运行或编辑的UWorld实例,支持多世界并存(如编辑器模式下的主场景、PIE实例等)。 在ida寻找Gworld ue的版本号为4.26.2 https://github.com/EpicGames/UnrealEngine/ dump出来的文件,函数窗口搜索 Anullobject ...

July 25, 2025 · 1 min · 42 words · huarui

目录穿越

目录穿越 写在前面 最近被各种各样的目录穿越恶心到了,所以写了这篇文章来总结一下目录穿越和遇到的题目 思路 构造: 正常 : /download?filename=../../../etcpasswd 双写绕../ : /download?filename=…//…//…///etc/passwd URL编码(双重) : . => %2c / => %2f % => %25 (双重URL编码) 收集的例题(遇到会继续写): 第二届“长城杯”铁人三项赛 (防护赛)初赛 发现 ../hackme.php 文件包含 ../hackme.php 但访问不到 有过滤 尝试绕过过滤 可以双写然后绕过过滤….//hackme.php http://eci-2zef3sej7rworr0h35d8.cloudeci1.ichunqiu.com/index.php?file=....//hackme.php XYCTF2025 源码: # -*- encoding: utf-8 -*- ''' @File : main.py @Time : 2025/03/28 22:20:49 @Author : LamentXU ''' ''' flag in /flag_{uuid4} ''' from bottle import Bottle, request, response, redirect, static_file, run, route with open('../../secret.txt', 'r') as f: secret = f.read() app = Bottle() @route('/') def index(): return '''HI''' @route('/download') def download(): name = request.query.filename if '../../' in name or name.startswith('/') or name.startswith('../') or '\\' in name: response.status = 403 return 'Forbidden' with open(name, 'rb') as f: data = f.read() return data @route('/secret') def secret_page(): try: session = request.get_cookie("name", secret=secret) if not session or session["name"] == "guest": session = {"name": "guest"} response.set_cookie("name", session, secret=secret) return 'Forbidden!' if session["name"] == "admin": return 'The secret has been deleted!' except: return "Error!" run(host='0.0.0.0', port=8080, debug=False) 读取部分的pyaload: ...

April 14, 2025 · 1 min · 162 words · huarui