DNS, wywarzanie otwartych drzwi :)

0

Mój problem nie jest implementacyjny. Chciałbym skorzystać z serwera DNS ale chciałbym to zrobić ręcznie :] Znam funkcję gethostbyname() i strukturę hostent ale zastanawiam się jak mógłbym obsłużyć zapytanie DNS ręcznie. Tzn. connect() potem send() z odpowiednim zapytaniem.
Szukałem trochę, dłubałem w RFC ale nadal jestem w d***e. Podłączyć się podłączyłem (adres jednego z openDNS i port 21) ale nie otrzymałem żadnej odpowiedzi. Wiem że muszę dostać się do rekordu 'A' serwera, ale ort! nie wiem jak powinna wyglądać kwerenda żeby otrzymać cokolwiek.

ps. Nie wyzywajcie mnie od noobów itp, ja doskonale wiem że nim jestem ;-)

//q: 'cholipka' pochodzi od 'cholera' :)

0

Laczyc sie nie musisz z tym serwerem, ale jak chcesz. Mozesz skorzystac normalnie z datagramow UDP, albo raw sockets do tego uzyc. Wszystko i tak idzie datagramami.

Wysylasz wartosc 0x1000, czyli standard query z zapytaniem w postaci:

[nazwa host] [type] [klasa]

Serwer odpowiada 0x8180, czyli standard query response oraz no errors do tego otrzymujesz zapytanie, ktore Ty wyslesz mniej wiecej i czesc zawierajaca odpowiedz w postaci:

[nazwa host] [type] [klasa] [address ip]

Troche mnie zaciekawil Twoj problem, wiec postaram sie napisac kodzik i wrzucic, aby obadac dokladnie sprawe ;)

0

Z raw socketami to bym uważał, Windows generalnie od XP SP2 je blokuje, bo były używane wyłącznie do abuse...

0

@t0m_k-tmp: To teraz widzę że jestem głębiej w d***e niż sądziłem. Za kodzik będę bardzo wdzięczny ale....mógłbyś go wrzucić dopiero jutro wieczorem? ;-P Do tej pory chciałbym sam popróbować, wiem że jestem zboczony :D

0

Szkoda, ze jutro bo tylko naglowek mi zostal, ale ok ;)

0

To wyślij mi na maila :> Wiadomości nie odczytam a świadomość że już się z tym uporałeś mnie zmotywuje ;-P

0

Spoko, bede mial swiadomosc ze sie komus przyda jednak, ale jak juz zajrzysz to wrzuc na forum ;)

0

Wrzucę wrzucę, nie ograbię Cię z Twojej własności ;)

0

Wyslane, pare ciekawych rzeczy sie dowiedzialem, wszystko masz w mailu.
Nie chce mi sie pisac wnioskow znowu, jak bedziesz mogl to skopiuj maila, czy cos i wrzuc na forum ;)

0

Ja też bym z chęcią skorzystał.

0

Jako że już zajrzałem to wrzucę tego maila. Oto jego pełna treść:

"Wszystko napisalem na podstawie logow z wiresharka, wiec jest troche na sztywno.
Zauwazylem, ze kropki w nazwie hosta sa zamieniane na cos innego, przykladowo
www.google.pl
zamieni pierwsza kropke na 0x06, a druga na 0x02, niestety niewiem dlaczego tak sie dzieje ;p
Do tego przed nazwa hosta jest jeden bajcik przeznaczony chyba na jakis identyfikator, poniewaz jak wysylalem zle pakiety to mialem ze oznacza to roota, dla roznych hostow roznie wygladala ta wartosc.
Struktury samego naglowka za bardzo nie rozkminialem, ale pierwsze jest identyfikatorem, pozwalajacym polaczyc odpowiedz z zapytaniem.
Nastepnie typ zapytania, tez za bardzo w to nie wnikalem, dalej jedno pole okreslajace ilosc zapytan(tutaj sie przejechalem, bo raz nie chcacy dalem 0xFF i 255 zapytan zlych bylo :D).
Dalej niewiem co jest poniewaz na zera bylo ustawione. No i na koncu ten dziwny bajt, nazwa hosta, oraz dwa shorty okreslajace odpowiednio typ i klase zadania ;)
Kodzik wymaga podania nazwy hosta z www na poczatku oraz nie dodalem recvfrom, ale odpowiedz przychodzi, wiec jak dodasz to bedzie na pewno ip wybranego hosta.
Jeszcze jedno, struktura ta na gorze okresla wszystko oprocz tego bitu, hosta, typu i klasy."

I kod z poprawkami z drugiego maila:

#include <stdio.h>
#include <string.h>
#include <winsock.h>
#include <windows.h>
//#include <ws2tcpip.h>

typedef struct {
    unsigned short id;
    unsigned short qr;
    unsigned short wpisy;
    unsigned short odp;
    unsigned short bonus;
    unsigned short unk;
} dns_header;

int main(int argc, char *argv[])
{
	WSADATA wsaData;
	int sock;
    struct sockaddr_in sin;
    unsigned char bufor[1024];
    dns_header *dns = (dns_header*)bufor;

	if(argc != 2)
	{
		puts("USAGE: dns.exe <host>\n");
		return 0;
	}

	if(WSAStartup(MAKEWORD(2,0), &wsaData) != 0)
	{
		puts("ERROR: WSAStartup");
		return -1;
	}

    sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if(sock == INVALID_SOCKET)
    {
        puts("ERROR: socket");
        return -1;
    }

    memset(&sin, 0, sizeof(struct sockaddr_in));
    sin.sin_family = AF_INET;
    sin.sin_port = htons(53);
    sin.sin_addr.s_addr = inet_addr("208.67.222.222");//openDNS resolver1
    

    memset(bufor, 0, 1024*sizeof(unsigned char));
    dns->id = htons(0xDEAD);
    dns->qr = htons(0x0100);
    dns->wpisy = htons(0x0001);
    int i, b = 0x02;
	for(i = strlen(argv[1])-1; i >= 0; i--)
       if(argv[1][i] == 0x2e)
       {
           argv[1][i] = b;
           b += 0x04;
       }
	int len;
   while(i < strlen(argv[1]) && argv[1][i] != 0x2e)
   {
       len++;//dlugosc nazwy hosta od pierwszej kropki
       i++;
   }
    strcpy(bufor+sizeof(dns_header)+1, (unsigned char*)argv[1]);
    *((unsigned char*)&bufor[sizeof(dns_header)]) = len;
    *((unsigned char*)&bufor[sizeof(dns_header)+strlen(argv[1])+3]) = 1;
    *((unsigned char*)&bufor[sizeof(dns_header)+strlen(argv[1])+5]) = 1;

    if(sendto(sock, bufor, sizeof(dns_header)+strlen(argv[1])+6, 0, (struct sockaddr*)&sin, sizeof(struct sockaddr)) == SOCKET_ERROR)
    {
            puts("ERROR: sendto");
            return -1;
    }

    closesocket(sock);
	WSACleanup();

	return 0;
}

Mój kod (na podstawie wniosków t0mk) nie nadaje się do pokazywania ludziom ;-P

0

Tam w tym drugim opisalem te kropki i ten dziwny bajcik, jak mozesz to tez wrzuc tresc :D
Jeszcze co do rzutowania na unsigned char ta tablice w trzech miejscach to jest tu bez sensu, ale kombinowalem z unsigned short dla tablicy unsigned char, a nie chcialo mi juz sie zmieniac.

Dodatkowo niewiem dlaczego czasami wysylane jest zle zapytanie oraz niewiem dlaczego trzeba czasem www podac, a czasem bez www, dzis bede jeszcze sie zastanawial nad tym to dopisze.

0
t0m_k-tmp napisał(a)

Tam w tym drugim opisalem te kropki i ten dziwny bajcik, jak mozesz to tez wrzuc tresc

Yyy, dostałem tylko poprawki do kodu. Żadnych kolejnych wniosków nie ma w tym drugim mailu. Mogę screena zrobić :>

EDIT
@down: Te poprawki w kodzie już naniosłem wyżej.

0

Ja mam w wyslanych maila z trescia, wiec juz wrzuce ;p

Doszedlem do wniosku, ze ta petla powinna isc od konca:

    int i, b = 0x02;
    for(i = strlen(argv[1])-1; i >= 0; i--)
        if(argv[1][i] == 0x2e)
        {
            argv[1][i] = b;
            b += 0x04;
        }

oraz ten bicik:         // edit teraz: bajcik nie bicik

  *((unsigned char*)&bufor[sizeof(dns_header)]) = 3; 

okresla dlugosc nazwy hosta do pierwszej kropki:

  while(i < strlen(argv[1]) && argv[1][i] != 0x2e)
    {
        len++;
        i++;
    }

zamiast 3 daj tam wartosc zmiennej len

Teraz kod juz prawie jest uniwersalny, ale jeszcze w nim czegos brakuje,
albo o czyms niewiem. Jeszcze troche pokminie, ale jak cos wykminie to dopiero
jutro ;)

Pozdrawiam
t0m_k
0

Hmm, a jakby to musiało wyglądać w drugą stronę? Tzn. w zapytaniu IP i otrzymać hosta?

1 użytkowników online, w tym zalogowanych: 0, gości: 1