26957 total geeks with 3514 solutions
Recent challengers:
 Welcome, you are an anonymous user! [register] [login] Get a yourname@osix.net email address 

Articles

GEEK

User's box
Username:
Password:

Forgot password?
New account

Shoutbox
MaxMouse
It's Friday... That's good enough for me!
CodeX
non stop lolz here but thats soon to end thanks to uni, surely the rest of the world is going good?
stabat
how things are going guys? Here... boring...
CodeX
I must be going wrong on the password lengths then, as long as it was done on ECB
MaxMouse
lol... the key is in hex (MD5: of the string "doit" without the "'s) and is in lower case. Maybe i should have submitted this as a challenge!

Donate
Donate and help us fund new challenges
Donate!
Due Date: Jul 31
July Goal: $40.00
Gross: $0.00
Net Balance: $0.00
Left to go: $40.00
Contributors


News Feeds
The Register
Joe Average isn"t
worth $10 a year to
Mark Zuckerberg
VMware counters
containers with
SaaSy VM disk swap
Russia sends
SEX-CRAZED GECKOS
to SPAAAAACE!
Verizon to limit
unlimited 4G plans
Redmond in rapid
rebuild after
sysadmin request
STUNNER
Bring back error
correction, say
Danish "net boffins
AusCERT chief
Ingram steps down
Google outlines
research priorities
for boffin grants
Batteries take the
lithium for charge
boost
Colbert report
reveals VMware"s
AirWatch
integration plan
Slashdot
Popular Android
Apps Full of Bugs:
Researchers Blame
Recycling of Code
Newly Discovered
Virus Widespread in
Human Gut
Off the Florida
Coast, Astronauts
Train For Asteroid
Mission
Valencia Linux
School Distro Saves
36 Million Euro
A Router-Based Dev
Board That Isn"t a
Router
Satellite Images
Show Russians
Shelling Ukraine
Linus Torvalds:
"GCC 4.9.0 Seems To
Be Terminally
Broken"
SpaceX Executive
Calls For $22-25
Billion NASA Budget
Ask Slashdot: What
Would You Do With
Half a Rack of
Server Space?
Amputee Is German
Long Jump Champion
Article viewer

Changing BitComet's peer_id



Written by:sefo
Published by:sefo
Published on:2006-05-27 16:07:28
Topic:Assembly
Search OSI about Assembly.More articles by sefo.
 viewed 16146 times send this article printer friendly

Digg this!
    Rate this article :
This bittorrent client has been banned from the majority of private trackers.
It is possible to bypass the ban by spoofing the peer_id it sends.

This article is by no means a way to protest against the measures taken by those private trackers or a way to promote the use of BitComet. This article is completely disinterested and tries to demonstrates a technique of spoofing by means of modifying a program.

Tools used:

-OllyDbg
-WPE packet sniffer

Note:
WPE is detected by some AVs as a trojan but this is not the case.
http://www.symantec.com/avcenter/venc/data/hacktool.wpe.html

When you start downloading a torrent, BitComet sends a packet identifying the request and the version of the client you use.
In the case of version 0.66, the packet looks like:

0010 70 3F 69 6E 66 6F 5F 68 61 73 68 3D 25 44 31 25 p?info_hash=%D1%
0020 38 46 4A 50 25 30 35 73 31 25 42 31 25 41 46 48 8FJP%05s1%B1%AFH
0030 6A 61 66 4F 25 32 36 25 39 34 25 43 36 25 37 45 jafO%26%94%C6%7E
0040 32 25 39 37 26 70 65 65 72 5F 69 64 3D 25 32 44 2%97&peer_id=%2D
0050 42 43 30 30 36 36 25 32 44 54 25 41 34 25 30 33 BC0066%2DT%A4%03
0060 25 46 34 25 42 45 7A 5A 25 31 31 6D 25 39 44 25 %F4%BEzZ%11m%9D%
0070 32 44 25 46 39 26 70 6F 72 74 3D 39 34 34 39 26 2D%F9&port=9449&
0080 75 70 6C 6F 61 64 65 64 3D 30 26 64 6F 77 6E 6C uploaded=0&downl


At offset 0050 we can find the identifier of the client BC0066 (BitComet v0.66)
In older versions, this peer_id was directly hardcoded in the executable and it was very trivial to modify it in an hexadecimal editor. (value excb if I remember)
If you take a look at the string references in version 0.66 using OllyDbg, you can still find this value, but it might be only a way to confuse the potential 'hacker'.

Being the only way to identify the client, we need to change this peer_id to a value like UT1500 which corresponds to the UTorrent client version 1.5
A tracker would then believe you are using a UTorrent client and let you in.

Where do we start?

The hardest part in that kind of analysis is to find where to start; especially since this value is not hardcoded but generated on the fly.
In the packet we captured earlier, we had a string like "&peer_id="
Right-click anywhere on the disassembly windows and select Search for -> All referenced textstrings

In the list that pops up, right-click again and choose Search for text.
We find 2 occurences for the string "&peer_id=" at addresses 00537DA2 and 00537E54
This will be our starting point and we need to put a breakpoint on each of them.
(select the first line and press F2 then select the second line and press F2 again)

Let's start BitComet and see what happens.

Ignoring exceptions

What happens when you run BitComet in OllyDbg is that the debugger gets stuck on 3 exceptions in the library msxml3.dll
Those exceptions are not anti-debugging technics as I first thought, but are actually real exceptions/errors occurring in the program. (mostly due to a badly formatted xml file or BitComet is maybe calling the dll too many times)
When BitComet runs on its own, it just ignores those exceptions as they are not critical, but the debugger lets you know that something is happening.
What we just need to do is to tell OllyDbg to ignore these exceptions.

Each time OllyDbg signals an exception, you can go to the menu Option / Debugging options and select the Exceptions tab.
Check the checkbox "Ignore also custom exceptions" and click on the "Add last exception" (do this each time OllyDbg signals an exception - happens 3 times in our case)

The exceptions are:

C06D007F
E0000001
E06D7363


Now we can run BitComet in the debugger and start the analysis.

Debugging

When you start downloading a torrent file, it immediately breaks on one of our breakpoints we set earlier at 00537E54
The function looks like:

00537E4A CALL BitComet.005558B0
00537E4F PUSH EAX
00537E50 LEA EDX,DWORD PTR SS:[ESP+20]
00537E54 PUSH BitComet.00634D34 ; ASCII "&peer_id="
00537E59 PUSH EDX
00537E5A MOV BYTE PTR SS:[ESP+B4],0C
00537E62 CALL BitComet.00412680


The reasoning we should have now is that we need to know what's happening before and after that PUSH &peer_id=
and especially what are those 2 CALLs we have at the begining and at the end.

The logic of the second function is that it pushes 2 parameters on the stack:

  • The string "&peer_id="
  • A value in EDX (actually a pointer to a value)

    Let's take a look at the stack before the CALL.
    You can click on the lower window (called the dump window, it looks like an hexadecimal editor) to activate it and then press Ctrl+G (goto address)
    enter ESP and you will have the dump of the memory pointed by ESP.

    There's nothing much to see for the moment except a value we saw earlier in our packet: 8FJP.
    If we continue executing the program and trace over the CALL at 00537E62, you now see the value BC0066 we are looking for (see the memory dump of ESP)

    What we could do is change this value now, directly by selecting each 6 bytes and press <space> to modify it, but the change will only be temporary and can't be apply to the executable as it is only a value in memory.
    What this function actually does is to fill a buffer with the value of peer_id, but that has been already generated previously and this function is copying it from memory.

    That's where the CALL at 00537E4A comes into play.

    This function is being called at different places in the code and it might look like:

    GeneratePacket(int part_id);


    Where part_id identifies what part of the packet is to be generated. (info_hash, peer_id...etc.)
    In our case, since we are in the peer_id part, we will follow the peer_id generation code.

    The first part of the function is just setting an Exception Handler and saves some registers before use:

    005558B0 PUSH -1
    005558B2 PUSH BitComet.0060E4B1
    005558B7 MOV EAX,DWORD PTR FS:[0]
    005558BD PUSH EAX
    005558BE SUB ESP,30
    005558C1 MOV EAX,DWORD PTR DS:[6B4D94]
    005558C6 XOR EAX,ESP
    005558C8 MOV DWORD PTR SS:[ESP+2C],EAX
    005558CC PUSH EBX
    005558CD PUSH EBP
    005558CE PUSH ESI
    005558CF PUSH EDI


    Then it initialises some variables:

    005558D0 MOV EAX,DWORD PTR DS:[6B4D94]
    005558D5 XOR EAX,ESP
    ...
    005558FE MOV EAX,DWORD PTR DS:[EDI+14]
    00555901 CMP EAX,ESI
    00555903 MOV DWORD PTR SS:[ESP+4C],ESI


    And starts a loop with a number that will identify how many bytes of the peer_id it already generated:

    00555907 MOV DWORD PTR SS:[ESP+1C],1
    0055590F JBE BitComet.00555A9F ;start of the loop
    00555915 LEA EBP,DWORD PTR DS:[EDI+4]


    Then you have that very long and un-esthetic loop containing code that looks like a switch()/case with a series of comparisons and jumps:
    Those comparisons actually check the loop index to see which part of the packet is being generated and where to put it.

    0055592D CMP ESI,EAX
    0055592F MOV DWORD PTR SS:[ESP+4C],1
    00555937 JBE SHORT BitComet.0055593E
    00555939 CALL BitComet.005A5261
    0055593E CMP DWORD PTR DS:[EDI+18],10
    00555942 JB SHORT BitComet.00555949
    ...
    005559E7 CALL BitComet.005A5261
    005559EC CMP DWORD PTR DS:[EDI+18],10
    005559F0 JB SHORT BitComet.005559F7
    005559F2 MOV EAX,DWORD PTR SS:[EBP]
    005559F5 JMP SHORT BitComet.005559F9
    ...


    Then, if we're still following the dump of ESP at the same time, we notice that after the CALL at 00555A09,
    the first byte of the peer_id ("B") has been copied in memory. We continue the execution of the code, and on the second loop, the same CALL fills the memory with the second byte of the peer_id ("C").

    Now on the third loop, we trace into the call (using F7 instead of F8) and see what's happening there.
    The following steps are a bit indigest and very long. It consists in following what's happening in esp where each byte of the peer_id is copied
    and finding what function called what function by following numerous CALLs and re-running the application and breaking a bit earlier in the code...etc.

    So I'll give you directly the interesting part here:

    004D2687 CALL BitComet.0040A900 ;
    004D268C PUSH 30 ;
    004D268E PUSH 1
    004D2690 MOV ECX,ESI
    004D2692 MOV DWORD PTR SS:[ESP+74],EBX
    004D2696 MOV DWORD PTR SS:[ESP+1C],1
    004D269E CALL BitComet.0041A4F0
    004D26A3 PUSH 30 ;
    004D26A5 PUSH 1
    004D26A7 MOV ECX,ESI
    004D26A9 CALL BitComet.0041A4F0
    004D26AE PUSH 36 ;
    004D26B0 PUSH 1
    004D26B2 MOV ECX,ESI
    004D26B4 CALL BitComet.0041A4F0
    004D26B9 PUSH 36 ;
    004D26BB PUSH 1
    004D26BD MOV ECX,ESI
    004D26BF CALL BitComet.0041A4F0


    What catches the eye here is the series of PUSH 30 and PUSH 36
    Knowing that BC0066 equals 42 43 30 30 36 36 we can now safely assume that the 0066 are generated by pushing the hexadecimal values directly on the stack.
    For the moment we can change definitely the value 0066 to 1500 by selecting each of the 4 lines concerned and press <space>

    You can now tell OllyDbg to assemble:

    PUSH 31
    PUSH 35
    PUSH 30
    PUSH 30

    Now let's see how "BC" is generated from the function at 0040A900

    The function is very long, but it actually only loads the 2 bytes "BC" hardcoded in the program at address 0062E538
    Select the dump window and press Ctrl+G to go to this address and find the hardcoded value.

    You can now also change definitely the "BC" part to "UT".

    Right-click anywhere on the disassembly window and select Save to File / All modifications and you have you're new BitCometClient identified as a UTorrent client v1.5

    Note for those who read only the end of the articles:

    In the assembly window:
    1/ Go to 004D268C and change PUSH 30 to PUSH 31
    2/ Go to 004D26A3 and change PUSH 30 to PUSH 35
    3/ Go to 004D26AE and change PUSH 30 to PUSH 30
    4/ Go to 004D26B9 and change PUSH 30 to PUSH 30

    In the dump window go to 0062E538:
    5/ Change BC to UT

    Save all modifications using right-click / save to file / all modifications.

  • Did you like this article? There are hundreds more.

    Comments:
    anilg
    2006-05-27 23:12:36
    This bittorrent client has been banned from the majority of private trackers.

    And the reason they give is?
    sefo
    2006-05-28 04:54:18
    [...]many private tracker operators argue that BitComet does not honor the private flag. Instead, the torrent is shared on the DHT network and those who do not belong to the private tracker can freely leech off the resources of that community. That is the much simplified story many private trackers are telling.

    Taken from http://www.slyck.com/news.php?story=1021
    anilg
    2006-05-28 09:53:17
    With utorrent already there, beats me wh anybody would go for BC. The former has almost all features n more, and its only growing by the day
    think12
    2006-05-29 07:40:07
    Nice article sefo. It was above me, but I still enjoyed the read.

    utorrent is teh pwn.
    Anonymous
    2006-06-01 19:37:40
    (bb) well, i do find that bitcomet achieves much higher transfer rates, especially under a 'traffic shaped' connection. but utorrent is very sexy
    Fingerlessknight
    2006-06-02 21:29:41
    utorrent all the way baby :D
    Jak205
    2006-06-06 20:11:19
    bitPump by AnalogX.
    Kevan
    2006-09-04 02:38:48
    Good article sefo. I followed through with BC66. But when I applied on BC70, the "very long and un-esthetic loop" that get me lost. Probably I loose my patience.
    Anonymous
    2007-02-08 06:04:14
    Save all modifications using right-click / save to file / all modifications.

    How do I do that ?
    Anonymous
    2007-02-25 09:05:11
    right-click / save to file / all modifications = copy to executable / all modifications
    Anonymously add a comment: (or register here)
    (registration is really fast and we send you no spam)
    BB Code is enabled.
    Captcha Number:


    Blogs: (People who have posted blogs on this subject..)
    jackier
    jackier on Mon 13th Oct 10am
    111
    sefo
    Sneak - encryption on Fri 17th Nov 12pm
    I'm developing the win32 version of sneak: http://snarkles.net/scripts/sneak/sneak. php The ASM source code is available on cyberarmy svn (for members only - free) Check the forum for details: http://www.cyberarmy.net/forum/sneak/mes sages/295244.
    sefo
    Geek Toolbar on Mon 13th Nov 8am
    This a very simple and small toolbar I wrote in my spare time. I use the same set of tools very often and I find it very annoying to look for them in the start menu, on the desktop or in explorer. http://www.osix.net/modules/folder/index .php?tid=134
    sefo
    BinScan and Alternate Data Stream on Thu 27th Jul 9am
    BinScan I created this tool to quickly identify modifications in the PE, use of a TLS callback and Alternate Data Streams. -> Some modifications done in the PE structure of an executable can prevent debuggers or other tools to open the executable.
    sefo
    Wmf Creator on Wed 26th Jul 7am
    Now that the blog is online, I'll be able to share two or three tools I wrote. The first one I'd like to share is WMF Creator. I already put a link in the comments of my article: Wmf Exploit but I thought it would look nicer here. This tool will tak

    Test Yourself: (why not try testing your skill on this subject? Clicking the link will start the test.)
    Reverse Engineering by Geek_Freek

    A test to check your assembly and reversing skills.
    Assembly Language - non compiler specific by TroPe

    You can test your assembly knowledge by taking this test. It starts out relatively easy, but gets progressively hards very quickly! If you know assembly, or just want to see what you DONT know about assembly, this test is for you. A more advanced assembly


         
    Your Ad Here
     
    Copyright Open Source Institute, 2006