chr()绕过

发布时间 2023-03-26 13:07:21作者: admin_hello

前言

在做CTF时,经常遇到题目过滤很多关键字/字符的情况,然后看到了一种用chr()方法绕过的解法(在PHP环境中).
如环境:


测试:

尝试用chr():

成功.
下面介绍将字符串转化为chr()的小脚本:

复杂版:

<?php
/*
author:star
整体思路:
1:先将传入的字符串分割为单个字符,并放到一个数组$arr1中,
2:利用for循环,将数组$arr1中的每个元素都转为16进制数,并做点修饰
3:将$arr1的每个元素提取出来,拼接到字符串$str1中,拼接完成后发现美中不足的是在最前面有个点,下面代码进行优化
4:重复第一步,将$str1切割,得到数组$arr2
5:利用unset()函数去除$arr2的第一个元素,即第3步提到的点
6.利用for循环将$arr2中的元素提取出来并进行拼接,得到目标$str2
*/
fwrite(STDOUT, "请输入要转化的字符串: \n"); //https://blog.csdn.net/e421083458/article/details/8077297
$str = trim(fgets(STDIN));
echo sprintf("您输入的内容是: %s\n",$str);
$arr1 = str_split($str); //第1步


$str1 = '';  //初始化
for($b=0;$b<sizeof($arr1);$b++){
    $c = '.chr(0x'.bin2hex($arr1[$b]).')'; //第2步将数组中的每个元素都转为16进制,并作适当修饰,形成字符串
    $str1 .= $c;  //第3步:将这些字符串拼接起来
}
//print($str1);//发现在最前面多了一个点
$arr2 = str_split($str1); //第4步
unset($arr2[0]); //第5步:删除数组中第一个元素,删除之后数组的下表从1开始
$str2 = '';//初始化
for($b=1;$b<sizeof($arr2)+1;$b++){  //因为下标从0开始,所以这里$b的值要从原来的0改为1
    $c = $arr2[$b]; //第6步:将数组中的每个元素都转为16进制,并作适当修饰,形成字符串
    $str2 .= $c;  //将这些字符串拼接起来
}
print('转为chr()方式的结果为: '.$str2."\n".'类型为: '.gettype($str2)."\n"); //\n必须由双引号包裹,否则无法起到换行的作用

/*验证的话:不知道为什么,直接print($str2);是不行的,要通过复制在终端得出的结果,然后粘贴到下面的print()中才行
如's'的结果为chr(0x73),验证时是print(chr(0x73));而不是print($str2);
*/

测试:

与前面得到的结果相同.

简化版:

通过trim()函数,简化了去除前后的点的这个步骤,开头的演示就是用的简化版

<?php
/*
author:star
*/
fwrite(STDOUT, "请输入要转化的字符串: \n"); //https://blog.csdn.net/e421083458/article/details/8077297
$str = trim(fgets(STDIN));
echo sprintf("您输入的内容是: %s\n",$str);
$arr1 = str_split($str); //第1步


$str1 = '';  //初始化
for($b=0;$b<sizeof($arr1);$b++){
    $c = '.chr(0x'.bin2hex($arr1[$b]).')'; //第2步将数组中的每个元素都转为16进制,并作适当修饰,形成字符串
    $str1 .= $c;  //第3步:将这些字符串拼接起来
}
//print($str1);//发现在最前面多了一个点
print("转为chr()方式的结果为: \n");
print(trim($str1,'.'));  //trim()的作用是移除字符串左右两边特定的字符
// print(chr(0x27).chr(0x77).chr(0x68).chr(0x6f).chr(0x61).chr(0x6d).chr(0x69).chr(0x27));