The encrypted string:
fR4aHWwuFCYYVydFRxMqHhhCKBseH1dbFygrRxIWJ1UYFhotFjA=
Title download address:
https://ctf.bugku.com/files/6b8e8eb682d757d851cd5dcdca349668/PHP_encrypt_1.zip
After downloading the zip, obtain the following code and analyze it:
<?php
function encrypt($data,$key)
{
$key = md5('ISCC');
$x = 0;
$len = strlen($data);
$klen = strlen($key);
for ($i=0; $i < $len; $i++) {
if ($x == $klen)
{
$x = 0;
}
$char .= $key[$x];
$x+=1;
}
for ($i=0; $i < $len; $i++) {
$str .= chr((ord($data[$i]) + ord($char[$i])) % 128);
}
return base64_encode($str);
}
?>
Script reverse analysis:
1. Parse from the back to the front, $str has undergone a base64 encryption. We first use the decode function to decrypt:
<?php
echo base64_decode("fR4aHWwuFCYYVydFRxMqHhhCKBseH1dbFygrRxIWJ1UYFhotFjA=");
?>
Get the base64 decrypted string:
2. $str
Before the variable is generated, it goes through a for loop:
for ($i=0; $i < $len; $i++) {
$str .= chr((ord($data[$i]) + ord($char[$i])) % 128);
}
Several functions and variables in the for loop:
- $len = the length of the $data string (the string length of $data is the length of the string after base64 decryption, which is the same as the length of the original flag, and has not changed.)
- $char
- chr(): Convert an asill code into characters
- ord(): convert characters into ascii codes
- %: Remainder
- $data: is the original flag
The string of the original flag is added to the ascii code corresponding to the variable char, and the ascii code after 128 is converted into a character and spliced on $str.
Encryption formula analysis:
(I am poor in math... I am trying to make up for it)
The ord($data[$i])
as a
will ord($char[$i]
as b
will $str
asc
(a+b)%128=c
Decryption formula:
如果 b+c<=128
解: a=128+c-b
如果 b+c>128
解:如果(c-b)大于128
a=c-b-128
如果不大于128
a=c-b
3. After analyzing the encryption method in the for loop, we need to know the contents of the $char variable and continue to analyze the previous for loop.
$key = md5('ISCC');
$x = 0;
$len = strlen($data);
$klen = strlen($key);
for ($i=0; $i < $len; $i++) {
if ($x == $klen)
{
$x = 0;
}
$char .= $key[$x];
$x+=1;
}
function:
- md5(): MD5 encrypt the string
- strlen(): Get the length of the string
Code analysis:
- MD5 encryption of ISCC
$key = md5('ISCC');
- Calculate the string length of $data and assign it to $len. Calculate the string length of $key and assign it to $klen. The
len variable is the same as the string length after base64 decryption. The
klen variable is equal to 32 (because the md5 encryption has a length of 32 bits )
$len = strlen($data);
$klen = strlen($key);
- The for loop is executed to calculate the value of $char
for ($i=0; $i < $len; $i++) {
#for循环$len次
if ($x == $klen)#如果$x等于32,那么$x将等于0
{
$x = 0;
}
$char .= $key[$x];#char: 如果$data长度为10,那么会将$key的前10位赋值给$char
$x+=1;
}
After analyzing the code value of $char, you can use the previous 余求值
decryption formula to solve the value of data(flag).
<?php
$str= base64_decode("fR4aHWwuFCYYVydFRxMqHhhCKBseH1dbFygrRxIWJ1UYFhotFjA=");
$key = md5('ISCC');
$x = 0;
$len = strlen($str);
$klen = strlen($key);
for ($i=0; $i < $len; $i++) {
if ($x == $klen)
{
$x = 0;
}
$char .= $key[$x];
$x+=1;
}
for ($i=0; $i < $len; $i++) {
if (ord($char["$i"])+ord($str["$i"])<=128)
{
$data.=chr(128+ord($str["$i"])-ord($char["$i"]));
}else{
$data1=chr(ord($str["$i"])-ord($char["$i"]));
if (ord($data1) >128 ){
$data.=chr(ord($data1)-128);
}else{
$data.=$data1;
}
}
}
echo $data;
?>