Page 1 of 2

WinSock2 RAW socket : what's wrong with my code ?

Posted: Tue Dec 23, 2003 9:05 pm
by newbie
Hi,

I'm trying for security purpose to write my own packet (currently i'm tsting the strenght of an encrypted chat server).

I have the following code :
Structure in_addr
s_addr.l
EndStructure

Structure sockaddr_in2
sin_family.w
sin_port.w
sin_addr.in_addr
sin_zero.b[8]
EndStructure

Structure ip_hdr2
ip_hl.b
ip_v.b
ip_tos.b
ip_len.w
ip_id.w
ip_off.w
ip_ttl.b
ip_p.b
ip_cksum.w
ip_src.l
ip_dest.l
EndStructure

Structure Packet
headerIP.ip_hdr2
EndStructure




Procedure toto()
; Variables
IPdst.s
sock.sockaddr_in2
pckt.packet

; Initialise la pile TCP/IP
Resultat = InitWinsock() ; (Steve Bigras piece of code)
If Resultat = 0
MessageBox_(0, "Aucune Pile TCP/IP disponible sur le système.", "Error", #MB_ICONERROR)
ProcedureReturn 1
EndIf

; remplissage variables
IPdst = GetGadgetText(#String_0)
*pckt = @VirtualAlloc_(#NULL, SizeOf(ip_hdr2), #MEM_COMMIT, #PAGE_READWRITE)
rtlzeromemory_(pckt, SizeOf(ip_hdr2))

; IP header
pckt\headerIP\ip_src = inet_addr_("192.168.0.4")
pckt\headerIP\ip_dest = inet_addr_("192.168.0.2")
pckt\headerIP\ip_v = 4
pckt\headerIP\ip_hl = 5
pckt\headerIP\ip_tos = 0
pckt\headerIP\ip_len = htons_(SizeOf(ip_hdr2))
pckt\headerIP\ip_id = htons_(1111)
pckt\headerIP\ip_off = htons_(0)
pckt\headerIP\ip_ttl = 255
pckt\headerIP\ip_p = #IPPROTO_IP
;pckt\headerIP\ip_cksum = 0


; création du socket
fd = socket_(#AF_INET, #SOCK_RAW, #IPPROTO_RAW)
If fd < 0
MessageBox_(0, "Erreur lors de la création du socket", "Socket Error", #MB_ICONERROR)
ProcedureReturn 1
EndIf

; envoi du paquet
sock\sin_family = #AF_INET
sock\sin_addr\s_addr = inet_addr_(IPdst)
res = sendto_(fd, @pckt, SizeOf(ip_hdr2), 0, @sock.sockaddr_in2, SizeOf(sock))
If res < 0
MessageBox_(0, "Erreur lors de l'envois du paquet", "Erreur", #MB_ICONERROR)
EndIf

CloseSocket_(fd)

TerminateWinsock()

MessageBox_(0, "Envoyés", "ok", #MB_ICONINFORMATION)

EndProcedure
The IP header that i write is written by the OS after his own IP header :
20:56:23.826775 192.168.0.1 > 192.168.0.2: ip-proto-255 21 (ttl 128, id 2672, len 41)
0x0000 4500 0029 0a70 0000 80ff ae12 c0a8 0001 E..).p..........
0x0010 c0a8 0002 0504 0000 1504 5700 00ff 0000 ..........W.....
0x0020 00c0 a800 04c0 a800 0200 0000 0000 ..............
80 : TTL => 128 (OS defined)
FF : TTL => 255 : that i chose, but it is not written (like all the other stuff) where it should be written, so it isn't a TTL from the OS point of view.

Why my IP header is not write in first ?
The fact to define a socket as RAW should force the OS to _not_ write the header and to let us do it, what's wrong ?

Posted: Wed Dec 24, 2003 2:19 am
by newbie
i had many mistakes, a more simple code (still not working) :
IPdst.s
sock.sockaddr_in2
pckt.packet

; Initialise la pile TCP/IP
Resultat = InitWinsock()
If Resultat = 0
MessageBox_(0, "Aucune Pile TCP/IP disponible sur le système.", "Error", #MB_ICONERROR)
ProcedureReturn 1
EndIf

; remplissage variables
IPdst = GetGadgetText(#String_0)

; IP header
pckt\headerIP\ip_hlv = $45
pckt\headerIP\ip_tos = $00
pckt\headerIP\ip_len = htons_(SizeOf(packet))
pckt\headerIP\ip_id = $1111
pckt\headerIP\ip_off = htons_($4000)
pckt\headerIP\ip_ttl = $FF
pckt\headerIP\ip_p = #IPPROTO_IP
pckt\headerIP\ip_cksum = 0
pckt\headerIP\ip_src = inet_addr_("192.168.0.4")
pckt\headerIP\ip_dest = inet_addr_("192.168.0.2")

; création du socket
fd = socket_(#AF_INET, #SOCK_RAW, #IPPROTO_RAW)
If fd < 0
MessageBox_(0, "Erreur lors de la création du socket", "Socket Error", #MB_ICONERROR)
ProcedureReturn 1
EndIf

; envoi du paquet
sock\sin_family = #AF_INET
sock\sin_addr\s_addr = pckt\headerIP\ip_dest
res = sendto_(fd, pckt, SizeOf(packet), 0, @sock, SizeOf(sockaddr_in2))
If res < 0
MessageBox_(0, "Erreur lors de l'envois du paquet : " + Str(wsagetlasterror_()), "Erreur", #MB_ICONERROR)
EndIf

CloseSocket_(fd)
TerminateWinsock()
This time i'm using the normal "ip_hdr" structure.

I can't understand why it doesn't works, because i already done it in C and even a simple sniffer, i just converted the code and it should work.
I checked what was #IPPROTO_RAW value and others constants to see if PB picked up good values and there is no bugs in PB, so the error is in the code.
It's going to make me mad since the code is step by step my existing working code in C.

If someone can help :cry:

Posted: Wed Dec 24, 2003 2:31 am
by pbdep
long time ago i played with RAW, but i think im missing "setsocketopt"
in your code...

pbdep.

Posted: Wed Dec 24, 2003 1:48 pm
by newbie
never used that in the C code (but never used too the Winsock initialization in C code on linux whereas it is needed on Windows).

so i will take a look at it, and who knows, may it'll work, thx you :)

Posted: Wed Dec 24, 2003 7:40 pm
by newbie
didn't work :(

I tried with loading winsock ver 1 ou 2, and i have always the same result :cry:

Posted: Wed Dec 24, 2003 10:12 pm
by Doobrey
newbie wrote:didn't work :(

I tried with loading winsock ver 1 ou 2, and i have always the same result :cry:
What version of Windows are you using?
Sending raw packets (with your own header) under Win95 & 98 is broken. Typical Microsoft, take perfectly working BSD TCP code, and screw it up !

Posted: Thu Dec 25, 2003 1:19 am
by newbie
I am very near the solution.

i'm using Win XP + SP1.

the key seems indeed the setsockopt :
temp.w = 1
#IP_HDRINCL = 2
res = setsockopt_(fd, #IPPROTO_IP, #IP_HDRINCL, @temp, SizeOf(temp))
the middle option IP_HDRINCL seems to be the key which tell to the OS that we INCLude the HDRer.
This line is accepted.

But, after the following line :
sock\sin_family = #AF_INET
sock\sin_addr\s_addr = inet_addr_("192.168.0.2")

res = sendto_(fd, pckt, SizeOf(pckt), 0, @sock, SizeOf(sock))
I have winsock error :
WSAEADDRNOTAVAIL (10049) Cannot assign requested address.

whereas before without setting socket option i haven't errors with it.

So may be i badly built my header which result in this error ?
pckt\headerIP\ip_hlv = $45
pckt\headerIP\ip_tos = $0
pckt\headerIP\ip_len = SizeOf(packet)
pckt\headerIP\ip_id = $1111
pckt\headerIP\ip_off = $4000
pckt\headerIP\ip_ttl = $FF
pckt\headerIP\ip_p = #IPPROTO_IP
;pckt\headerIP\ip_cksum = 0; computed by the OS
pckt\headerIP\ip_src = inet_addr_("192.168.0.1")
pckt\headerIP\ip_dest = inet_addr_("192.168.0.2")

Posted: Thu Dec 25, 2003 2:29 am
by pbdep
:-)

Are you trying to fake sourceaddress ?

pbdep.

Posted: Thu Dec 25, 2003 2:58 am
by newbie
yes, between other.

purposes ?

- knowledge, to do packets myself
- security tests (yes, really!)
- firewall tests

as i said the code is near to work... if someone know the last which miss... :)

EDIT :
i found someone having the same pb under XP with C++, and his solution was :
fd = WSASocket_(#AF_INET, #SOCK_RAW, #IPPROTO_RAW, #NULL, 0, 0)
For an unknown reason PB doesn't recognize this API, where is the problem ?

Posted: Thu Dec 25, 2003 4:03 am
by newbie
last post before to sleep ;)

I can use the WSAsocket in loading ws2_32.dll but it still doesn't work.
I can use the following packet which is a good header, even if the cheksum isn't good :
Dim a.l(9)
a(0) = $45
a(1) = $00
a(2) = $05DC
a(3) = $7800
a(4) = $4000
a(5) = $FF
a(6) = $06
a(7) = $45BA
a(8) = $C8C00001
a(9) = $C8C00002

res = sendto_(fd, a, SizeOf(a), 0, @sock, SizeOf(sock))
Still the error : "the requested adress is not valid in its context."

Posted: Thu Dec 25, 2003 1:33 pm
by pbdep
Whats the number in sin_port ?
(They both must be set to a valid port, not zero!)

pbdep.

Posted: Thu Dec 25, 2003 1:37 pm
by pbdep
btw... It seems windows gives this error also when you try bind
to a invalid local socket + port.
(Thus Could be a bindError is a strange way perhpas...)

I assume both source address and destination address are know in your
network?

pbdep.

Posted: Thu Dec 25, 2003 2:33 pm
by newbie
since i just want (to start) make an IP packet, there is no ports, ports are in TCP and UDP, so indeed i didn't put a sin_port.

But i remember to have tried too, with sin_port = 2700, just to see, and still the same error, what means this "port" ?

Yes my comp = 192.168.0.1 and the other is on my LAN.

I didn't try to bind anything, i just want to send a packet, if i remember right the OS bind itself when i send the packet, but how can i bind if i spoof the packet ? (which isn't for now).

i'm still trying, if i find i will tell you.

Posted: Thu Dec 25, 2003 3:19 pm
by newbie
i found that the following code is indeed needed, and is done if i don't do it myself by the OS.
By doing it myself,i have the same error but we can see that it's indeed after the "bind" call :
sock\sin_family = #AF_INET
sock\sin_addr\s_addr = inet_addr_("192.168.0.2")
sock\sin_port = htons_(2700)
res = bind_(fd, @sock, SizeOf(sock))
an idea ?

Posted: Fri Dec 26, 2003 4:30 am
by newbie
Is anyone has a Windows C++ Raw Socket code to compare ?