ZenHAX

Free Game Research Forum | Official QuickBMS support | twitter @zenhax | SSL HTTPS://zenhax.com
It is currently Tue Oct 17, 2017 1:14 pm

All times are UTC




Post new topic  Reply to topic  [ 44 posts ]  Go to page 1 2 3 Next
Author Message
PostPosted: Tue Aug 19, 2014 12:14 pm 
Site Admin
User avatar

Joined: Wed Jul 30, 2014 9:32 pm
Posts: 6852
Yesterday I checked the possibility of (ab)using the Steamworks P2P API to retrieve the IP addresses of the other Steam users.
And with IP addresses I mean both the LAN and Internet interfaces available on his system.

Technically the P2P API works in the following way:
  • user A uses SendP2PPacket to user B
  • a callback on user B tells him that user A wants to send packets
  • user B can ignore it, or use AcceptP2PPacketsFromUser or another SendP2PPacket to accept it
  • at this point the NAT traversal mechanism allows the users to send and receive packets
In all the games there are no alerts telling that an user is trying to send you packets so this is usually all anonymous.

What's interesting instead is that some games have the third point (accepting the packets) as an automatic operation even if you are not hosting a lobby/server and you are just a normal player.
One of these games is DOTA 2 (appID 570), in fact it's enough to load the game and after the loading screen the game is able to receive the packets and the IP address can be retrieved easily.

The target can be any user, not only your friends.

I have just released a tool to test this simple mechanism, steamuserip:
http://aluigi.org/papers.htm#steamuserip

Using it is very simple:
Code:
steamuserip 570 7656119**********
Where the second number is the SteamID64 of the target, it can be also in the STEAM_0: format.
The ID is available in the URL of the Steam profile of the user or, if it's a custom URL, it's enough to add /?xml=1:
Code:
http://steamcommunity.com/profiles/7656119**********
http://steamcommunity.com/id/TARGET_NICKNAME/?xml=1
Code:
<profile>
<steamID64>7656119**********</steamID64>
<steamID>*******</steamID>
<onlineState>online</onlineState>


The tool is also able to scan the whole online lobbies if you specify the steamID 0 (or ""), with some games you may be able to retrieve also the IP address of the other users in the lobby, not just the hoster/owner of the lobby.

Additional information are available at runtime, I copy&paste them here as reference:
Code:
steamuserip 0.1
by Luigi Auriemma
e-mail: me@aluigi.org
web:    aluigi.org


Usage: steamuserip <appID> <steamID/64/"">

  If the steamID is 0 or "", the tool will get the online lobbies, join them
  and scan all the users currently in them (in some games it may work).

  The user must be online and playing with the same game of appID.

  If you get only a LAN IP address, retry again.
  You may get also the Steam relay servers like 146.66.15*.*
  Other Steam servers may be 208.78.16*.*
  If you get only LAN and relay IP address, retry again.

  Remember that the results are game depend, this is not an universal solution.
  This tool is only a proof-of-concept, it may be updated in future.


Please note that may exist other better ways to retrieve the IP addresses of non-friend Steam users, this is just a proof-of-concept based on the Steamworks API.


Top
   
PostPosted: Tue Aug 19, 2014 3:53 pm 
Site Admin
User avatar

Joined: Wed Jul 30, 2014 9:32 pm
Posts: 6852
Exists a quicker way to retrieve those IP addresses avoiding to wait some seconds from the GetP2PSessionState API and moreover limiting the risk of having some IP addresses missing from the list.

When the other user accepts the connection, Steam sends a k_EMsgClientP2PConnectionInfo message to both the users in which are contained the IP addresses of each other.
The content is something like the following:
Code:
valvep2p
udp
IP address
NAT traversal token 1
NAT traversal token 2
stun
and this is the same for all the interfaces of the other user.

The problem is that I have not seen an API or another way that allows to read this information easily, so the only solution at the moment is using NetHook2.

That project aims to decrypt all the Steam packets and dumping all the low level data sent and received from the Steam server.
It's incredibly useful for debugging purpose but also to verify if everything is working as expected (for example that the IP addresses are shared after having accepted the connection and not before, design issues are ever possible).

So it's enough to go in the folder of its dumps and using the *in*clientp2pconnectioninfo* filter to get all the packets containing the users IP addresses.

The structure is very simple, the SteamID64 of the target at offset 0x23 and the IP address usually at offset 0x3d:
Code:
3a 15 00 80 11 00 00 00 2a 2a 2a 2a 2a 2a 2a 2a   :.......********
2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a   ****************
2a 2a 2a 53 54 45 41 4d 5f 49 44 2a 2a 2a 2a 2a   ***STEAM_ID*****
76 61 6c 76 65 70 32 70 00 75 64 70 00 31 31 31   valvep2p.udp.111
2e 32 32 32 2e 33 33 33 2e 34 34 34 00 2a 2a 2a   .222.333.444.***
2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a   ****************
2a 2a 00 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a   **.*************
2a 2a 2a 00 73 74 75 6e 00 30 00 00 00 00 00 00   ***.stun.0......


Testing NetHook2 is quite simple, you need to have Visual Studio installed, then you must get the headers of zlib and Google protobuf and putting them inside the folder before building the project.
Basically in NetHook2\NetHook2 you must have the folders "Debug", "steam", "google" (containing all the protobuf folder with sourcecode) and "zlib" (containing only zconf.h and zlib.h).

When Steam is running inject the NetHook2.dll library in the Steam.exe process (RemoteDll is a simple injector).
A console window will popup showing some debug information and the name of the files while they are dumped.

Go in the Steam folder (c:\Program Files (x86)\Steam) and you should see a new folder called nethook containing another folder composed just by numbers.
That's where are located all the dumped packets.


Top
   
PostPosted: Tue Aug 19, 2014 4:15 pm 
Site Admin
User avatar

Joined: Wed Jul 30, 2014 9:32 pm
Posts: 6852
Simple quickbms script to parse the dumped clientp2pconnectioninfo packets
Code:
get NAME basename
if NAME & "_in_"
    get TYPE byte
    if TYPE == 0x3a
        goto 0x23
        get STEAMID2 long
        get STEAMID1 long
        string STEAMID p= "%I64u%c" STEAMID2 STEAMID1 0 # 32->64 workaround
        string STEAMID >>= 1
        goto 0x30
        get VALVEP2P string
        get PROTOCOL string
        get IP string
        print "%STEAMID% %IP%"
    endif
endif
You can launch it against the whole folder redirecting the output in a new text file:
Code:
quickbms script.bms "C:\Program Files (x86)\Steam\nethook\NUMBER" > list.txt


Top
   
PostPosted: Wed Aug 20, 2014 1:53 am 
User avatar

Joined: Thu Aug 07, 2014 9:43 pm
Posts: 51
aluigi wrote:
I have just released a tool to test this simple mechanism, steamuserip:
http://aluigi.org/papers.htm#steamuserip

Wow. It's work! Thanks =)
P.S. Not all users determined by their IP.

_________________
-= GP-team =-
https://twitter.com/Haoose


Top
   
PostPosted: Wed Aug 20, 2014 10:40 am 
Site Admin
User avatar

Joined: Wed Jul 30, 2014 9:32 pm
Posts: 6852
I have seen that in some rare cases the users have only the LAN IP.
With others you get no IP even after retrying multiple times and they are in-game.
The alternative is the NetHook2 method but it's not so easy and immediate and I don't know how risky (VAC) is dll injection on Steam process, but being DOTA2 free you can just create a new account for these things.
But also with the NetHook2 method the only advantage is regarding the time necessary to get the list and the the results being available immediately without the need of retrying if they are partial.
So, in any case, this method will not give more IP than what you will get with the GetP2PSessionState method (the one used in steamuserip to read the IP).


Top
   
PostPosted: Sun Aug 24, 2014 12:09 am 

Joined: Sat Aug 23, 2014 10:39 pm
Posts: 2
Does it work for games like counter strike (source), where server is hosted by arbitrary hosting company?
I don't think this kind of games have lobby, or maybe there is one (when u click in-game view all players on the server and u get their steams).


Top
   
PostPosted: Sun Aug 24, 2014 7:51 am 
Site Admin
User avatar

Joined: Wed Jul 30, 2014 9:32 pm
Posts: 6852
From my tests the Counter-Strike series (1, Source and GO) do not seem affected.

A game is vulnerable when it uses the Steam Networking API and it uses AcceptP2PPacketsFromUser with ANY incoming packet, so it's not directly related to the lobbies system.


Top
   
PostPosted: Thu Sep 04, 2014 6:22 am 
User avatar

Joined: Fri Aug 08, 2014 12:51 am
Posts: 17
technically you could just DDOS someone on the other team?

_________________
Devblog


Top
   
PostPosted: Fri Sep 05, 2014 3:05 pm 
Site Admin
User avatar

Joined: Wed Jul 30, 2014 9:32 pm
Posts: 6852
@cra0
That's usually what people try to do when they get the IP address of another player, as stated in many posts on reddit regarding getting the IP using the Steam voip API (but you will not get the IP of the enemy, only the team-mates).


Top
   
PostPosted: Sun Jan 25, 2015 5:53 pm 

Joined: Sun Jan 25, 2015 5:52 pm
Posts: 6
Api loaded no... Help please.


Top
   
PostPosted: Sun Jan 25, 2015 7:10 pm 
Site Admin
User avatar

Joined: Wed Jul 30, 2014 9:32 pm
Posts: 6852
You must have Steam running.


Top
   
PostPosted: Sun Jan 25, 2015 7:38 pm 

Joined: Sun Jan 25, 2015 5:52 pm
Posts: 6
Is this steam_api.dll for 32 or 64 bit system? I have x64 win 7 and i cant run regsvr32 steam_api.dll


Top
   
PostPosted: Sun Jan 25, 2015 7:52 pm 
Site Admin
User avatar

Joined: Wed Jul 30, 2014 9:32 pm
Posts: 6852
You don't need to register the dll.
Steam is 32bit only just like the dll (that is the official one from Steam SDK) and the tool.


Top
   
PostPosted: Sun Jan 25, 2015 8:05 pm 

Joined: Sun Jan 25, 2015 5:52 pm
Posts: 6
C:\Users\Кельтир\Desktop\steamuserip\steamuserip>rem tasklist > .\tl.log

C:\Users\Кельтир\Desktop\steamuserip\steamuserip>rem .\tl.log

C:\Users\Кельтир\Desktop\steamuserip\steamuserip>rem pause

C:\Users\Кельтир\Desktop\steamuserip\steamuserip>steamuserip.exe 570 76561198161
663957""

steamuserip 0.1
by Luigi Auriemma
e-mail: me@aluigi.org
web: aluigi.org

Setting breakpad minidump AppID = 570
Steam_SetMinidumpSteamID: Caching Steam ID: 76561198161663957 [API loaded no]
Your ID 76561198161663957 - 201398229 1 1 1
Your Name ╨е╨╕╤В╤А╤Л╨╣╨е╤Г╨╣

### GAME 570 - dota 2 beta ###

- done


Top
   
PostPosted: Sun Jan 25, 2015 8:12 pm 
Site Admin
User avatar

Joined: Wed Jul 30, 2014 9:32 pm
Posts: 6852
Ah, no it's not an error :)
In case of error the tool displays an "Error" message.

In your case it's simply not possible to retrieve the information of that user, maybe because he is not online or p2p doesn't work with him.

Here you can see an example made by Haoose where you can clearly notice the "no api loaded" text which is not related to the success of the tool, in fact he got the remote IP address:
http://games-gen.mcdir.ru/forum/viewtop ... f=13&t=726


Top
   
PostPosted: Sun Jan 25, 2015 8:19 pm 

Joined: Sun Jan 25, 2015 5:52 pm
Posts: 6
.


Top
   
PostPosted: Thu Mar 05, 2015 2:48 pm 

Joined: Sun Jan 25, 2015 5:52 pm
Posts: 6
Steamuserip fixed.


Top
   
PostPosted: Thu Mar 05, 2015 5:34 pm 
Site Admin
User avatar

Joined: Wed Jul 30, 2014 9:32 pm
Posts: 6852
Currently I have a timeout error, do you refer to this error?
Do you have any confirmation about this "fix"?

Being a feature of the Steam framework, it cannot be fixed.


Top
   
PostPosted: Thu Mar 05, 2015 6:54 pm 

Joined: Sun Jan 25, 2015 5:52 pm
Posts: 6
aluigi wrote:
Currently I have a timeout error, do you refer to this error?
Do you have any confirmation about this "fix"?

Being a feature of the Steam framework, it cannot be fixed.


I have the same error.
I dont have any official confirmation...But after update this method does not work.


Top
   
PostPosted: Thu Mar 05, 2015 7:48 pm 
Site Admin
User avatar

Joined: Wed Jul 30, 2014 9:32 pm
Posts: 6852
The structure filled by GetP2PSessionState has m_bConnecting set to 1 so, apparently, it's still trying to make the connection but after 10 seconds m_eP2PSessionError becomes 4 (an error not available in the EP2PSend enum).

I made some quick tests but at the moment I found no easy solution.
GetP2PSessionState is a debugging feature so it's possible that it has been limited.


Top
   
Display posts from previous:  Sort by  
Post new topic  Reply to topic  [ 44 posts ]  Go to page 1 2 3 Next

All times are UTC


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
cron
Powered by phpBB® Forum Software © phpBB Limited