hping wiki



Salvatore Sanfilippo 14Mar2004: eDonkey is the name of a file sharing network, actually it's also the non formal name of the protocol is uses. The eDonkey protocol is a binary protocol that works over TCP, usually port 4662. It also uses UDP in other ports for non-vital stuff. I wrote the following code as an exercise when I was learning Tcl (well, I'm still learning it, as all the simple things that can be combined in may ways it's infinite). It's not a complete implementation, but it's able to connect to another client, ask it for some info like username, server/port used, ID, and try to get the list of shared files (if the client is configured to allow it).
The usage is trivial. The program takes two arguments, one is the target host, and the second the target port (4662 should work). You can use it to make sure the file listing feature of your client is not turned on, or as a proof-of-concept of the fact that even with dynamic IP address is possible to identify people on internet using fixed information the software the user is running will report for free. Btw, that's the code:
#!/bin/sh
# the next line restarts using tclsh \
exec tclsh "$0" "$@"

# Some initial part of the client-side Emule protocol
# implementation.
#
# Copyright (C) 2003/2004 Salvatore Sanfilippo
# Under the same license as Tcl/Tk 8.4
#
# This code is already usable to connect to another client IP/Port
# (port is usually 4662) and show it's username, server, ID,
# and if available the list of shared files.
#
# Note that I'll never finish this code, this was written when
# I was learning some initial Tcl and liked to play with
# binary stuff.

proc write {fd data} {
    puts -nonewline $fd $data
}

proc protostr proto {
    switch $proto {
	e3 {format eDonkey}
	c5 {format {eMule extensions}}
	d4 {format {eMule compressed}}
	default {format "Unknown ($proto)"}
    }
}

proc cmdstr cmd {
    switch $cmd {
	4b {format {View files answer}}
	4c {format {Hello answer}}
	4e {format {Message}}
	58 {format {File name request}}
	default {format "Unknown (0x$cmd)"}
    }
}

proc mtagstr mtag {
    switch $mtag {
	0 {format Undefined}
	1 {format Hash}
	2 {format String}
	3 {format DWord}
	4 {format Float}
	5 {format Bool}
	6 {format {Bool array}}
	7 {format Blob}
	default {format "Unknown ($mtag)"}
    }
}

proc stagstr stag {
    switch $stag {
	1 {format Name}
	2 {format {Size of file}}
	3 {format Type}
	4 {format Format}
	5 {format Collection}
	6 {format {Part Path}}
	7 {format {Part Hash}}
	8 {format Copied}
	9 {format {Gap start}}
	10 {format {Gap end}}
	11 {format Description}
	12 {format Ping}
	13 {format Fail}
	14 {format Preference}
	15 {format Port}
	16 {format Ip}
	17 {format Version}
	18 {format TempFile}
	19 {format Priority}
	20 {format Status}
	21 {format Availability}
	22 {format QTime}
	23 {format Parts}
	default {format "Unknown $stag"}
    }
}

# Start
if {$argc != 1 && $argc != 2} {
    puts stderr {Usage: edinfo <host> [port]}
    exit 1
}
if {$argc == 1} {lappend argv 4662}
foreach {targethost targetport} $argv break

proc readPacket {fd protovar lenvar pktvar} {
    upvar $protovar proto $lenvar len $pktvar pkt
    # Read the header
    set hdr [read $fd 5]
    puts "Header length: [string length $hdr]"
    binary scan $hdr H2i proto len
    puts "Protocol: $proto ([protostr $proto])"
    puts "Length  : $len bytes"

    # Read the actual packet
    set pkt [read $fd $len]
}

proc buildPacket data {
    set len [string length $data]
    append pkt "\xe3"; # protocol (eDonkey)
    append pkt [binary format i $len]
    append pkt $data
}

proc sendHelo fd {
    puts "> Helo"
    # Build the Hello request
    append hello "\x01"; # command (Hello)
    append hello "\x10"; # user hash size (16 bytes)
    append hello "\x24\x0f\xf8\x30\xdd\x4b\x4e\x50"; # userhash first 8 bytes
    append hello "\x56\x91\xac\xeb\xae\x52\x4c\x9e"; # userhash last 8 bytes 
    append hello "\xaa\xbb\x00\x00"; # user id = Our IP for High ID
    append hello "\x36\x12"; # our ports
    append hello "\x02\x00\x00\x00"; # tag count (must be <= 7)
    append hello "\x03\x01\x00\x11\x3c\x00\x00\x00"; # Version tag
    append hello "\x02\x01\x00\x01\x07\x00panzutu"; # Name tag
    append hello "\x42\x6F\x2B\x50"; # server IP (0 = none)
    append hello "\x92\x10"; # server port (0 = none)

    # Send the Hello request
    set hellopkt [buildPacket $hello]
    write $fd $hellopkt

    # Read the packet
    readPacket $fd proto len reply

    # Porcess the reply
    binary scan $reply "cH32H2H2H2H2sia*" cmd userhash x1 x2 x3 x4 port tagcount reply
    set userid [expr 0x$x4$x3$x2$x1]
    set ip [expr 0x$x1].[expr 0x$x2].[expr 0x$x3].[expr 0x$x4]
    if {$userid <= 0xFFFFFF} {set ip "Low ID"}
    puts "Command : [format %02x $cmd] ([cmdstr [format %02x $cmd]])"
    puts "UserHash: $userhash"
    puts "UserId  : $userid ($ip)"
    puts "Port    : $port"
    puts "Tags    : $tagcount"

    # Read the tags
    while {[incr tagcount -1] >= 0} {
	binary scan $reply "csa*" mtag taglen reply
	if {$taglen == 1} {
	    binary scan $reply "ca*" stag reply
	    set tagname [stagstr $stag]
	} else {
	    binary scan $reply [format "%s%s" a$taglen a*] tagname reply
	}
	puts -nonewline "  [mtagstr $mtag] $taglen $tagname: "
	switch $mtag {
	    2 {
		binary scan $reply "sa*" strlen reply
		append fmt "a$strlen" "a*"
		binary scan $reply $fmt str reply
		puts "$str ($strlen bytes)"
	    }
	    3 {
		binary scan $reply "H2H2H2H2a*" x1 x2 x3 x4 reply
		set dw [expr 0x$x4$x3$x2$x1]
		puts $dw
	    }
	    default {
		puts "Unable to handle this TAG"
		exit 1
	    }
	}
    }

    # Read Server and Port
    binary scan $reply "H2H2H2H2sa*" x1 x2 x3 x4 servport reply
    set ip [expr 0x$x1].[expr 0x$x2].[expr 0x$x3].[expr 0x$x4]
    puts "Server IP: $ip"
    puts "Serv Port: $servport"
    if {[string length $reply]} {
	puts -nonewline "WARNING: Spurious data at end of reply:"
	binary scan $reply H* spurious
	puts " \[$spurious\]"
    }
}

proc hexdump data {
    set bytesperline 16
    set idx 0
    set l [string length $data]
    while {$l} {
	if {$l < $bytesperline} {
	    set c $l
	} else {
	    set c $bytesperline
	}
	set hexrepr {}
	set asciirepr {}
	for {set i 0} {$i < $c} {incr i} {
	    binary scan $data "aa*" byte data
	    binary scan $byte "H2" hexbyte
	    append hexrepr "$hexbyte "
	    if {[string is print $byte]} {
		append asciirepr $byte
	    } else {
		append asciirepr .
	    }
	}
	puts [format "%08d: %-50.50s|%-18.18s|" $idx $hexrepr $asciirepr]
	incr l -$c
	incr idx $c
    }
}

proc showGenericReply fd {
    readPacket $fd proto len reply
    binary scan $reply "ca*" cmd reply
    puts "Command : [format %02x $cmd] ([cmdstr [format %02x $cmd]])"
    puts "Data dump follows:"
    hexdump $reply
}

proc sendViewFiles fd {
    puts "> View Files"
    # Build the View Files request
    append pkt "\x4a"; # command (View Files)
    set hpkt [buildPacket $pkt]
    write $fd $hpkt

    # Read the packet
    showGenericReply $fd
}

proc sendMessage {fd msg} {
    puts "> Message \"$msg\""
    append pkt "\x4e" [binary format "s" [string length $msg]] $msg
    set hpkt [buildPacket $pkt]
    write $fd $hpkt

    # Read the packet
    # showGenericReply $fd
}

proc sendFileStatusRequest {fd hash} {
    puts "> File Status Request"
    # Build the File Status Request
    append pkt "\x4f"; # command (File Request)
    append pkt $hash; # file hash
    set hpkt [buildPacket $pkt]
    write $fd $hpkt

    # Read the packet
    readPacket $fd proto len reply
    puts "File Satatus reply length $len"
}

proc sendFileNameRequest {fd hash} {
    puts "> File Name Request"
    # Build the Files Request request
    append pkt "\x58"; # command (File Request)
    append pkt $hash; # file hash
    # black magic string
    append pkt "\x4b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04"

    # Send the request
    set hpkt [buildPacket $pkt]
    write $fd $hpkt

    # Read the packet
    readPacket $fd proto len reply
    puts "File Name Request reply length $len"
}

set fd [socket $targethost $targetport]
fconfigure $fd -encoding binary -buffering none
sendHelo $fd
#sendMessage $fd Hello
sendViewFiles $fd
#sendFileStatusRequest $fd 0123456789012345
close $fd

# vim: filetype=tcl softtabstop=4 shiftwidth=4

Links
http://www.edonkey2000-france.com/
 
Edit this page Upload file Page history - Page last update: Tue Nov 16 09:24:38 GMT 2004 by 80.181.43.200 | Your address: 18.117.153.38 | Admin