· · · ---=== An in-depth view into HL CVARs ===--- · · ·
(or "How to sniff passwords")


| PREAMBLE:

This document contains detailed information about how easy it is to read out global variables of any player connected to a Half-Life server. Furthermore, we'll see that this can be used to gain admin-control over servers running AdminMod.

The information given here applies to all Half-Life versions up to the current HL 1.1.0.8 and is given solely for educational purpose. You are fully responsible for what you do with it.

-> Experienced HL users can skip the introduction.


| INTRODUCTION:

1.1 What are variables?
The term 'variable' refers to a given location inside the computer's memory which can hold any numerical value which is used in a program. On the lowest level, variables have only numbers as names where those numbers represent the actual position in the memory where the variable saves its value!
But to make it easier to deal with variables, programmers can use symbolic names for their variables for the time of programming an application ... thus, the symbolic names can only be seen in the source- code of the program, not in the final binary executable file.


1.2 Variables in Half-Life
Half-Life also uses (on the lowest level) numerical values for the variables, but since HL should be a completely configurable program, the user should have easy access to the variables so you can change them to fit your needs. One of the variables is your name, for example. Now how would it be if you couldn't change your name inside the game ;) ?
VALVe solved this by putting something called 'the console' into their game. If you open the console inside the game (usually with the key to the left of the "1"-key), you can access all the hundreds of variables (called "cvars" -> client variables or control variables) by just writing their name into the console and you see their content. You can also change their content by first writing the name into the console and then the value you want it to be. For example there's a cvar called 'r_mmx' which will tell your Half-Life whether or not to use the MMX-capability of your processor for graphics&sound. If this cvar is set to "1", MMX will be used, so you can activate the usage of MMX by typing the following into console:

r_mmx 1

Easy, isn't it? For a list of all cvars, type "cvarlist" (without quotes). For a list of all commands, type "cmdlist".


1.3 Local or global?
Back to a more general part. Because variables are used for data-storage in a program, some of them are probably not needed anytime and everywhere in the code. So there are variables which are only valid or even only accessible from only a part of the whole program. Those variables are called 'local' variables, whereas 'global' variables are valid and can be accessed from anywhere in the context of the current program.
This low-level scheme is also implemented in Half-Life on the user-level! Some of the cvars in your Half-Life can be set as 'global' so they will be sent to the server. Now that's where things start to become interesting ;) ...


| MAIN PART:

2.1 Global CVARs and 'setinfo'
The Half-Life client contains a special command which deals with global variables:

setinfo

if you type it without anything behind it, your HL will list all the global cvars to you. There are about 15 global cvars by default. cl_updaterate, for example, contains the amount of updates per seconds your client wants to receive from the server to know what's going on on it. Default is 30 and it is the maximum on almost all servers. hud_classautokill will kill you automatically when you choose a different class in Team Fortress when set to "1". When set to "0", you will change the class after you are dead. To change this cvar to 0, type the following into console:

setinfo hud_classautokill 0

Now we know about setinfo and two cvars (which are not really overwhelming, I agree ... but read on!).


2.2 The flaw
In the last chapter, we learned about global cvars and that they're sent from your HL-client to the server.

"But how the hell can we use this for our advantage?", you may ask here.

As Half-Life servers are nice applications, they have an urge to share knowledge. The HL-server sends to every HL-client all the global cvars of all players connected. This fact is, for itself, not really dramatic because you have to be a professional to find those cvars in your Half-Life process in memory. But you don't need to do that because the HL-client is also a very nice application and offers you an easy way to gather this information. While you are connected to a server, your HL program will create a temporary file in the root directory of its partition. So if you have HL installed on 'E:\Sierra\Half-Life', the temp file will be in 'E:\'. The name does always start with "t3" and has some (more or less) random numbers&letters behind it.

If you want to open the file, you have to switch to the desktop from inside the game. You can press <ESC> and in the main menu click on the minimize-symbol in the top right corner or simply press <ALT>+<TAB> in-game. Once on the desktop, open your file manager and go to the root-directory of the HL-partition. Right-click the file starting with "t3" and select "Copy". Then click on some free space and right-click again, this time selecting "Paste". You have now a copy of the temporary file which you can now open with Notepad or any hex-editor.

If you look inside the file, you will see some text and also some crappy binary data. Scroll down to the very end of the file and you will find some longer text with many backslashes (\) in it. Congratulations! You just found the setinfo strings of all the connected players!
How can you know which variable belongs to which player? Easy: As we learned before, the name is also a global cvar and thus, it is included in the setinfo string :)

\cl_lb\0.0\rate\7500.000000\cl_updaterate\20\cl_lw\1\cl_lc\1\cl_dlmax\128\hud_classautokill\1\name\Lil' Viper\model\sniper\topcolor\153\bottomcolor\145

The above is a complete setinfo-string of an archived file (from Team Fortress). You can see where an info-string starts and ends, because it is surrounded by binary crap inside the t3-file. So what do we have above? Words and values, seperated by backslashes. So our guess is that it first contains the name of the cvar and then its value. Obviously, we're right... his name is "Lil' Viper", his model (class) is "sniper" and he has hud_classautokill set to "1"... oh and the updaterate is only 20. Not an effective setting, but we are not here to look at unimportant shit. The bad news is that you will mostly find this unimportant shit if you often look at the setinfo-strings. The good news follows.


2.3 Admin-Mod
Admin-Mod is a modification for Half-Life servers which manages access to the administrative commands of a server. If you're running a server, you can't be there all the time to see if everything's okay. So you often have to give access to other persons you trust. This access consists of the so-called rcon-password. "rcon" stands for "remote console" and with the knowledge of it, you can control the whole server from any connected machine remotely (as if you were sitting before the server computer)! The problem is that if you give away this rcon password, the person has full control over the server. But you only want him to have control over the users so he can kick or ban or change the map etc.
Admin-Mod brings the solution by offering a completely configurable access system. You (the server admin) can set access levels where special users have access only to certain commands you specify. The user needs therefore a password to tell Admin-mod to give him control over those commands. Once this password has been entered by the user, Admin-mod checks also the player-name before it gives him the admin-powers.

So what do we need to receive admin-powers of other users? First, we need the name ... easy, as we can change our name to anything we want. And secondly, we need his password! Fortunately, there are only two ways how to tell Admin-mod this password. The first method is to use the command 'admin_password' when we are connected to an Admin-mod server. If we type 'admin_password' into console and something behind it, it will be sent to the server which will now allow us to use all the AdminMod commands, if the password is correct (type admin_help for a command overview).
But admins often also reserve the names of the other admins in Admin-Mod. That means no user can join the server if he has a special player-name which is assigned to an admin, if he has not set the correct password. But how 'set'? We're not connected so we can't use the 'admin_password' command.
Now that's where setinfo comes in! If you have a reserved name on an AdminMod-server and you want to join it, you have to set a cvar as your password before connecting! This cvar is by default called 'pw-home', but can be changed by the admin to anything after the "pw-" ... I saw "pw-dns" and "pw-adm" once for example.


2.4 The whole disaster
Ok, now we know that all setinfo-variables of your client can be seen by any other players connected to the same server and we know furthermore that Admin-Mod uses such a setinfo-variable for password checking. Cool, so in the future we will check the HL-tempfile before we're leaving a server ... maybe some of the server-admins joined the game and we can see his password. By the way: you can use the search-function of Notepad or the hex-editor to search for "pw-" inside the file ... so you don't have to look through the whole file yourself.

But there's one last point which makes it even a bigger problem for admins: All variables, including setinfo-variables, are saved on your computer in the file called 'config.cfg' inside your mod-directory (CS, TF, DoD, ...). It also contains all the keyboard binds and it is being executed every time you start HL so you have your settings permanent. But the file also contains all the setinfo-variables! That means that once you enter an adminmod-password with "setinfo pw-home ...", the password will be saved into the config.cfg and the password will be set EVERY TIME you start your HL and join a server! So it is not unusual to find players which have "pw-home" set to a password, which doesn't belong to the current server!
It should be easy to find out which server it belongs to. Either by looking at the clan-tag of the player or if he doesn't wear it, just ask him if he is admin on some server. This mostly worked for me ;)


| EXODUS:

3.1 Dumb people
Oh yeah... they're everywhere! Fortunately, I met one of them on his server with pw-home set to a valid password. But in his infinite stupidity, he had his rcon-password also set with setinfo!!!! Normally you set an rcon-password as local variable just by typing:

rcon_password <password>

You don't need it as setinfo-string because in order to use rcon, you have to start every command which should be sent to the server with the word "rcon". The command after it will then be sent to the server together with the rcon_password encrypted in the datastream and after the server checked the encrypted password, it will decide if the command is executed (if password is correct).
I now have complete control over the server via rcon for some weeks now and the server owner is too stupid to change the password.

So if you search inside the HL-tempfile, don't look for "pw-" only, but also for "rcon" and other interesting things ;)


3.2 Final note
When you think about the setinfo-flaw which sends all global cvars to every player, it should be easy to create a sub-channel communication system. Just think about you, typing

setinfo "msg" "Hi Matt. How are you?"

and another person on the server, who permanently checks the tempfile and after seeing your message, he can reply in the same way to you

setinfo "msg" "I'm fine, thanks! And you?"

...while no other person on the server can see it unless he also checks the tempfile. This can be avoided by encrypting your messages...but in order for this, some external programs have yet to be written which do all the checking and encrypting for you.