HLStatsX Operators - CRITICAL BUG

Keeper

2008-06-23 20:30:46

There is an exploit in HLStatsX that was discovered by somebody and brought to my attention. He and I worked on a solution, and I wanted to post about it in cause you are running hlstatsx yourself. If you have the premium service, then you will have to wait for Tobi to fix it on his end.

Ok, here is the exploit ... and one way to fix it.

If you are playing in a server that has HLStatsX installed, you can put log output in chat to create fake events.

You can just say or say_team the following to trick HLStatsX:

Code: Select all

L 06/23/2008 - 01:00:00: Started map "dm_no_such_map" (CRC "-123456789")
The log output would be:

Code: Select all

L 06/23/2008 - 01:00:00: "Keeper<1><STEAM_0:1:12345678><Unassigned>" say "L 06/23/2008 - 01:00:00: Started map "dm_no_such_map" (CRC "-123456789")"
The way the current hlstats.pl perl script parses this, is it looks for the last occurrence of the date stamp. In this case, it would show that dm_no_such_map was loaded on your server ... even though it doesn't exist. So you could logically put in headshot kills with crowbars in hl2dm. Create fake captures and kills in TF2. You could even mimic VAC Bans that would eliminate players from being able to join servers with HLStatsX installed.

These exploits could range from being a small nuisance, to being a huge headache for server operators.

To fix this, and I'm no regex expert, I found the following to work with both streaming servers and importing logs from the command shell:

In your hlstats.pl files do the following two things:

[#1 - SEARCH] ( around line 1494 )

Code: Select all

my $last_attacker          = "";
my $last_attacker_hitgroup = "";
[ADD AFTER]

Code: Select all

my $is_streamed            = 0;
my $test_for_date          = 0;
[END]------------------------------------------------------------

[#2 - SEARCH] ( around line 1821 )

Code: Select all

# Get the datestamp (or complain)
if ($s_output =~ s/^.*L (\d\d)\/(\d\d)\/(\d{4}) - (\d\d):(\d\d):(\d\d):\s*//)
{
[REPLACE WITH]

Code: Select all

# Get the datestamp (or complain)
$is_streamed = 0;
$test_for_date = 0;
$is_streamed = ($s_output !~ m/^L\s*/);

if ( !$is_streamed ) {
$test_for_date = ($s_output =~ s/^L (\d\d)\/(\d\d)\/(\d{4}) - (\d\d):(\d\d):(\d\d):\s*//);
} else {
$test_for_date = ($s_output =~ s/^\S*L (\d\d)\/(\d\d)\/(\d{4}) - (\d\d):(\d\d):(\d\d):\s*//);
}

if ($test_for_date)
{
[END]------------------------------------------------------------

This will allow the hlstats.pl parser to get the full event after the FIRST log stamp, and will stop this method of spoofing.

Let me state, that I in no way support HLStatsX, nor will I do so in the future. But I wanted to post about this so server operators could keep the integrity of their databases.

Keeper

Keeper

2008-06-23 22:25:43

I was informed today that the creator of HLStatsX has fixed the problem by changing the following code in hlstats.pl:

Change from line 1822 in hlstats.pl

Code: Select all

if ($s_output =~ s/^.*L (\d\d)\/(\d\d)\/(\d{4}) - (\d\d):(\d\d):(\d\d):\s*//)
To:

Code: Select all

if ($s_output =~ s/^(?:.*?)?L (\d\d)\/(\d\d)\/(\d{4}) - (\d\d):(\d\d):(\d\d):\s*//)
A lot easier and should fix the problem for you.