01
漏洞简述
应用程序在调用一些能够将字符串转换为代码的函数时,如PHP中的eval(),没有考虑用户是否控制这个字符串,造成的代码执行漏洞。
-
命令执行与代码执行漏洞区别
命令执行漏洞是可以直接调用操作系统命令,代码执行漏洞是靠执行脚本代码调用操作系统命令
-
命令执行&代码执行漏洞危害
可以执行代码、系统命令进行读写文件、反弹shell等操作,拿下服务器,进一步内网渗透等等。
-
代码执行,文件读取,命令执行的函数都有哪些
代码执行:eval,pregreplace+/e,assert,call_userfunc,call_user_func_array,create_function
命令执行:
system(), exec(), shellexec(), passthru() ,pcntlexec(), popen(),proc_open()
文件读取:
filegetcontents(),highlightfile(),fopen(),read file(),fread(),fgetss(), fgets(),parseinifile(),showsource(),file()等
02
代码执行漏洞的原理是在应用程序中存在一种方式,使得用户能够将自己的代码注入到应用程序中执行。这种注入可以是通过用户输入、外部数据源或者其他不可信的来源。当应用程序在处理这些输入时,没有进行适当的验证、过滤或者限制,就会导致恶意代码被执行,从而引发代码执行漏洞。
以下是一般情况下代码执行漏洞的原理:
1. 用户输入未经验证和过滤:应用程序接受用户输入作为参数,并将其直接或间接地传递给可执行代码的函数或解释器。
2. 缺乏输入验证和过滤:应用程序未对用户输入进行充分验证和过滤,未对输入进行安全性检查,或者错误地信任了用户提供的数据。
3. 可执行代码的执行:由于未经验证和过滤的用户输入被传递给可执行代码的函数或解释器,恶意代码被执行,从而导致代码执行漏洞的发生。
4. 潜在危害:恶意代码可以执行任意操作,如修改文件、读取敏感数据、执行系统命令、控制服务器等,威胁应用程序和服务器的安全性。
代码执行漏洞可以以多种形式出现,如动态函数调用、动态类实例化、动态 SQL 查询、动态文件包含等。攻击者可能利用这些漏洞来执行恶意代码,获得越权访问、获取敏感信息或者破坏应用程序的正常功能。
03
代码执行常用函数
在 PHP 中,一些代码执行的函数包括:
Eval()
将字符串当做函数进行执行 需要传入一个完整的语句 必须以分号 ;
结尾 最常用的函数
Assert()
判断是否为字符串 是则当成代码执行 在php7.0.29之后的版本不支持动态调用
Preg_replace()
用来执行一个正则表达式的搜索和替换 执行代码需要使用/e修饰符 前提是不超过php7
mixed preg_replace ( mixed pattern, mixed replacement, mixed subject [, int limit])
-
pattern:正则表达式匹配的内容−replacement: 用于替换的字符串或字符串数组。
-
$subject: 要搜索替换的目标字符串或字符串数组
-
-
动态函数
由于PHP的特性原因,PHP的函数支持直接由拼接的方式调用,这直接导致了PHP在安全上的控制有加大了难度。不少知名程序中也用到了动态函数的写法,这种写法跟使用`call_user_func()`的初衷一样,用来更加方便地调用函数,但是一旦过了不严格就会造成代码执行漏洞。
Array_map()
为数组的每个元素应用回调函数
<?php
highlight_file(__FILE__
);
$a
=$_GET
['a'];
$b
=$_GET
['b'];
$array
[0]=
$b
;
$c
=array_map(
$a
,$array
);
?>
Call_user_func()
回调函数,可以使用is_callable查看是否可以进行调用
mixed call_user_func ( callable $callback [, mixed $parameter [, mixed $... ]] )
第一个参数 callback 是被调用的回调函数 其余参数是回调函数的参数
Call_user_func_array()
array_filter()
array array_filter ( array $array [, callable $callback [, int $flag = 0 ]] )
依次将 array 数组中的每个值传递到 callback 函数 如果 callback 函数返回 true,则 array 数组的当前值会被包含在返回的结果数组中 数组的键名保留不变。
把输入数组中的每个键值传给回调函数,与 call_user_func_array() 不同的是,该函数的第一个参数 为回调函数的参数,而第二个参数则是传入的回调函数。
Array_walk()
array_walk() 函数对数组中的每个元素应用用户自定义函数。在函数中,数组的键名和键值是参数。
Create_function()
用来创建匿名函数
create_function(string $args,string $code)
-
args是要创建的函数的参数
-
code是函数内的代码
$a = @create_function('$abc', } system(dir);/* );
ob_start()
此函数将打开输出缓冲,当输出缓冲激活后,脚本将不会输出内容(除http标头外) 相反需要输出的内容被存储在内部缓冲区中。
内部缓冲区的内容可以用 ob_get_contents()
函数复制到一个字符串变量中
想要输出存储在内部缓冲区中的内容
可以使用 ob_end_flush()
函数 另外, 使用 ob_end_clean()
函数会静默丢弃掉缓冲区的内容
usort()
使用自定义函数对数组进行排序
bool usort ( array &$array , callable $value_compare_func )
本函数将用用户自定义的比较函数对一个数组中的值进行排序 如果要排序的数组需要用一种不寻常的标准进行排序,那么应该使用此函数
usort() 函数参数可控,也可能可造成RCE。PHP版本<=5.6可实现
04
安全建议
安全建议
1. 验证和过滤用户输入:对于所有用户提供的数据,包括表单输入、URL 参数、Cookie 值等,都应该进行严格的验证和过滤。确保只接受预期的输入,并拒绝或处理恶意或非法的输入。
2. 使用白名单和最小权限原则:限制可以执行代码的环境和权限。使用白名单机制,只允许特定的安全操作和函数调用。同时,确保代码在最小权限的执行环境中运行,以减少潜在的安全风险。
3. 不信任用户输入:永远不要直接将用户输入作为代码执行的一部分。用户提供的数据应该被视为潜在的不可信任来源。在使用用户输入时,使用枚举的方法或者安全的替代方法,以避免代码执行漏洞。
4. 严格的输入验证和过滤:对于需要允许一定程度的动态代码的情况,应该进行严格的输入验证和过滤。使用安全的解析器或语法分析器来解析和执行动态代码,确保只允许安全的操作,并限制执行环境。
5. 安全编码实践:采用安全的编码实践,包括避免使用已知的不安全函数、避免拼接用户输入和代码、避免动态构建代码字符串等。了解和遵循最佳的安全编码准则和标准,如 OWASP Top 10。
6. 安全更新和漏洞修复:定期更新和修复已知的安全漏洞。保持应用程序和相关组件的最新版本,并及时应用安全补丁。
综合以上措施,可以有效减少代码执行漏洞的风险。然而,安全是一个持续的过程,需要综合考虑应用程序的整体安全性,并在开发、部署和运行过程中进行全面的安全测试和审计。
End
原文始发于微信公众号(贝雷帽SEC):WEB 安全--深入学习代码执行漏洞(一)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论