Team Fortress 2
This topic has been locked
TF2 Spray Handling Bugs
tl;dr: Spray handling bugs, empty servers, terrorize children and f2p nerds

I believe I will preface this post with a story. There is a convention in DC called Shmoocon that has been running a tournament called HackFortress for a few years now. They combine a hacking ctf with a game of tf2. It's really pretty interesting. I would recommend looking it up. This is right up my alley as I spend nearly all of my free time playing ctf's or tf2. I'm not really good at either but it's a hobby...

I have been trying to get tickets for a few years now but, up until this latest series of ticket sales, I tried the old-fashioned way and slapped f5 eagerly looking for the reg link and my ticket to fail. This year I was going to be prepared. I had written up a quick bot that I thought would ensure I would be able to get tickets for the con. Sadly, this year was just like every other year and I didn't get tickets (seriously guys. 2.14 seconds? I was pretty hung over but that is impressive. I would love to see some of the code you're running). All of that being said, I'm going to throw a temper tantrum like a child kicking and screaming in the super market because he didn't get what he wanted. My shortcoming will be your windfall. I have tf2 bugs for the more enterprising individuals in the tf2 universe to play with. I was hoping to use them in the tournament. I figured that the crowd would at least appreciate it. Given the stories about vendor responses in the gaming industry these might still be alive in a month when the con runs. Finding these bugs was trivial. I think most of the work would be trying to evade goons at the con and load your textures on the compo computers. That alone should be worth a free round for your team. :P

Debugging and fuzzing the game takes a long time and my interest in it is waning so I figured I'd pass my findings along. Trying to get code execution would be super leet-o but it doesn't matter that much to me in the context of trolling whole tf2 servers.

Sorry to all of the people who I used these bugs on over the weekend. I had previously kept to myself with a server on my local network but I needed to do some testing. It was a lot of fun trolling the larger clan based servers because people kept reconnecting and asking if anyone else crashed. I would paint the wall again. I wish I had saved some of the nicks so I could give a proper shout out to the more vocal individuals whose days were just absolutely ruined by my antics ...err... empirical analysis.

highResImageFormat header field

This is a generic access violation bug in materialsystem.dll. The function uses a lookup table but doesn't validate the offset that it is going to be grabbing. I know Source provides support for a lot of image formats but an unsigned dword is really ambitious. I tried to get it to do something meaningful but there's a validation function a little down the line that seems to do a good job catching things. So, dos it is then. If you set the byte at position 0x36 to something high (like 0xff) you can get the client to crash reliably. I tried to use this bug on a couple pub servers and found that nobody was crashing. My guess is that the client uses the low res image for other people's sprays and the high res for your own. There might be a way to correlate this to the lowResImageFormat field in the header or find a similar bug there. I tried a few test cases that worked with highRes but didn't find much so I just wrote it off as a local bug.

Here's the location of the crash (ecx is the same value as in the file and is used for the computation of eax):

(cc0.46c): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=06f9005b ebx=00000100 ecx=00ff000d edx=00000000 esi=00000100 edi=00000001
eip=6e7763a0 esp=0034da64 ebp=0034da6c iopl=0 nv up ei pl nz ac po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010212
materialsystem+0x463a0:
6e7763a0 8b048568b17d6e mov eax,dword ptr materialsystem!CreateInterface+0x29988 (6e7db168)[eax*4] ds:002b:8a61b2d4=????????

frames header field

This was a really interesting bug that causes crashes if you set the value of the frames field to 0x00. I can get the local client to reliably crash if I spray the normal texture, log off the server, log back in and then spray the bad vtf. Similarly, if I spray it in one server and then move to another and spray it there I can also get the local client to crash. I have had mixed results on public servers. There were a couple times when a swath of the server would leave immediately, and other times it wouldn't appear to do anything. Given that all of my friends are imaginary, I couldn't really test it in a more controlled environment and I couldn't exactly post an exit survey for all of the players whose games were cut short. As I said before, testing and debugging this is a <censors>f-ing </censors> bear and I just decided to leave this as it is. Maybe someone will find more use in it than me. This is just crash I got at the time of writing. I have seen dumps at a few different locations.

Wheee! windbg!:
(758.1820): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=ffffffff ecx=6dcde201 edx=6db63ef0 esi=6dcde41c edi=00000000
eip=6db795c8 esp=002ed7e4 ebp=002ed7e4 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010246
shaderapidx9+0x195c8:
6db795c8 844846 test byte ptr [eax+46h],cl ds:002b:00000046=??

flags header field

This is by far my favorite bug. This is the moneymaker right here, folk. If you set top two bits of offset 0x15 (ie 0xc0 and greater), there's a delightful little client crash with some stack corruption.

Tracing execution leads us here:
eax=8876086c ebx=ffffffff ecx=00000000 edx=000004a3 esi=7268e41c edi=5724a990
eip=722f028f esp=004bd8cc ebp=004bd8dc iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
d3d9!CCubeMap::GetCubeMapSurface+0x99:
722f028f c21000 ret 10h
eax=8876086c ebx=ffffffff ecx=00000000 edx=000004a3 esi=7268e41c edi=5724a990
eip=725295a9 esp=004bd8e0 ebp=004bd8dc iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
shaderapidx9+0x195a9:
72529\5a9 8b4508 mov eax,dword ptr [ebp+8] ss:002b:004bd8e4=90a92457
eax=5724a990 ebx=ffffffff ecx=00000000 edx=000004a3 esi=7268e41c edi=5724a990
eip=725295ac esp=004bd8e0 ebp=004bd8dc iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
shaderapidx9+0x195ac:
725295ac 5d pop ebp
eax=5724a990 ebx=ffffffff ecx=00000000 edx=000004a3 esi=7268e41c edi=5724a990
eip=725295ad esp=004bd8e4 ebp=7252caef iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
shaderapidx9+0x195ad:
725295ad c20400 ret 4
eax=5724a990 ebx=ffffffff ecx=00000000 edx=000004a3 esi=7268e41c edi=5724a990
eip=5724a990 esp=004bd8ec ebp=7252caef iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
5724a990 0300 add eax,dword ptr [eax] ds:002b:5724a990=03000000
(1b64.1e10): Access violation - code c0000005 (first chance)

I have tested it with different textures as well as different sizes and the results are similar. Padding the spray out to 512 KB results in an all black image. Code execution would be great but I don't feel like making 25 players all spawn calc at the same time. I played with some heap spraying to see if I could get it to execute anything with little success. I tried using the say command to fill up the console buffer but that didn't seem to work. I think I would have to log in with a bunch of my imaginary friends and have people just start spraying textures to spray the heap. More testing (and friends) would be needed for that. I'd be interested if anyone garners an exploit.

For those of you keeping score, this also crashes VTFedit. :P

"Exploitation"

Nobody wants to crash themselves while they drop these textures. Luckily, there is a way to prevent yourself from being affected and you can watch the server turn into a museum as the server waits for people to timeout. This is a really convenient mechanism. The game caches your texture in %TF2_BASE%\tf\downloads as, presumably, the CRC of the file as the file name and dat as the extension. Then, when it's time to render the spray, it copies the dat file to %TF2_BASE%\tf\materials\temp and changes the extension to vtf unless there is a file with that name already cached. You can fix the header of the vtf in temp and your client will use it in game. For example, my texture was 5f....dat so I copied it from the downloads folder and and pasted it into the temp folder, renamed it 5f....vtf. I also edited the vtf in a hex editor to fix the header to its proper value. It sounds convoluted but, if you just clear both of those folders and log into a game, you can see exactly what I'm talking about. The other clients on the server have the dat file cached. When you hit the spray you render the good texture and everyone else loads the bad. Simple as pie! Another thing to note would be that you can probably cause a collision with another texture that has a matching CRC, I'd imagine that anyone who has already been affected by my ‘testing' would crash again (hence the abbreviated filename). Remember, real men use the console. Use cl_logofile because, if you try to import it through the menu, hl2.exe will crash. You will need to set the texture every time you load tf2.

Work around

Disable sprays. I noticed that the server doesn't always clear out completely. The people that are left always provide some good lulz as they try and figure out what the <censor>heck</censor> happened. They might be running with it disabled or, maybe, one of the other os clients isn't vulnerable. These were all tested on Windows 7 64-bit (doesn't really matter because hl2.exe runs in 32-bit anyway).

Well guys, it's been fun. Hope you have as much fun as I did terrorizing the general public. I might get klined for this so it's been real. It would be great, though, if the Steam mods don't get draconian. We could probably open a positive dialog for more responsible disclosures in the future. If they don't moderate this thread out, please direct all flames to /dev/null. Any exploit code or other relevant insights would be interesting. These should also work on the other Source games that allow spraying (such as L4D or Portal iirc) but I haven't tested it. Oh golly! I hope I get a CVE for this! :)

--pleasekline

Last edited by pleasekline; Jan 9, 2013 @ 6:12am
< >
Showing 1-15 of 20 comments
templar Jan 8, 2013 @ 3:18pm 
The proper thing to do would be to report the bug to Valve, not post it on an open forum and advocate exploits, don't you think?
pleasekline Jan 8, 2013 @ 3:50pm 
I considered it and quickly dismissed it for the following reasons:

- As I said, I'm throwing a temper tantrum
- I would like to see if someone can devine something more interesting out of these bugs
- I like full disclosure
- Remote client denial of service is hilarious
- Sharing is caring

Monke Jul 19, 2014 @ 10:53am 
lol
Did not work the way with me
How did you do it you?
dalttran Aug 27, 2014 @ 8:45pm 
dafuq is this help
Scraps Aug 27, 2014 @ 8:45pm 
I usually ask for more detail in these bug threads but... Uh, -this is a first- could you perhaps give us simple folk a TL;DR?
Monke Aug 28, 2014 @ 2:40pm 
Originally posted by SPeEeD D3sS:
Did not work the way with me
How did you do it you?

Why did you necro this



؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟

I thought he could adjust the size of the image to 0 × 15 and converted to a formula VTF
Or perhaps a way similar with the addition of an error at the picture
pleasekline Sep 4, 2014 @ 7:29am 
I'm surprised about the sudden interest in this. Most of the info in this has been patched out or modified. The bug in the flags field (offset 0x15 for those of you playing at home with a hex editor) of the vtf, surprisingly, is still effective and fun.

I'm not going to get into the details here but they have changed the way tf2 caches downloaded sprays. I suggest just diffing the file system when you connect to an online game. You can find the 'downloaded' copy of your spray that way and then you can use that to pollute the cache (which is a crazy hierarchy based on the first byte of the hash name of the texture).
pleasekline add me friend

plz
Last edited by HOVERFIELD 20-42fps; Sep 27, 2014 @ 5:58am
peebles geebles May 30, 2015 @ 8:26pm 
It is back 2 normal although it does get abusive
Clifford Sep 20, 2015 @ 8:20am 
is this outdated?
peebles geebles Sep 20, 2015 @ 9:06am 
Originally posted by Clifford:
is this outdated?
LOL GG
Clifford Sep 20, 2015 @ 9:23am 
a yes or no would be fine
', id=1 Sep 20, 2015 @ 9:49am 
Originally posted by Clifford:
a yes or no would be fine
Probably yes. Nathaniel Thies reported to valve two months ago about something like that.
< >
Showing 1-15 of 20 comments
Per page: 1530 50

Date Posted: Jan 8, 2013 @ 2:50pm
Posts: 20