[Perl][3.1.1] Introducing Perl / Reading SRP6 session key menu

User Tag List

Results 1 to 13 of 13
  1. #1
    Jotunskjoldr's Avatar Member
    Reputation
    3
    Join Date
    Apr 2009
    Posts
    7
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [Perl][3.1.1] Introducing Perl / Reading SRP6 session key

    Greetings folks!

    Well, I haven't been part of this community for long, I just got in because the idea struck me, 4 years from launch, that it would be cool to have a proxy handling the WoW client-server communication and do various funky things with it (immediate application is to provide an IRC interface to chat, longer term goal is to build various bots). Turns out this was relatively easy until recently (namely patch 3.1), but now your best bet to do this is to actually go on the client and snatch the SRP6 authentication key from the client's memory.

    Meanwhile I was crawling the server emu boards for info on packets, and that's how little by little I've discovered the various hacking communities like this one.

    The first thing I've noticed is that everyone uses predominantly C/++, which is something I've left behind years ago (it feels awfully sluggish compared to the freedom of scripting languages). I can understand the reasons, C has the reputation of being a very memory-, hacking-oriented language, and scripting languages are not exactly natives to the Windows platform.

    However, let me show you something that I believe will convince you Perl is just as suitable for WoW hacking as C/++, if not even more!
    Code:
    use strict;
    use warnings;
    
    use Win32::Process::Info;
    use Win32::Process::Memory;
    
    my $proc = Win32::Process::Memory->new({ name=>'Wow.exe' });
    
    my $K_addr = $proc->get_u32(0x01132F74) + 0x508;
    my $K_len = $proc->get_buf($K_addr, 40, my $K);
    die "Couldn't read from memory location ".sprintf('0x%08X', $K_addr)."!\n" if !$K_len;
    
    my @K = split //, $K; # split the string buffer into a byte array
    printf('0x%02X ', ord($_)) foreach @K; # $_ will take the value of each element of @K in turn
    print "\n";
    This short code will attach to the WoW process and read the SRP6 key from its memory (kudos to kynox for providing the address in another thread on this forum). To write in memory you can use $proc->set_buf() or set_u8(), _u16() and so on. You can find the complete documentation at Win32::Process::Memory - read and write memory of other windows process - search.cpan.org


    Hth making your hacking experience easier and more enjoyable

    PS. It's trivial to get Perl running on Windows, despite what you might have heard about messing with Cygwin and such. Have a look at ActivePerl (they even have a graphical package manager to install packages such as Win32::Process::Memory).

    [Perl][3.1.1] Introducing Perl / Reading SRP6 session key
  2. #2
    Cypher's Avatar Kynox's Sister's Pimp
    Reputation
    1356
    Join Date
    Apr 2006
    Posts
    5,368
    Thanks G/R
    0/4
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The reason C and C++ are used is because they are the easiest to get running in the context of a remote process (due to DLL injection).

    Something which you cannot do with Perl (afaik).

  3. #3
    BoogieManTM's Avatar Active Member
    Reputation
    52
    Join Date
    May 2008
    Posts
    193
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Pretty neat. perl was my first language I learned, and I still use it on a daily basis for automation tasks in my job (systems engineer/administration).

    One thing to note, however, is the 40 byte "K" isn't directly used for anything anymore. It's more of a seed these days. Packet header encryption key generation uses it, as well as warden's communication, but again - not directly.

    Still pretty neat, never knew about that module. thanks for the share.

  4. #4
    Jotunskjoldr's Avatar Member
    Reputation
    3
    Join Date
    Apr 2009
    Posts
    7
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Cypher View Post
    The reason C and C++ are used is because they are the easiest to get running in the context of a remote process (due to DLL injection).
    Hmmm, that is a good point, it falls pretty far outside what I want to do so I didn't even think of that, but you're right it would be pretty hard to do in Perl.

    There is however a module which theoretically allows you to output your Perl as equivalent C code, which supposedly you could recompile as a DLL. But those "theoretically" and "supposedly" are pretty huge... In any case, this is the module: B::C - Perl compiler's C backend - search.cpan.org


    From what I gather, though, bots nowadays try to steer away from injection due to it being less and less safe. True? (I'm actually only basing this on Zulu taking pride in its lack of injection).
    Last edited by Jotunskjoldr; 05-08-2009 at 02:33 AM.

  5. #5
    Cypher's Avatar Kynox's Sister's Pimp
    Reputation
    1356
    Join Date
    Apr 2006
    Posts
    5,368
    Thanks G/R
    0/4
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Partial truth. Although its harder to secure an injected public bot than to secure a public non-injected bot, in the private scene injection is usually the way to go (unless you're super paranoid about inline stack traces or warden adding thread context checks). Whilst it would be easier to generically detect injected bots, Blizzard seem more interested in targeted attacks, that's the only reason I see for them not doing full hashes of read-only memory and instead sticking to targeted parts.

    The danger really comes when you do one of two things:
    1. Modify memory
    2. Call engine functions

    Both of which you can secure fairly well if you stay private (and even if you're public and you know what you're doing, look at ISXWarden, it gave Warden a really hard time to find it).

    But then again, once you're public its not that hard to find non-injected bots if they're not using a shadow driver or something like that.

  6. #6
    amadmonk's Avatar Active Member
    Reputation
    124
    Join Date
    Apr 2008
    Posts
    772
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Perl (and other scripting languages) rock for out-of-process work. If you can get away with scripting/VM languages, I'd highly recommend them over C/C++. In-process, I would avoid anything but C/C++. It's certainly technically possible (although it can be complex) to inject a full VM/interpreter into another process -- I have injected Perl, .Net, LUA, and other weird things into remote processes, but it's not a trivial task. Perl is especially thorny since its C interface is (or at least was, the last time I looked) especially hard to build against and rife with memory leaks and reentrancy problems. My work injecting a Perl interpreter into the old EQ was a nightmare that really led me to love LUA...

    Still, since I'm overly paranoid, I wouldn't inject a scripting language into WoW since it would increase your detectability profile significantly. I'd use a tiny bit of injected code that opened a socket or named pipe or something to talk to a true out-of-process controller and just have a few dedicated functions (DX frame hook, read memory, write memory, maybe an object list walker). The controller you could write in whatever you want. I think that that would be the best non-native solution to a group bot controller. If you used sockets, you could even run your group controller off-box; I was doing some thumbnail calculations about how much traffic would be required to send the full local radar scan via a socket 2-3 times per second and it's not too bad, even with a full group and decent refresh rates.

    But yeah, Perl is fun. Back in my EQ reversing days I used to hang out (in IRC) with a guy who had a pretty full-featured group bot working all in Perl using packet captures and simulated input. Kinda cool. These days, since I'm ramping up on Python for work, I'd probably use that, but it's kinda just a matter of preference, really.

  7. #7
    Jotunskjoldr's Avatar Member
    Reputation
    3
    Join Date
    Apr 2009
    Posts
    7
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by amadmonk View Post
    It's certainly technically possible (although it can be complex) to inject a full VM/interpreter into another process -- I have injected Perl, .Net, LUA, and other weird things into remote processes, but it's not a trivial task. Perl is especially thorny since its C interface is (or at least was, the last time I looked) especially hard to build against and rife with memory leaks and reentrancy problems. My work injecting a Perl interpreter into the old EQ was a nightmare that really led me to love LUA...
    Haha, nice, I didn't even fathom it would be feasible to inject the entire interpreter, but come to think of it yeah, why not? I still think though it would be easier to try and translate the Perl to C and then compile it to DLLs.

    Originally Posted by amadmonk View Post
    I'd use a tiny bit of injected code that opened a socket or named pipe or something to talk to a true out-of-process controller and just have a few dedicated functions (DX frame hook, read memory, write memory, maybe an object list walker). The controller you could write in whatever you want. I think that that would be the best non-native solution to a group bot controller.
    Funny you should say that, I think that's exactly what Win32::Monitoring:LLInject - Injects Win32 programs with overloaded functions - search.cpan.org is trying to do (check their website for the code to the DLL).

  8. #8
    Jotunskjoldr's Avatar Member
    Reputation
    3
    Join Date
    Apr 2009
    Posts
    7
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by BoogieManTM View Post
    One thing to note, however, is the 40 byte "K" isn't directly used for anything anymore. It's more of a seed these days. Packet header encryption key generation uses it, as well as warden's communication, but again - not directly.
    Well, not directly K as such, but I still need it to generate the other keys. Packet header encryption is really just mangling it a little, nothing serious. I s'pose I could go grab the RC4 key from memory, but we already have K and I know the algorithm to mangle it, so whatever :P


    Maybe if kynox is kind enough to find it for us?

  9. #9
    kynox's Avatar Account not activated by Email
    Reputation
    830
    Join Date
    Dec 2006
    Posts
    888
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Jotunskjoldr View Post
    Well, not directly K as such, but I still need it to generate the other keys. Packet header encryption is really just mangling it a little, nothing serious. I s'pose I could go grab the RC4 key from memory, but we already have K and I know the algorithm to mangle it, so whatever :P


    Maybe if kynox is kind enough to find it for us?
    You want the memory offset of the RC4 key? Seriously, mangling it is too hard?

    You're lucky i'm bored. I'll look soon.

    *edit*:The RC4 context's are listed below:
    NetClient = [0x01132F74]
    WoWConnection = [NetClient+0x2B94]
    DecryptionRC4Context = WoWConnection + 0x24A
    EncryptionRC4Context = WoWConnection + 0x148
    Last edited by kynox; 05-10-2009 at 07:12 AM.

  10. #10
    UnknOwned's Avatar Legendary
    Reputation
    713
    Join Date
    Nov 2006
    Posts
    583
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by kynox View Post
    You want the memory offset of the RC4 key? Seriously, mangling it is too hard?

    You're lucky i'm bored. I'll look soon.


    *edit*:The RC4 context's are listed below:
    NetClient = [0x01132F74]
    WoWConnection = [NetClient+0x2B94]
    DecryptionRC4Context = WoWConnection + 0x24A
    EncryptionRC4Context = WoWConnection + 0x148
    That is like winning in the lottery!

  11. #11
    Jotunskjoldr's Avatar Member
    Reputation
    3
    Join Date
    Apr 2009
    Posts
    7
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by UnknOwned View Post
    That is like winning in the lottery!
    Word!! Much thanks kynox! Hehe, I actually finished the mangling yesterday before going to bed (well, this morning at 6AM really), but I'm thinking grabbing the RC4 key directly would be more robust if they ever change the mangling.

    I guess I might as well post it here for reference, if you really need this and can't Perl, drop me a line. (None of these functions are custom, btw, it's all in available Perl packages).
    Code:
    use Digest::SHA1 qw(sha1);
    use OpenSSL::Cipher qw(new_encrypt);
    
    package Golemmo::WoW::Cipher;
    
    sub spawn {
        my $class = shift;
        return bless {
            seed_key    => 0,
            session_key => 0,
            cipher_key  => 0,
            cipher      => 0,
        }, $class;
    }
    
    sub init {
        my ($self, $seed_key, $session_key) = @_;
        $self->{seed_key} = my $SDK = $seed_key;
        $self->{session_key} = my $SSK = $session_key;
    
        # compute the actual RC4 based on the session key (received from Golemmo::WoW::Espionage)
        my @b1; $b1[$_] = 0x36 for (0 .. 63);
        my @b2; $b2[$_] = 0x5C for (0 .. 63);
        my @SDK = split //, $SDK;
    
        for (0 .. $#SDK) {
            $b1[$_] ^= $SDK[$_];
            $b2[$_] ^= $SDK[$_];
        }
    
        my $CIK = sha1( join('', @b1), $SSK );
        $CIK = sha1 ( join('', @b2), $CIK );
    
        $self->{cipher_key} = $CIK;
    
        # build the cipher
        $self->{cipher} = new_encrypt('rc4', $CIK);
    
        # discard the first 1024 bytes of the keystream
        my $a = ""; $a .= chr(0) until length($a)==1024;
        $self->{cipher}->update($a);
    }
    Note: you'll need two ciphers, one for encryption and one for decryption. You'll notice the seed key above, it's different for these two ciphers. From Aspire Hearthstone:
    Code:
    uint8 ServerEncryptionKey[SeedKeyLen] = { 0x22, 0xBE, 0xE5, 0xCF, 0xBB, 0x07, 0x64, 0xD9, 0x00, 0x45, 0x1B, 0xD0, 0x24, 0xB8, 0xD5, 0x45 };
    uint8 ServerDecryptionKey[SeedKeyLen] = { 0xF4, 0x66, 0x31, 0x59, 0xFC, 0x83, 0x6E, 0x31, 0x31, 0x02, 0x51, 0xD5, 0x44, 0x31, 0x67, 0x98 };
    then you simply apply the appropriate cipher (i.e. encrypt, RC4 uses only one kind of action for both enc and dec, and that's XORing your data with the keystream) to do either encoding or decoding.

  12. #12
    kynox's Avatar Account not activated by Email
    Reputation
    830
    Join Date
    Dec 2006
    Posts
    888
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ah, its a simple HMAC-RC4 implementation then. Seems fitting, they use that everywhere.

  13. #13
    Jotunskjoldr's Avatar Member
    Reputation
    3
    Join Date
    Apr 2009
    Posts
    7
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Lol, being the crypto noob that I am, I didn't realised that. Ah well, then you can replace all my code with
    Code:
    $self->{cipher_key} = hmac_sha1($session_key, $hmac_key);
    where hmac_key is what I used to call the seed_key before.

Similar Threads

  1. Replies: 0
    Last Post: 07-13-2009, 05:07 AM
  2. Perl operators
    By tttommeke in forum Programming
    Replies: 1
    Last Post: 03-09-2008, 10:44 PM
  3. Anyone know Perl scripting?
    By Monx_W0W in forum Community Chat
    Replies: 2
    Last Post: 11-17-2007, 09:00 AM
All times are GMT -5. The time now is 06:35 AM. Powered by vBulletin® Version 4.2.3
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2024 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search