Project Gazelle is a php frontend for private bittorrent tracker, developed by What.CD sysops.
Private tracker that use Gazelle : What.CD, Save The Coratee, TorrentIt, Vortex, Wunza, Filmdom, PTP, etc.
The source code itself is available to public, google it for more info.
After you read this article, I hope you gain knowledge about how staff member found cheater and avoid any future ban from What.CD
Note from the developers :
"some of our tools, such as cheater evasion, will not be included in the public version of the source, for obvious reasons."
This is true. If you read the source code, it's clear that they remove any anti-cheating script from the public source code.
But keep reading, you'll understand how they caught cheater so fast even if you make a little mistake.
I'll divide the analysis into two sections :
I. Gazelle Source Code
II. Staff Account's Screenshot
I. Gazelle Source Code
PHP Code:
// Check DNS blacklists to see if IP is a proxy or a tor node
function blacklisted_ip($IP) {
// http://en.wikipedia.org/wiki/Comparison_of_DNS_blacklists
$DNSBLs = array('http.dnsbl.sorbs.net', 'misc.dnsbl.sorbs.net', 'socks.dnsbl.sorbs.net', 'ohps.dnsbl.net.au', 'tor.dan.me.uk');
// Reverse IP, so 127.0.0.1 becomes 1.0.0.127
$IP = implode('.', array_reverse(explode('.', $IP)));
foreach($DNSBLs as $DNSBL) {
$TestHost = $IP.'.'.$DNSBL;
$ResolvedHost = gethostbyname($TestHost);
if($ResolvedHost!=$TestHost) {
return $DNSBL.' ('.$TestHost.' returned '.$ResolvedHost.')';
}
}
return false;
}
This function checks if the user use proxy / tor to access the website by checking these lists :
1. http.dnsbl.sorbs.net : Open HTTP proxy servers
2. misc.dnsbl.sorbs.net : Additional proxy servers
3. socks.dnsbl.sorbs.net : Open SOCKS proxy servers
4. ohps.dnsbl.net.au : RIP as of April 29,2009
5. tor.dan.me.uk : All tor nodes (both entry and exit nodes)
You can use dnsbltools.com to check if your IP/proxy is in DNS blacklists or not.
PHP Code:
// Cookie management
if ($_COOKIE['keeplogged']!='') {
$LoginCookie=decrypt($_COOKIE['keeplogged']);
$LoginCookie=explode("|~|",decrypt($LoginCookie));
$CookieID = $LoginCookie[2];
if($CookieID!=$LoggedUser['CookieID'] || !$CookieID) {
// The user's cookie is different from the one we have stored in the database
// They're either trying hax, or have logged in from multiple computers.
// Both of these are a big no-no.
logout();
}
}
This routine check if the cookie in your browser and database is different or not.
PHP Code:
CREATE TABLE `cheater_log` (
`ID` int(5) NOT NULL auto_increment,
`Client` varchar(8) default NULL,
`User` int(10) default NULL,
`TorrentID` int(10) default NULL,
`Test` int(2) default NULL,
`Time` timestamp NOT NULL default CURRENT_TIMESTAMP,
`Peers` text,
`GroupID` int(10) default NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Once they caught cheater, they store the data in this table.
PHP Code:
CREATE TABLE `users_history_emails` (
`UserID` int(10) NOT NULL,
`OldEmail` varchar(255) default NULL,
`NewEmail` varchar(255) default NULL,
`ChangeTime` datetime default NULL,
`ChangerIP` varchar(15) default NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `users_history_ips` (
`UserID` int(10) NOT NULL,
`IP` varchar(15) NOT NULL default '0.0.0.0',
`StartTime` datetime NOT NULL default '0000-00-00 00:00:00',
`EndTime` datetime default NULL,
PRIMARY KEY (`UserID`,`IP`,`StartTime`),
KEY `UserID` (`UserID`),
KEY `IP` (`IP`),
KEY `StartTime` (`StartTime`),
KEY `EndTime` (`EndTime`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `users_history_passkeys` (
`UserID` int(10) NOT NULL,
`OldPassKey` varchar(32) default NULL,
`NewPassKey` varchar(32) default NULL,
`ChangeTime` datetime default NULL,
`ChangerIP` varchar(15) default NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `users_history_passwords` (
`UserID` int(10) NOT NULL,
`ChangeTime` datetime default NULL,
`ChangerIP` varchar(15) default NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
These changes are logged, with IP & timestamp.
1. Email change
2. IP change
3. Passkey change
4. Password change
PHP Code:
$DB->query("SELECT MAX(Sequence) FROM users_history_ratio");
list($Sequence) = $DB->next_record();
$LastSequence = $Sequence;
$Sequence++;
if(!$Sequence){
$Sequence = 1;
}
$DB->query("INSERT INTO users_history_ratio(Sequence, UserID, Uploaded, Downloaded, UpChange, DownChange, Time)
SELECT '$Sequence', m.ID, m.Uploaded, m.Downloaded, (m.Uploaded - r.Uploaded), (m.Downloaded - r.Downloaded), '".sqltime()."'
FROM users_main AS m
LEFT JOIN users_history_ratio AS r ON r.UserID=m.ID AND r.Sequence='$LastSequence'");
Every day and every hour, a script dump your ratio history to database.
This is what the script log :
- UserID
- Uploaded
- Downloaded
- UpChange
- DownChange
- Time
The log is stored separately, so at day 20 a staff can still see how much you upload / download at day 5.
PHP Code:
m_cheater = false;
m_cheater_speed = 26214400;
XBTT's abnormal upload speed detection, deactivated by default.
If upload speed is greater than 25 MB/s, consider that user is cheating.
PHP Code:
// F****** btjunkie piece of s***
if(strpos($_SERVER['HTTP_REFERER'], 'btjunkie.org')) {
// This code is executed if someone is downloading a torrent from btjunkie
// Do what you want here, be creative. ;)
}
Yeah, they hate btjunkie. Don't try to download What.CD's torrent from btjunkie.
PHP Code:
log_attempt($UserID);
if ($Enabled=='2') {
$Err='Your account has been disabled.<br />This is either due to inactivity or rule violation.';
} elseif ($Enabled=='0') {
$Err="Your account has not been confirmed.<br />Please check your email.";
} else {
$Err="Your username or password was incorrect.";
}
If you're unable to log in, there're 3 reasons given :
- Your account has been disabled. This is either due to inactivity or rule violation.
- Your account has not been confirmed.
- Your username or password was incorrect.
You won't see the ban reason, although moderators usually put the reason in the Staff Notes.
PHP Code:
`BanReason` enum('0','1','2','3','4') NOT NULL default '0',
// Disabled manually by moderators / admins
BanReason=1
// If a user hasn't been taken off ratio watch in the two weeks since he was put on, banhammer
BanReason=2
AdminComment=Disabled by ratio watch system
// If a user has downloaded more than 10 gigs while on ratio watch, banhammer
BanReason=3
AdminComment=Disabled by ratio watch system for downloading more than 10 gigs on ratio watch
// Disable inactive user accounts
BanReason=3
AdminComment=Disabled for inactivity
// Disable unconfirmed users
BanReason=3
AdminComment=Disabled for inactivity (never logged in)
There're 4 different kind of ban reason.
I haven't seen the 4th reason in the source code, maybe it's either "reserved" or "disabled automatically for cheating";
PHP Code:
$DB->query("UPDATE users_info AS ui JOIN users_main AS um ON um.ID=ui.UserID
SET um.Enabled='2',
ui.BanDate='".sqltime()."',
ui.BanReason='3',
ui.AdminComment=CONCAT('".sqltime()." - Disabled for inactivity', ui.AdminComment)
WHERE um.PermissionID IN ('".USER."', '".MEMBER ."')
AND um.LastAccess<'".time_minus(60*60*24*7*10)."'
AND um.LastAccess!='0000-00-00 00:00:00'
AND ui.Donor='0'
AND um.Enabled!='2'");
Users will be disabled for inactivity if they don't login for 10 weeks (70 days).
PHP Code:
$DB->query("UPDATE users_info AS ui JOIN users_main AS um ON um.ID=ui.UserID
SET um.Enabled='2',
ui.BanDate='".sqltime()."',
ui.BanReason='3',
ui.AdminComment=CONCAT('".sqltime()." - Disabled for inactivity (never logged in)', ui.AdminComment)
WHERE um.LastAccess='0000-00-00 00:00:00'
AND ui.JoinDate<'".time_minus(60*60*24*7)."'
AND um.Enabled!='2'
");
Unconfirmed users will be disabled after 1 week (7 days)
II. Staff Account's Screenshot
Maybe you have seen lots of What.CD tracker screenshots, with user / power user permission.
It's time to see what staff account screenshots looks like.
Since we'll deal with staff more often than admin account, let's focus on staff account :
1. Staff Account's Toolbox
2a. User's Permission
2b. Power User's Permission
2c. Staff's Permission
3. IP Bans
Note : There's no expires date
4. Login Watch
5. Invite Pool
6. User Search
7. Active Reports
8. Duplicate IPs
9. User's Profile
Unlike regular user, staff have access to specific feature when they access your profile.
10. Watched users
Usually, staff have to click "Add to watchlist" to make a user account go into "Watch List".
But, I'm sure the system will add any account to "Watch List" automatically if the account meet specific suspicious condition.
Final Note :
Gazelle is open source, so developer can easily modify it to add more feature, like new feature in toolbox or anti-cheating script.
What you see here may be obsolete in a few month later.
Bookmarks