So I am wanting to learn more about DNS and I am wanting to use assembly to accomplish the task.
I noticed in tcpdump that my request appears to be accurate and I receive a response back, but my code doesn't know how to handle this.
I looked on a few sites and it looks like a recvfrom should be used , but I don't understand how I would call that function. Another answer I see is to use DUP2 and from what I understand it redirects stdin,out and err . From what I have been reading , I should manipulate sockcall ( 0x66 ) to call the recvfrom and get the data that has been sent to me. Most of the examples are using TCP and don't quite fit here since I am using UDP for the DNS.
Here is my code which queries google for example.com
nop
nop
nop
nop
; we create a socket fd, using again syscall 0x66 and argument SYS_SOCKET so ebx = 1
push 0x66
pop eax
push 0x1
pop ebx
xor ecx,ecx
push ecx
; but this times it will be a SOCK_DGRAM UDP, so 0x2 as argument
push 0x2
push 0x2
mov ecx,esp
int 0x80
; saving fd
push 0x08080808 ; 8.8.8.8 ; I love that this doesn't really need to be backwards.
;push 0x0100007F ; 0100007F 1.0.0.127 for testing...
xor edx,edx
mov dh, 0x35 ; port 53; comment this for variable port
push dx ; comment this for variable port
; push word PORT ; UNcomment this for variable port
push word 0x2 ;
mov ecx,esp ; save pointer to ecx
push 0x10 ; addrlen
push ecx ; pointer to sockaddr
push eax ; fd received previously
mov ecx,esp ;
mov esi,eax ; save fd for next call
xor eax,eax
mov al,0x66
add bl,0x2
int 0x80
; now we send a UDP packet to open stateful firewall :]
xor eax,eax
mov al,0x66 ; ssize_t send(int sockfd, const void *buf, size_t len, int flags);
push 0x00000001
push 0x00010000
push 0x6d6f6303
push 0x656c706d
push 0x61786507
push 0x00000000
push 0x00000100
push 0x0001AAAA
mov edx,esp ; Move the string to EDX so we can send it.
xor ecx,ecx
push ecx
push 64 ; size of message to be sent is 8
push edx
push esi
mov ecx,esp
xor ebx,ebx
mov bl,0x9
int 0x80
mov ebx,esi
xor ecx,ecx
mov cl,0x2
loop: ;Not sure if this is needed at all
; syscall dup2
mov al,0x3f
int 0x80
dec ecx
jns loop
xor esi,esi
push esi
mov edx,esp
push ebx
mov ecx,esp
int 0x80
nop
nop
nop
Here is how it's done .
;Author : Krash
section .text
global main ;must be declared for linker (ld)
; SOCKETCALL PARAMS You can pass a value to EBX to utilize one of these functions.
; #define SYS_SOCKET 1 /* sys_socket(2) */
; #define SYS_BIND 2 /* sys_bind(2) */
; #define SYS_CONNECT 3 /* sys_connect(2) */
; #define SYS_LISTEN 4 /* sys_listen(2) */
; #define SYS_ACCEPT 5 /* sys_accept(2) */
; #define SYS_GETSOCKNAME 6 /* sys_getsockname(2) */
; #define SYS_GETPEERNAME 7 /* sys_getpeername(2) */
; #define SYS_SOCKETPAIR 8 /* sys_socketpair(2) */
; #define SYS_SEND 9 /* sys_send(2) */
; #define SYS_RECV 10 /* sys_recv(2) */
; #define SYS_SENDTO 11 /* sys_sendto(2) */
; #define SYS_RECVFROM 12 /* sys_recvfrom(2) */
; #define SYS_SHUTDOWN 13 /* sys_shutdown(2) */
; #define SYS_SETSOCKOPT 14 /* sys_setsockopt(2) */
; #define SYS_GETSOCKOPT 15 /* sys_getsockopt(2) */
; #define SYS_SENDMSG 16 /* sys_sendmsg(2) */
; #define SYS_RECVMSG 17 /* sys_recvmsg(2) */
; #define SYS_ACCEPT4 18 /* sys_accept4(2) */
; #define SYS_RECVMMSG 19 /* sys_recvmmsg(2) */
; #define SYS_SENDMMSG 20 /* sys_sendmmsg(2) */
;The Message We want to send.
;DNS HEADER;
; AA AA - ID
; 01 00 - Query parameters
; 00 01 - Number of questions
; 00 00 - Number of answers
; 00 00 - Number of authority records
; 00 00 - Number of additional records
; DNS QUESTION --
; 07 - 'example' has length 7, ;so change this to be the length of domain ; keep in mind there are not '.' in the question.
; 65 - e
; 78 - x
; 61 - a
; 6D - m
; 70 - p
; 6C - l
; 65 - e
; 03 - subdomain '.com' length 03 ; change this to be the length of type.
; 63 - c
; 6F - o
; 6D - m
; 00 - zero byte to end the QNAME
; 00 01 - QTYPE
; 00 01 - QCLASS
; DNS ANSWER! This is What We Want to receive ;
; aa aa
; 81 80
; 00 01
; 00 01
; 00 00
; 00 00
; 07 65
; 78 61
; 6d 70
; 6c 65
; 03 63
; 6f 6d
; 00 00
; 01 00
; 01 c0
; 0c 00
; 01 00
; 01 00
; 00 12
; 8d 00
; 04
; IP ADDRESS IN HEX -- 93.184.216.34
; 5d
; b8
; d8
; 22
main:
; we create a socket fd, using again syscall 0x66 and argument SYS_SOCKET so ebx = 1
push 0x66
pop eax
push 0x1
pop ebx
xor ecx,ecx
push ecx
; but this times it will be a SOCK_DGRAM UDP, so 0x2 as argument
push 0x2
push 0x2
mov ecx,esp
int 0x80 ; SYS_SOCKET
; saving fd on the stack ; In reality I think I will save the port here instead
push eax
push 0x08080808 ; 8.8.8.8 ; I love that this doesn't really need to be backwards.
;push 0x0100007F ; 0100007F 1.0.0.127 for testing...
xor edx,edx
mov dh, 0x35 ; port 53; comment this for variable port
push dx ; comment this for variable port
; push word PORT ; UNcomment this for variable port
push word 0x2 ;
mov ecx,esp ; save pointer to ecx
push 0x10 ; addrlen
push ecx ; pointer to sockaddr
push eax ; fd received previously
mov ecx,esp ;
mov esi,eax ; save fd for next call
xor eax,eax
mov al,0x66
add bl,0x2 ; BL = 3 SYS_CONNECT
int 0x80 ;CALL SYS_CONNECT
; now we send a UDP packet to open stateful firewall :]
xor eax,eax
mov al,0x66
push 0x00000001 ; Origional Working request to google dns for example.com
push 0x00010000
push 0x6d6f6303
push 0x656c706d
push 0x61786507
push 0x00000000
push 0x00000100
push 0x0001AAAA ; This is the DNS HEADER above in little endian order.
mov edx,esp ; Move the string to EDX so we can send it.
xor ecx,ecx
push ecx
push 64 ; size of message to be sent is 8
push edx
push esi
mov ecx,esp
xor ebx,ebx
mov bl,0x9
int 0x80 ;CALL SYS_SEND
mov eax, 3 ; Prepare for SYSCALL_READ
mov ebx, 3 ;
mov ecx, esp
mov edx, 100
int 0x80 ;CALL SYSCALL_READ
add esp, eax
sub esp, 4
mov eax ,[esp]
push eax ; Probably not needed, I just want to ensure it's saved on the stack for further use..
User contributions licensed under CC BY-SA 3.0