Results 1 to 5 of 5

Thread: Winex Sniffer

  1. #1
    Registered User
    Join Date
    Jan 2003
    Posts
    2

    Winex Sniffer

    uses Ptrace function to the read the sessionkey, prints the session key, and sends it via udp to a server/port if specified.

    syntax: ./Sniff <PID> <OFFSET> <IP ADDRESS> <PORT>

    To get pid use the ps -ax command.

    enjoy!
    Attached Files Attached Files

  2. #2
    Registered User
    Join Date
    Oct 2002
    Posts
    235

    Local sniffing

    This quite likely will only work if you have two machines, one linux running wine and one linux running showeq. The code does not sniff loopback.

    I have a kernel driver that processes an encrypted command block and returns the key encrypted back to the client which sends it encrypted over the ethernet to the seq box via a server on the showeq box. This server decrypts the key and sends it plain text to 127.0.0.1 on the same port as an 8 byte key format packet. Below are the edits to showeq to make it listen to these (and as a result your winex sniffer) packets alone with a few paranoid changes.

    Much of this is a moot point until someone figures out the new packet format. From what I can tell either the opcodes have drastically changed or every packet gets a seemingly random chunk of data prepended and the opcodes changed. Many packets are still zlibed as they have a valid chunk of compressed data with dictionary inside (0x785e).

    summary of changes:
    increase packet sizes, check key packet length, change pcap filter, and finally check DLL for cooked SLL sockets (network "any" instead of "eth")

    diff follows:

    diff -r -b -w -c /root/showeq/showeq/src/packet.cpp ./packet.cpp
    *** /root/showeq/showeq/src/packet.cpp Thu Jan 16 12:56:28 2003
    --- ./packet.cpp Tue Jan 28 19:18:16 2003
    ***************
    *** 799,805 ****
    /* Set flag that we are busy decoding */
    m_busy_decoding = true;

    ! unsigned char buffer[1500];
    short size;

    /* fetch them from pcap */
    --- 910,916 ----
    /* Set flag that we are busy decoding */
    m_busy_decoding = true;

    ! unsigned char buffer[1518]; // XXX fester 1500 original, too small?
    short size;

    /* fetch them from pcap */
    ***************
    *** 1015,1021 ****
    }

    /* Key Sniffer Hook */
    ! if ((packet.getDestPort() == m_keyPort))
    {
    keyStruct* keypacket = (keyStruct *)packet.getUDPPayload();
    m_decode->theKey(keypacket->key);
    --- 1126,1132 ----
    }

    /* Key Sniffer Hook */
    ! if ((packet.getDestPort() == m_keyPort) && (packet.getRawPacketLength() == 8)) // fester added len chk
    {
    keyStruct* keypacket = (keyStruct *)packet.getUDPPayload();
    m_decode->theKey(keypacket->key);
    ***************
    *** 3668,3674 ****
    --- 3845,3855 ----
    else
    {
    printf ("Filtering packets on device %s, IP host %s\n", device, host);
    + #if 1 // fester need to also get lo if packets to 127.0.0.1 when using "any" device
    + sprintf (filter_buf, "udp[0:2] > 1024 and udp[2:2] > 1024 and ((host %s and ether proto 0x0800) or (ho
    st 127.0.0.1 and udp))", host);
    + #else
    sprintf (filter_buf, "udp[0:2] > 1024 and udp[2:2] > 1024 and host %s and ether proto 0x0800", host);
    + #endif
    }
    }

    ***************
    *** 3701,3707 ****
    --- 3882,3893 ----
    ** and cause us to miss new stream when the player zones.
    */
    // initialize the pcap object
    + #if 1 // XXX fester ethernet size limit is 1518 and not 1500
    + m_pcache_pcap = pcap_open_live((char *) device, 1518, true, 0, ebuf);
    + // printf("device name %s, datalink %d\n", device, pcap_datalink(m_pcache_pcap));
    + #else
    m_pcache_pcap = pcap_open_live((char *) device, 1500, true, 0, ebuf);
    + #endif

    if (!m_pcache_pcap)
    {
    ***************
    *** 3760,3766 ****
    --- 3948,3962 ----
    PacketCaptureThread* myThis = (PacketCaptureThread*)param;
    pc = (struct packetCache *) malloc (sizeof (struct packetCache) + ph->len);
    pc->len = ph->len;
    + if (pcap_datalink(myThis->m_pcache_pcap) == DLT_LINUX_SLL) { // fester
    + // XXX If we opened device "any" on Linux, we get datalink type
    + // DLT_LINUX_SLL (16 bytes) instead of ethernet (14 bytes).
    + // Showeq currently does not make use of the Ethernet Datalink
    + // data, so chop off two bytes to make it all work.
    + memcpy (pc->data, &data[2], ph->len);
    + } else {
    memcpy (pc->data, data, ph->len);
    + }
    pc->next = NULL;

    pthread_mutex_lock (&myThis->m_pcache_mutex);
    ***************
    *** 3822,3827 ****
    --- 4018,4034 ----

    /* Listen to World Server or the specified Zone Server */
    if (address_type == IP_ADDRESS_TYPE && client_port)
    + #if 1 // fester need to also get lo if packets to 127.0.0.1 when using "any" device
    + sprintf (filter_buf, "(udp[0:2] = 9000 or udp[2:2] = 9000 or udp[0:2] = 9876 or udp[0:2] = %d or udp[2:2
    ] = %d or udp[2:2] = %d) and ((host %s and ether proto 0x0800) or (host 127.0.0.1 and udp))", client_port, client_
    port, key_port, hostname);
    + else if (address_type == IP_ADDRESS_TYPE && zone_port)
    + sprintf (filter_buf, "(udp[0:2] = 9000 or udp[2:2] = 9000 or udp[0:2] = 9876 or udp[0:2] = %d or udp[2:2
    ] = %d or udp[2:2] = %d) and ((host %s and ether proto 0x0800) or (host 127.0.0.1 and udp))", zone_port, zone_port
    , key_port, hostname);
    + else if (address_type == MAC_ADDRESS_TYPE && client_port)
    + sprintf (filter_buf, "(udp[0:2] = 9000 or udp[2:2] = 9000 or udp[0:2] = 9876 or udp[0:2] = %d or udp[2:2
    ] = %d or udp[2:2] = %d) and ((ether host %s and ether proto 0x0800) or (host 127.0.0.1 and udp))", client_port, c
    lient_port, key_port, hostname);
    + else if (address_type == MAC_ADDRESS_TYPE && zone_port)
    + sprintf (filter_buf, "(udp[0:2] = 9000 or udp[2:2] = 9000 or udp[0:2] = 9876 or udp[0:2] = %d or udp[2:2
    ] = %d or udp[2:2] = %d) and ((ether host %s and ether proto 0x0800) or (host 127.0.0.1 and udp))", zone_port, zon
    e_port, key_port, hostname);
    + else if (hostname != NULL && !client_port && !zone_port)
    + sprintf (filter_buf, "udp[0:2] > 1024 and udp[2:2] > 1024 and ((ether proto 0x0800 and host %s) or (hos
    t 127.0.0.1 and udp))", hostname);
    + #else
    sprintf (filter_buf, "(udp[0:2] = 9000 or udp[2:2] = 9000 or udp[0:2] = 9876 or udp[0:2] = %d or udp[2:2
    ] = %d or udp[2:2] = %d) and host %s and ether proto 0x0800", client_port, client_port, key_port, hostname);
    else if (address_type == IP_ADDRESS_TYPE && zone_port)
    sprintf (filter_buf, "(udp[0:2] = 9000 or udp[2:2] = 9000 or udp[0:2] = 9876 or udp[0:2] = %d or udp[2:2
    ] = %d or udp[2:2] = %d) and host %s and ether proto 0x0800", zone_port, zone_port, key_port, hostname);
    ***************
    *** 3831,3836 ****
    --- 4038,4044 ----
    sprintf (filter_buf, "(udp[0:2] = 9000 or udp[2:2] = 9000 or udp[0:2] = 9876 or udp[0:2] = %d or udp[2:2
    ] = %d or udp[2:2] = %d) and ether host %s and ether proto 0x0800", zone_port, zone_port, key_port, hostname);
    else if (hostname != NULL && !client_port && !zone_port)
    sprintf (filter_buf, "udp[0:2] > 1024 and udp[2:2] > 1024 and ether proto 0x0800 and host %s", hostname
    );
    + #endif
    else
    {
    printf ("Filtering packets on device %s, searching for EQ client...\n", device);

  3. #3
    Registered User
    Join Date
    Jan 2003
    Posts
    2
    wasnt intended for a machine running both winex and seq, so i never really tested it for loopback.

  4. #4
    Registered User
    Join Date
    Dec 2001
    Posts
    247
    Honestly the work seems somewhat overkill to also sniff the loopback. Obviously you can't send the key to yourself either... so pick another IP in an existenting or non-existent ip network(preferably and unrouted one).
    The system was designed to be stupid simple and get the job done, which it is. Over complication will only create problems down the road. I object specficially to sniffing loopback in that it complicates the process of ignoring packets showeq doesn't need. But I guess if you are paranoid enough to "encrypt" the key being sent from the EQ host to the SEQ host then anything I have to say must just be propaganda. Convince me this change is beneficial.

    Questions:
    If we open the "any" device for pcap we aren't able to set promiscous. Is this a problem you have encountered somewhere? Is this the result of sniffing loopback?

    Fee

  5. #5
    Registered User
    Join Date
    Oct 2002
    Posts
    235

    promisc

    I have promisc in the start up ifconfig for the system, so eth is always in promisc mode. Opening "any" doesnt enable promisc if it wasn't already enabled, but it also doesnt disable it when seq exits.

    I understand and appreciate what your saying on complication.
    The complicated part of the changes (imo) is the pcap changes to include seq keyport loopback packets. I couldnt think of a better way to craft those (save for being specific to the seq key sniffer port). The only other change for loopback that is required is a change to check the data link layer type for the pcap interface before each packet is copied. If it is SLL (Linux cooked format only used when multiple different types of interfaces are sniffed), then skip two bytes to make the bytes of the IP packet line up properly. The 2 other changes are me being concerned that 1500 is too short, and increasing a buffer to 1518 (probably not a real problem).

    Another alternative is to have seq open a real socket on 127.0.0.1 for listening and only accept packets from 127.0.0.1 (sent from localhost).

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

You may post new threads
You may post replies
You may post attachments
You may edit your posts
HTML code is Off
vB code is On
Smilies are On
[IMG] code is Off