题目
<?php
$miwen="a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws";
function encode($str){
$_o=strrev($str);
// echo $_o;
for($_0=0;$_0<strlen($_o);$_0++){
$_c=substr($_o,$_0,1);
$__=ord($_c)+1;
$_c=chr($__);
$_=$_.$_c;
}
return str_rot13(strrev(base64_encode($_)));
}
highlight_file(__FILE__);
/*
逆向加密算法,解密$miwen就是flag
*/
?>
源码分析
$miwen="a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws";
这里定义了一个字符串 $miwen
,它可能是加密后的 flag
function encode($str){
...
}
这个函数名虽然叫 encode
,但根据注释,它实际上是一个解密函数。
$_o=strrev($str);
将输入的字符串 $str
反转,并存储在 $_o
中。
strrev
是 PHP 中的一个内置函数,用于反转字符串中的字符顺序。该函数接受一个字符串作为参数,并返回一个新的字符串,其中原始字符串的字符顺序被完全反转。
for($_0=0;$_0<strlen($_o);$_0++){
$_c=substr($_o,$_0,1);
$__=ord($_c)+1;
$_c=chr($__);
$_=$_.$_c;
}
这个循环遍历 $_o
中的每一个字符。对于每一个字符:
$_=$_.$_c;
这行代码的意思是,将 _
变量中当前的值(即之前已经处理过的所有字符的累积结果)与新字符 $_c
连接起来,然后将连接后的新字符串重新赋值给 _
变量。这样,每次循环迭代时,_
变量都会包含到目前为止所有处理过的字符。
经过这个循环,$_
变量存储了处理后的字符串。
- 使用
substr
获取该字符。 - 使用
ord
获取该字符的 ASCII 值。 - 将 ASCII 值加 1。
- 使用
chr
将新的 ASCII 值转换回字符。 - 将这个新的字符附加到
$_
字符串上。在 PHP 中,字符串的连接是通过使用点号(
.
)来完成的。$_=$_.$_c;
这一行代码执行了两个主要的操作: -
$_c
变量包含了当前正在处理的字符的转换版本(即该字符的 ASCII 值加 1 后转换回字符的结果)。 -
$_
变量是累积结果字符串,它开始时可能是一个空字符串(如果之前没有定义过),然后随着循环的进行,它会不断附加新的字符。
substr
是 PHP 中的一个内置函数,用于从字符串中提取子串。它接受三个参数:原始字符串、开始位置和要提取的字符数
函数的语法如下
substr(string $string, int $start, int $length = null): string
$string
:要从中提取子串的原始字符串。$start
:开始提取的位置。如果是正数,则从字符串的开头开始计数;如果是负数,则从字符串的末尾开始计数。$length
(可选):要提取的字符数。如果省略或设为null
,则提取从$start
位置到字符串末尾的所有字符。
ord
是 PHP 中的一个内置函数,用于获取一个字符的 ASCII 值。它接受一个字符作为参数,并返回该字符在 ASCII 编码中的对应数值。
函数的语法如下:
ord(string $string): int
其中 $string
是你想要获取 ASCII 值的单个字符。函数返回一个整数,表示该字符的 ASCII 值。
chr
是 PHP 中的一个内置函数,用于将 ASCII 值转换为对应的字符。它接受一个整数参数,该参数代表一个字符的 ASCII 值,并返回对应的字符
chr(int $ascii): string
其中 $ascii
是你想要转换的 ASCII 值。函数返回一个字符串,该字符串只包含一个字符,即 $ascii
值对应的字符。
return str_rot13(strrev(base64_encode($_)));
首先,使用 base64_encode
对 $_
进行 Base64 编码。
然后,对编码后的字符串进行反转。
最后,使用 str_rot13
对反转后的字符串进行 ROT13 加密。
ROT13 是一种简单的凯撒密码,其中每个字母在字母表中移动 13 位。例如,'A' 变为 'N','B' 变为 'O' 等。
ROT13 是一种简单的替换式密码,也被称为 Caesar cipher 的一种变体。它通过将字母在字母表中向前(或向后,效果相同)移动 13 位来加密文本。由于英文字母表有 26 个字母,移动 13 位实际上等同于向后移动 13 位,因此加密和解密过程是一样的。
在 ROT13 中,字母 'a' 会变成 'n','b' 变成 'o',依此类推,直到 'm' 变成 'z'。然后,字母表会循环回来,所以 'n' 变成 'a','o' 变成 'b',以此类推。非字母字符(如空格、标点符号和数字)在 ROT13 中保持不变。
例如,字符串 "Hello, World!" 使用 ROT13 加密后变为 "Uryyb, Jbeyq!"。
在 PHP 中,实现 ROT13 加密和解密非常简单,因为只需要对字符的 ASCII 值进行相应的调整。但需要注意的是,标准的 ROT13 只对英文字符有效,对于非英文字符(如中文、特殊符号等)可能无法正确加密或解密。
下面是一个简单的 PHP 函数,用于实现 ROT13 加密:
function rot13($str) {
$result = '';
$length = strlen($str);
for ($i = 0; $i < $length; $i++) {
$char = $str[$i];
if (ctype_alpha($char)) { // 检查字符是否为字母
$offset = (ctype_lower($char)) ? 'a' : 'A';
$result .= chr(ord($char) - ord($offset) + 13) % 26 + ord($offset);
} else {
$result .= $char; // 非字母字符保持不变
}
}
return $result;
}
// 使用示例
$text = "Hello, World!";
$encrypted = rot13($text);
echo $encrypted; // 输出: Uryyb, Jbeyq!
在这个函数中,我们遍历输入字符串的每个字符。如果字符是字母,我们就计算它在字母表中的偏移量,并根据 ROT13 的规则调整它。如果字符不是字母,我们就直接将它添加到结果字符串中。
highlight_file(__FILE__);
这行代码会高亮显示当前文件的源代码。
playload构造将加密步骤反过来base_decode base64解码 >strrev 字符串反转>str_rot13解密
>for循环中ord改为-1>再次strrev字符串反转
<?php
$miwen="a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws";
$miwen=base64_decode(strrev(str_rot13($miwen)));
echo $miwen;
$m=$miwen;
for($i=0;$i<strlen($m);$i++){
$_c=substr($m,$i,1);
$__=ord($_c)-1; # 字符转数字,在减1
$__=chr($__); # 数字转字符
$_=$_.$__; # 拼接字符串
}
echo strrev($_); # 反转字符串
~88:36e1bg8438e41757d:29cgeb6e48c`GUDTO|;hbmgflag:{NSCTF_b73d5adfb819c64603d7237fa0d52977}
flag:{NSCTF_b73d5adfb819c64603d7237fa0d52977}