Results 1 to 8 of 8

Thread: Neopets cookies?

  1. #1

    Joined
    Oct 2014
    Posts
    15
    Userbars
    0
    Thanks
    0
    Thanked
    4/2
    DL/UL
    24/0
    Mentioned
    1 time
    Time Online
    13h 48m
    Avg. Time Online
    N/A

    Neopets cookies?

    I didn't really find a forum specific to this question, but it's kind of programming related and kind of neopets hacking related so it goes here.

    So when playing around with neopets, sending some cookies back to index.phtml, and I got the following headers:

    HTTP/1.1 200 OK
    Date Sat, 11 Oct 2014 00:57:43 GMT
    Server Apache/2.2.15 (CentOS)
    X-Powered-By PHP/5.4.28
    X-Cobalt loaded
    X-XSS-Protection 0
    Set-Cookie np_uniq=pending; expires=Sun, 11-Oct-2015 00:57:44 GMT; path=/; domain=.neopets.com
    Set-Cookie nupi=0; expires=Fri, 10-Oct-2014 23:17:44 GMT; path=/; domain=.neopets.com
    Set-Cookie nupid=0; expires=Fri, 10-Oct-2014 23:17:44 GMT; path=/; domain=.neopets.com
    Set-Cookie npid=0; expires=Fri, 10-Oct-2014 23:17:44 GMT; path=/; domain=.neopets.com

    Set-Cookie npuid=00000000000000000000000000000000000000000000 00000000000000000000; expires=Mon, 10-Nov-2014 00:57:44 GMT; path=/; domain=.neopets.com
    Set-Cookie ld_=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/; domain=.neopets.com
    Set-Cookie np_uniq_=2014-10-10; expires=Sun, 11-Oct-2015 00:57:44 GMT; path=/; domain=.neopets.com
    Connection close
    Transfer-Encoding chunked
    Content-Type text/html; charset=UTF-8

    What's up with the expiry times on these cookies being before the time the headers were sent? Is this the standard way http deletes cookies? Or is this neopets trying to detect programs that don't handle cookie expirations properly? Or what?

  2. #2
    Zachafer's Avatar
    Joined
    Dec 2011
    Posts
    1,235
    Userbars
    11
    Thanks
    769
    Thanked
    1,466/678
    DL/UL
    98/0
    Mentioned
    512 times
    Time Online
    24d 13h 9m
    Avg. Time Online
    8m
    I've seen that, not sure why they do that. The browser will delete those cookies when the page loads

  3. #3

    Joined
    Jun 2012
    Posts
    1,699
    Thanks
    876
    Thanked
    2,881/1,142
    DL/UL
    44/1
    Mentioned
    562 times
    Time Online
    118d 6h 45m
    Avg. Time Online
    40m
    here is the source code to cookies.php

    Code:
    <?php
    
    uselib('db/db_funcs_v1');
    uselib('db/npflags_v1');
    uselib('content/neofriend_func');
    uselib('neopets/UserUtils');
    
    
    uselib('neopets/flag_defs');
    NeopetsSiteFlags::register();
    
    
    class NPCookies {
    	const LOGIN_COOKIE_NAME = 'neologin';
    	const TOOLBAR_COOKIE_NAME = 'toolbar';
    
    
    	const SALT_NORMAL = '88f5065ac4';
    	const SALT_STEALTH = 'e044aa45d2';
    
    
    	/**
    	 * Constrain the cookie code value to a legal range.  The lower limit is
    	 * 1000, not 1, because neologin_decode() returns 0 if the ciphertext is
    	 * malformed.  Since we allow cookie codes to match within +/- 2 of the
    	 * actual value, this would cause a false authentication if someone's
    	 * cookie_code was 1 or 2, and the cookie decrypted to 0.
    	 * 
    	 * @param int $val 
    	 * @(you need an account to see links)
    	 * @access public
    	 * @(you need an account to see links) int
    	 */
    	public static function clamp_cookie_code($val) {
    		return min(max($val, 1000), 999999999);
    	}
    
    
    	/**
    	 * Break the login cookie into its component parts.  Returns false if the
    	 * cookie is malformed.
    	 * 
    	 * @(you need an account to see links)
    	 * @access public
    	 * @(you need an account to see links) array|bool
    	 */
    	public static function parse_login_cookie() {
    		$out = false;
    
    
    		if (!isset($_COOKIE[self::LOGIN_COOKIE_NAME])) return false;
    
    
    		if (preg_match("/^([^+]+)\+([^+]+)$/", $_COOKIE[self::LOGIN_COOKIE_NAME], $matches)) {
    			$out = array(
    				'cookie'     => $_COOKIE[self::LOGIN_COOKIE_NAME],
    				'username'   => strtolower(substr($matches[1], 0, 20)), // make sure it's max 20 chars long and is all lowercase
    				'ciphertext' => $matches[2]
    			);
    		}
    
    
    		return $out;
    	}
    
    
    	/**
    	 * Break the toolbar cookie into its component parts.  Returns false if the
    	 * cookie is malformed.
    	 * 
    	 * @(you need an account to see links)
    	 * @access public
    	 * @(you need an account to see links) array|bool
    	 */
    	public static function parse_toolbar_cookie() {
    		$out = false;
    
    
    		if (!isset($_COOKIE[self::TOOLBAR_COOKIE_NAME])) return false;
    
    
    		if (preg_match("/^([^+]+)\+([^+]+)\+([^+]+)$/", $_COOKIE[self::TOOLBAR_COOKIE_NAME], $matches)) {
    			$out = array(
    				'cookie'     => $_COOKIE[self::TOOLBAR_COOKIE_NAME],
    				'username'   => strtolower(substr($matches[1], 0, 20)), // make sure it's max 20 chars long and is all lowercase
    				'userclass'  => $matches[2],
    				'ciphertext' => $matches[3]
    			);
    		}
    
    
    		return $out;
    	}
    
    
    	/**
    	 * Return the standard formatted input for the cookie hash function to use.
    	 * 
    	 * @param string $username 
    	 * @param string $password 
    	 * @(you need an account to see links)
    	 * @access public
    	 * @(you need an account to see links) string
    	 */
    	public static function get_normal_key($username, $password) {
    		return "{$username}{$password}" . self::SALT_NORMAL;
    	}
    
    
    	/**
    	 * Same as get_normal_key(), but with the stealth salt.
    	 * 
    	 * @param string $username 
    	 * @param string $password 
    	 * @(you need an account to see links)
    	 * @access public
    	 * @(you need an account to see links) string
    	 */
    	public static function get_stealth_key($username, $password) {
    		return "{$username}{$password}" . self::SALT_STEALTH;
    	}
    
    
    	/**
    	 * Basic function for hashing a cookie value.  $key is their password, and
    	 * $plaintext is the cookie_code value.
    	 * 
    	 * @param string $key 
    	 * @param string $plaintext 
    	 * @(you need an account to see links)
    	 * @access public
    	 * @(you need an account to see links) string
    	 */
    	public static function cookie_hash_encrypt($key, $plaintext) {
    		// Do not change the message string below or it'll log everyone out.
    		// Conversely, if you want to log everyone out, change the message string below. :)
    		$message = "npc_{$key}_{$plaintext}_biglongrandomstringhahalolthecakeisalie";
    		return sha1($message);
    	}
    
    
    	/**
    	 * Set the login cookie.
    	 * 
    	 * @param string $username 
    	 * @param string $key 
    	 * @param string $plaintext 
    	 * @param int $expire 
    	 * @(you need an account to see links)
    	 * @access public
    	 * @(you need an account to see links) void
    	 */
    	public static function set_login_cookie($username, $key, $plaintext, $expire) {
    		// make sure the cookie is never set for frozen users - NEADMN-34 - adamb / 2010-06-24
    		if (is_frozen($username)) {
    			return false;
    		}
    		$cookie_value = "{$username}+" . self::cookie_hash_encrypt($key, $plaintext);
    		setcookie(self::LOGIN_COOKIE_NAME, $cookie_value, $expire, "/", ".neopets.com");
    		$_COOKIE[self::LOGIN_COOKIE_NAME] = $cookie_value;
    	}
    
    
    	/**
    	 * Set the toolbar cookie.  This is used for the VSI/premium toolbar.
    	 * 
    	 * @param string $username 
    	 * @param string $key 
    	 * @param string $plaintext 
    	 * @param int $expire 
    	 * @param string $password 
    	 * @param string $dob 
    	 * @(you need an account to see links)
    	 * @access public
    	 * @(you need an account to see links) void
    	 */
    	public static function set_toolbar_cookie($username, $key, $plaintext, $expire, $password, $dob) {
    		// make sure the cookie is never set for frozen users - NEADMN-34 - adamb / 2010-06-24
    		if (is_frozen($username)) {
    			return false;
    		}
    		$hash = self::cookie_hash_encrypt($key, $plaintext);
    		$permission = npflag_check($username, NPFLAG_PARENTAL_PERMISSION);
    		$agecode = self::toolbar_cookie_agecode($dob, $permission);
    		$cookie_value = "{$username}+{$agecode}+{$hash}";
    		setcookie(self::TOOLBAR_COOKIE_NAME, $cookie_value, $expire, "/", ".neopets.com");
    		$_COOKIE[self::TOOLBAR_COOKIE_NAME] = $cookie_value;
    	}
    
    
    	/**
    	 * Calculate the agecode to put into the toolbar cookie.
    	 * 
    	 * @param string $dob 
    	 * @param bool $permission 
    	 * @(you need an account to see links)
    	 * @access public
    	 * @(you need an account to see links) string
    	 */
    	public static function toolbar_cookie_agecode($dob, $permission) {
    		if ($dob == '') $age = 0;
    		else $age = UserUtils::ageFromDob($dob);
    
    
    		if ($age < 13) {
    			if (!$permission) {
    				$agecode = 'A';
    			} else {
    				$agecode = 'D';
    			}
    		} else if ($age < 18) {
    			$agecode = 'B';
    		} else {
    			$agecode = 'C';
    		}
    
    
    		return $agecode;
    	}
    
    
    	/**
    	 * Update last_logged_time and cookie_code.
    	 * 
    	 * @param string $username 
    	 * @param int $time 
    	 * @param string $cookie_code 
    	 * @(you need an account to see links)
    	 * @access public
    	 * @(you need an account to see links) void
    	 */
    	public static function update_llt_cc($username, $time, $cookie_code) {
    		$sql = "UPDATE personal SET last_logged_time = '{$time}', cookie_code = '{$cookie_code}' WHERE username = '{$username}'";
    		$rsUpdate = myoci("", $sql);
    		return $rsUpdate;
    	}
    
    
    	/**
    	 * Try to decode a cookie with both the regular and stealth salts, and
    	 * return which one worked (if any).
    	 * 
    	 * @param string $username 
    	 * @param string $password 
    	 * @param int $cookie_code 
    	 * @(you need an account to see links)
    	 * @access public
    	 * @(you need an account to see links) array
    	 */
    	public static function decrypt_login_cookie($username, $password, $cookie_code) {
    		$parts = self::parse_login_cookie();
    		if ($parts == false) return false;
    
    
    		$out = array(
    			'parts'      => $parts,
    			'normal'     => false,
    			'stealth'    => false,
    			'pt_normal'  => '',
    			'pt_stealth' => '',
    		);
    
    
    		$key_normal = self::get_normal_key($username, $password);
    		$key_stealth = self::get_stealth_key($username, $password);
    
    
    		// The order here is from most likely to least likely.  Usually the 0 offset will match;
    		// if not, then it's likely that they're 1 behind.  If not, then 2 behind.  Failing that,
    		// we try +1 and +2 which will almost never succeed.
    		$offsets = array(0, -1, -2, 1, 2);
    
    
    		foreach ($offsets as $offset) {
    			// For each offset, we need to try encrypting with the cookie_code plus that offset and see if it matches.
    	
    			$normal_hash = self::cookie_hash_encrypt($key_normal, $cookie_code + $offset);
    			if ($normal_hash == $parts['ciphertext']) $out['normal'] = true;
    			else {
    				$stealth_hash = self::cookie_hash_encrypt($key_stealth, $cookie_code + $offset);
    				if ($stealth_hash == $parts['ciphertext']) $out['stealth'] = true;
    			}
    
    
    			// If we found the correct hash, there's no reason to check the rest.
    			if ($out['normal'] == true || $out['stealth'] == true) break;
    		}
    
    
    		return $out;
    	}
    
    
    	/**
    	 * Same as decrypt_login_cookie, but for the toolbar cookie.
    	 * 
    	 * @param string $username 
    	 * @param string $password 
    	 * @param int $cookie_code 
    	 * @(you need an account to see links)
    	 * @access public
    	 * @(you need an account to see links) array
    	 */
    	public static function decrypt_toolbar_cookie($username, $password, $cookie_code) {
    		$parts = self::parse_toolbar_cookie();
    		if ($parts == false) return false;
    
    
    		$out = array(
    			'parts'      => $parts,
    			'normal'     => false,
    			'stealth'    => false,
    			'pt_normal'  => '',
    			'pt_stealth' => '',
    		);
    
    
    		$key_normal = self::get_normal_key($username, $password);
    		$key_stealth = self::get_stealth_key($username, $password);
    
    
    		// The order here is from most likely to least likely.  Usually the 0 offset will match;
    		// if not, then it's likely that they're 1 behind.  If not, then 2 behind.  Failing that,
    		// we try +1 and +2 which will almost never succeed.
    		$offsets = array(0, -1, -2, 1, 2);
    
    
    		// Try to decrypt it the old way.  If it works, yay.  If not, try the new way.
    		// Once there are no more cookies encrypted the old way, we can get rid of this.
    
    
    		// For the toolbar cookie, the "old way" was a simple MD5 hash of the password.  Clever.
    		if ($parts['ciphertext'] == md5($password)) {
    			$out['normal'] = true;
    			return $out;
    		} else {
    
    
    			// Okay, it didn't work using the old method.  Try the new method.
    
    
    			foreach ($offsets as $offset) {
    				// For each offset, we need to try encrypting with the cookie_code plus that offset and see if it matches.
    
    
    				$normal_hash = self::cookie_hash_encrypt($key_normal, $cookie_code + $offset);
    				if ($normal_hash == $parts['ciphertext']) $out['normal'] = true;
    				else {
    					$stealth_hash = self::cookie_hash_encrypt($key_stealth, $cookie_code + $offset);
    					if ($stealth_hash == $parts['ciphertext']) $out['stealth'] = true;
    				}
    
    
    				// If we found the correct hash, there's no reason to check the rest.
    				if ($out['normal'] == true || $out['stealth'] == true) break;
    			}
    
    
    		}
    
    
    		return $out;
    	}
    
    
    	/**
    	 * The main cookie manipulation method.  Can be used to set, update, check,
    	 * or clear the login cookie.
    	 * 
    	 * @param obj $NPUser 
    	 * @param string $action 
    	 * @param string $lang 
    	 * @(you need an account to see links)
    	 * @access public
    	 * @(you need an account to see links) bool
    	 */
    	public static function update_login_cookie($NPUser, $action, $lang) {
    
    
    		// Convenience vars
    		$new_code = intval($NPUser->cookie_code);
    
    
    		// Make sure cookie_code is in the valid range.
    		$new_code = self::clamp_cookie_code($new_code);
    
    
    		$now = time();
    
    
    		// set cookie expiration time, admins only get 12 hours
    		$expire = ($NPUser->is_admin) ? ($now + (3600 * 12)) : ($now + (3600 * 24 * 365));
    
    
    		if ($action == 'login' || $action == 'stealth') {
    
    
    			if ($action == 'login') {
    
    
    				// Anyone whose password isn't a 20-char hex string gets it changed forcibly here.
    				// This block can be deleted on or after 2012-03-01. - waggonem 2012-01-11
    				if (!preg_match('/^[a-f0-9]{20}$/', $NPUser->password)) {
    					$token = self::resetLoginToken($NPUser->username);
    					$NPUser->password = $token;
    				}
    
    
    				$key = self::get_normal_key($NPUser->username, $NPUser->password);
    
    
    				// Regular logins cause the last_logged_time and cookie_code to be updated;
    				// stealth logins do not.
    				$new_code = self::clamp_cookie_code($new_code + 1);
    				self::update_llt_cc($NPUser->username, $now, $new_code);
    
    
    				// Also do session tracking.  TODO: Shouldn't this use $now?
    				self::session_tracker($NPUser, $lang);
    
    
    			} else if ($action == 'stealth') {
    				$key = self::get_stealth_key($NPUser->username, $NPUser->password);
    			}
    
    
    			// Set the login cookie.
    			self::set_login_cookie($NPUser->username, $key, $new_code, $expire);
    
    
    			// Set the old login cookie, too.
    			self::set_toolbar_cookie($NPUser->username, $key, $new_code, $expire, $NPUser->password, $NPUser->dob);
    
    
    		} else if ($action == 'logout') {
    
    
    			// Log out.  This causes all the login cookies to be cleared from the
    			// user's computer.  If the user is currently normally logged in, then
    			// we also update their llt and cookie_code, which will invalidate any
    			// OTHER cookies (that, e.g. might have gotten grabbed).
    
    
    			// Stealth logouts do not cause an llt/cc update, because we don't want
    			// to interfere with the legitimately logged-in user.
    
    
    			$decrypt = self::decrypt_login_cookie($NPUser->username, $NPUser->password, $new_code);
    
    
    			if ($decrypt != false && $decrypt['normal'] == true) {
    
    
    				$new_code = self::clamp_cookie_code($new_code + 5);
    				self::update_llt_cc($NPUser->username, $now, $new_code);
    
    
    				// Track session info.
    				self::session_tracker($NPUser, $lang);
    			}
    
    
    			// Clear all the login cookies.
    			setcookie(self::LOGIN_COOKIE_NAME,    '', 0, "/", ".neopets.com");
    			setcookie(self::TOOLBAR_COOKIE_NAME,  '', 0, "/", ".neopets.com");
    
    
    		} else if ($action == 'check' || $action == 'check_no_update') {
    
    
    			// Validate the cookie.  This is used to determine whether the user is actually logged in.
    			// The 'check_no_update' action means that we only examine the cookie, we don't even bother
    			// trying to update it.
    
    
    			$decrypt = self::decrypt_login_cookie($NPUser->username, $NPUser->password, $new_code);
    
    
    			// The cookie was malformed, or the ciphertext did not decrypt with either key.
    			if ($decrypt == false || ($decrypt['normal'] == false && $decrypt['stealth'] == false)) {
    				return false;
    			}
    
    
    			// If it's been more than 5 minutes since the last update, we want to
    			// increment the cookie_code counter and resave the cookie.
    
    
    			if ($action == 'check' && $now - $NPUser->last_logged_time > 300) {
    
    
    				// If it's a normal login, then we update llt and cookie_code.
    				if ($decrypt['normal'] == true) {
    					// Update their last_logged_time and cookie_code.
    					$new_code = self::clamp_cookie_code($new_code + 1);
    					self::update_llt_cc($NPUser->username, $now, $new_code);
    
    
    					// track session info
    					self::session_tracker($NPUser, $lang);
    
    
    					$key = self::get_normal_key($NPUser->username, $NPUser->password);
    				} else if ($decrypt['stealth'] == true) {
    					$key = self::get_stealth_key($NPUser->username, $NPUser->password);
    				}
    
    
    				// Refresh the cookie for normal AND stealthed users.
    				self::set_login_cookie($NPUser->username, $key, $new_code, $expire);
    
    
    				// Refresh the old cookie, too.
    				self::set_toolbar_cookie($NPUser->username, $key, $new_code, $expire, $NPUser->password, $NPUser->dob);
    			}
    
    
    			// Whether or not we updated llt/cc and refreshed the cookie, either the old one
    			// or the new one matched.  Validated!  Yay!
    			//return true;
    
    
    			// return false if the user is frozen - NEADMN-34 - adamb / 2010-06-24
    			return is_frozen($NPUser->username) ? false : true;
    		}
    
    
    		// Return false in all other cases.
    		return false;
    	}
    
    
    	/**
    	 * Track user sessions.  A horrible abomination.
    	 * 
    	 * @param obj $NPUser 
    	 * @param string $lang 
    	 * @(you need an account to see links)
    	 * @access public
    	 * @(you need an account to see links) void
    	 */
    	public static function session_tracker($NPUser, $lang) {
    		// This is horrible.  We have to stop using this somehow.  But who can
    		// save us?
    		global $xt6Yr4e33D;
    
    
    		if ($xt6Yr4e33D != '') {
    
    
    			$code = $xt6Yr4e33D;
    			$now = time();
    			$cutoff = $now - 1800;
    
    
    			if ($NPUser->last_logged_time < $cutoff) {
    				$sql = "INSERT IGNORE INTO expired_sessions SELECT * FROM active_sessions WHERE code = '{$code}' AND end_time < '{$cutoff}'";
    				myoci('', $sql);
    
    
    				$sql = "INSERT INTO active_sessions (code, start_time, end_time, ip, lang) VALUES ('{$code}', '{$now}', '{$now}', '{$_SERVER['REMOTE_ADDR']}', '{$lang}') ON DUPLICATE KEY UPDATE end_time = '{$now}', start_time = '{$now}', ip = '{$_SERVER['REMOTE_ADDR']}', lang = '{$lang}'";
    				myoci('', $sql);
    			} else {
    				$sql = "INSERT INTO active_sessions (code, start_time, end_time, ip, lang) VALUES ('{$code}', '{$now}', '{$now}', '{$_SERVER['REMOTE_ADDR']}', '{$lang}') ON DUPLICATE KEY UPDATE end_time = '{$now}'";
    				myoci('', $sql);
    			}
    
    
    			if ($NPUser->username != '') {
    				$sql = "UPDATE active_sessions SET username = '{$NPUser->username}', userflag = '{$NPUser->flags}', gender = '{$NPUser->sex}', dob = '{$NPUser->dob}', age = '{$NPUser->age}', dma = '{$NPUser->dma}', lang = '{$lang}', signup_country = '{$NPUser->country}', ip_country = '{$NPUser->geoip_country}', zip = '{$NPUser->zipcode}' WHERE code = '{$code}'";
    				myoci('', $sql);
    			}
    		}
    	}
    
    
    
    
    	/**
    	 * We need to be able to generate a random 20-char string to put into the
    	 * password field, now that it is no longer containing the user's canonical
    	 * password.
    	 */
    	public static function genPasswordToken() {
    		mt_srand();
    		return substr(sha1(uniqid('', true)), 0, 20);
    	}
    
    
    
    
    	/**
    	 * Reset a user's login token.
    	 */
    	public static function resetLoginToken($username) {
    		$token = self::genPasswordToken();
    		$sql = "UPDATE personal SET password = '{$token}' WHERE username = '{$username}' LIMIT 1";
    		$rsUpdate = myoci('', $sql);
    		return $token;
    	}
    
    
    }
    Last edited by DarkByte; 10-13-2014 at 10:50 PM.

  4. The Following User Says Thank You to DarkByte For This Useful Post:

    txtsd (10-13-2014)

  5. #4
    txtsd's Avatar
    Joined
    Dec 2012
    Posts
    642
    Userbars
    7
    Thanks
    538
    Thanked
    327/146
    DL/UL
    60/2
    Mentioned
    91 times
    Time Online
    31d 8h 56m
    Avg. Time Online
    10m
    @(you need an account to see links) wrap it in [CODE] tags, noob

  6. The Following User Says Thank You to txtsd For This Useful Post:

    DarkByte (10-14-2014)

  7. #5

    Joined
    Jun 2012
    Posts
    1,699
    Thanks
    876
    Thanked
    2,881/1,142
    DL/UL
    44/1
    Mentioned
    562 times
    Time Online
    118d 6h 45m
    Avg. Time Online
    40m
    I did but it all messed up and went to single lines xD


    Edit:

    Ok noob status confirmed , [code] works i was usin [php]
    Last edited by DarkByte; 10-13-2014 at 10:51 PM.

  8. The Following User Says Thank You to DarkByte For This Useful Post:

    txtsd (10-13-2014)

  9. #6

    Joined
    Oct 2014
    Posts
    15
    Userbars
    0
    Thanks
    0
    Thanked
    4/2
    DL/UL
    24/0
    Mentioned
    1 time
    Time Online
    13h 48m
    Avg. Time Online
    N/A
    Quote Originally Posted by DarkByte View Post
    here is the source code to cookies.php

    Code:
    code expunged for brevity.
    Thanks, that's actually very helpful. Do you have the php source for all of neopets?

  10. #7

    Joined
    Jun 2012
    Posts
    1,699
    Thanks
    876
    Thanked
    2,881/1,142
    DL/UL
    44/1
    Mentioned
    562 times
    Time Online
    118d 6h 45m
    Avg. Time Online
    40m
    Yep pretty much

  11. #8
    Josh's Avatar
    Joined
    Dec 2011
    Posts
    415
    Userbars
    2
    Thanks
    25
    Thanked
    378/143
    DL/UL
    82/6
    Mentioned
    120 times
    Time Online
    17d 9h 48m
    Avg. Time Online
    5m
    @(you need an account to see links) - You're ridiculous. Lol.

  12. The Following User Says Thank You to Josh For This Useful Post:

    DarkByte (10-14-2014)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •