|
昨天突然無法訪問任何網站了,可是QQ還在正常工作~~~~~`嗯,肯定是DNS出了問題~~
用自己做的TraceRoute察看了一下,6個網關都工作正常~~~确實是DNS壞了~~
爛鐵通的DNS太差~~換~~~可是哪個DNS更好?
自己做一個工具比較一下吧~~可是還不懂DNS的工作原理^_^
搜索百度,下載TCP/IP 詳解2卷~~竟然沒有一個能下的了......還中了木馬~~~~`暈倒!
不過有收獲!找到了全國的各大城市DNS列表!
看來隻有自己蒙了!好在還有IRIS。不過試用期隻剩10天了!呵呵,抓包......原來是這樣的:Windows向DNS發送了一個UDP包,這個包中當然有’www.xxx.com’,然後DNS服務器返回一個包含IP地址的UDP包,我們的工作就是分解這個包~~~~~
DNS服務器的端口是53,接受的Query package格式如下:
PDomainQuery = ^YDomainQuery;
YDomainQuery = record
u16id : word;//任意
u16flag : word;//$0100; //标準查詢
u16question : word;//1
u16answer : word;//0
u16author : word;//0
u16addition : word;//0
u8secB : byte;//section begin
u8secE : byte;//section end
u16type : word;//1
u16class : word;//1
end; |
我們這樣填充這個包:
procedure FillDomainQuery( pdq: PDomainQuery; sAddr: string );
var
pData, pTemp : PChar;
i, cbLen : Integer;
pu16 : PWord;
begin
FillChar( pdq^, sizeof(YDomainQuery) + Length(sAddr), 0 );
pdq^.u16id := htons( DNS_ID );
pdq^.u16flag := htons( DNS_STAND_QUERY );
pdq^.u16question := htons( DNS_QUESTION );
//pdq^.u16answer := 0; //pdq^.u16author := 0; //pdq^.u16addition := 0;
//初始化域名數據緩沖區
cbLen := Length(sAddr) + 2;
pData := AllocMem( cbLen );
Inc( pData );
Move( sAddr[1], pData^, Length(sAddr) );
Dec( pData );
//填充域名數據緩沖區
pTemp := pData;
i := Pos( ’.’, sAddr ); //www.baidu.com --- example
while i > 0 do
begin //i=4; i=6
pTemp^ := Chr(i-1); // 3 5
Inc( pTemp, i ); // ^ ^
Delete( sAddr, 1, i ); //s=’baidu.com’; s=’com’
i := Pos( ’.’, sAddr );
end;
pTemp^ := Chr( Length(sAddr) ); //s=’com’
Inc( pTemp, Length(sAddr)+1 );
pTemp^ := #0;
//把域名數據拷貝到pdq^.u8secB
pTemp := @pdq^.u8secB;
Move( pData^, pTemp^, cbLen );
FreeMem( pData );
//最後填寫Type/Class
pu16 := PWord( pTemp + cbLen );
pu16^ := htons( DNS_TYPE_HOST );
Inc( pu16 );
pu16^ := htons( DNS_CLASS_INET );
end;
//把構造好的包發送出去
var
pdq : PDomainQuery;
pdq := AllocMem( sizeof(YDomainQuery) + Length(edtDomain.text) );
FillDomainQuery( pdq, edtDomain.text );
udp.SendBuf( PChar(pdq), sizeof(YDomainQuery) + Length(edtDomain.text) );
//不過DNS返回的包更複雜~~~不給它定義什麽結構了,直接整!!!
function DecodeDomainAnwser( pbuf: PChar; len: Integer ):string;
var
p : PChar;
w : Word;
j : Integer;
s1,s2,s3,s4: string;
begin
p := pbuf; j:=0;
result := ’TransactionID: ’ + IntToStr( PWord(p)^ ) +#13#10;
Inc( p, 2 ); Inc( j, 2 );
result := result + ’Response Flag:’ + Format(’%x’, [ntohs(PWord(p)^)]) +#13#10;
if ntohs( PWord(p)^ ) <> DNS_STAND_RES then
begin
result := result + ’Response error...’ +#13#10;
Exit;
end;
Inc( p, 2 ); Inc( j, 2 );
result := result + ’Question: ’ +IntToStr( ntohs(PWord(p)^) )+ #13#10;
Inc( p, 2 ); Inc( j, 2 );
result := result + ’Answer: ’ +IntToStr( ntohs(PWord(p)^) )+ #13#10;
Inc( p, 2 ); Inc( j, 2 );
result := result + ’Authority: ’ +IntToStr( ntohs(PWord(p)^) )+ #13#10;
Inc( p, 2 ); Inc( j, 2 );
result := result + ’Addition: ’ +IntToStr( ntohs(PWord(p)^) )+ #13#10;
Inc( p, 2 ); Inc( j, 2 );
w := Byte( p^ );
while w > 0 do //跳過DNS HOST返回的要查詢的域名
begin
Inc( p, w + 1 ); Inc( j, w+1 );
w := Byte( p^ );
end;
Inc( p ); Inc( j );
Inc( p, 4 ); Inc( j, 4 );//type/class
Inc( p, 6 ); Inc( j, 6 );//name/type/class
Inc( p, 4 ); Inc( j, 4 );//time
w := ntohs( PWord(p)^ ); //得到數據長度
Inc( p, 2 ); Inc( j, 2 );//到達真正的數據地址
Inc( p, w ); Inc( j, w );
Inc( p, 10 ); Inc( j, 10 );
Inc( p, 2 ); Inc( j, 2 );
s1 := IntToStr( Byte(p^) ); Inc( p ); Inc( j );
s2 := IntToStr( Byte(p^) ); Inc( p ); Inc( j );
s3 := IntToStr( Byte(p^) ); Inc( p ); Inc( j );
s4 := IntToStr( Byte(p^) ); Inc( p ); Inc( j );
result := result + ’IP: ’ + s1 + ’.’ + s2 + ’.’ + s3 + ’.’ + s4 + #13#10;
if len < j+32 then
Exit;
Inc( p, 6 ); //+name/type/class
Inc( p, 4 ); //+time
Inc( p, 2 ); //到達真正的數據地址
s1 := IntToStr( Byte(p^) ); Inc( p );
s2 := IntToStr( Byte(p^) ); Inc( p );
s3 := IntToStr( Byte(p^) ); Inc( p );
s4 := IntToStr( Byte(p^) );
result := result + ’IP: ’ + s1 + ’.’ + s2 + ’.’ + s3 + ’.’ + s4 +#13#10;
end; |
呵呵,試驗一下,全國的各大城市DNS列表中的Host竟然大都不能用~~~~~~~
|