作者:leveryd
原文鏈接:https://mp.weixin.qq.com/s/WQeOfZtyKndbDebe66-V_g

背景

了解hids的讀者應該知道hids agent會有上報很多信息,其中有的agent會將可疑文件上報到云端做惡意分析。

同事問我一個問題:文件如果特別大,也會被上報嗎?不會影響性能嗎?

這個問題讓我聯想到 你的掃描器可以繞過防火墻么(三) 中大包繞過waf的場景,接著很容易想到:如果agent碰到大文件就不上傳了,不就很容易繞過云端的惡意分析了嘛。

另外,一個惡意文件如果體積過大,可能對安全研究人員做"樣本分析"造成一些困難,比如無法將文件下載到本地電腦(網速、磁盤空間可能不夠)、ida等靜態分析軟件內存占用過大。

基于以上"安全攻防"的業務場景,加上我最近在學習一些操作系統相關的知識,所以就研究下"怎么讓elf文件變大"。

文件變大的同時,還要滿足以下條件: 不影響elf文件執行 從實用角度來說,攻擊隊也不會生成一個大文件,然后上傳到目標。最好是上傳一個小文件,上傳到目標機器,然后本地讓文件變大。

先說結論,有以下方式讓"文件大小"變大: 文件末尾追加數據 稀疏文件 修改inode元數據 向elf文件節中填充垃圾數據

說明一下測試環境:測試程序是id命令,復制到了/tmp/y目錄下

[root@instance-fj5pftdp y]# \cp /usr/bin/id /tmp/y

文件末尾追加數據

怎么實現? 這種方式實現很簡單,如下

  [root@instance-fj5pftdp y]# echo 1111 >> ./id
  [root@instance-fj5pftdp y]# ./id
  uid=0(root) gid=0(root) 組=0(root)

關鍵是這樣修改后的文件,還能正常執行。

稀疏文件

"稀疏文件"是什么?

"稀疏文件"的"文件大小"和實際占用磁盤空間是不一致的,比如:

  [root@instance-fj5pftdp y]# ll -h id
  -rwxr-xr-x 1 root root 10T 9月   6 20:03 id
  [root@instance-fj5pftdp y]# du -sh id
  40K   id

從上面命令可以看到:"文件大小"是10T,但實際數據只占用40K的磁盤大小。

對于原理感興趣的讀者,可以參考 深度剖析 Linux cp 的秘密 這篇文章。

怎么修改成"稀疏文件"?

可以利用fallocate、truncate命令。

使用起來也很簡單,以truncate舉例:

  [root@instance-fj5pftdp y]# ls -alh id
  -rwxr-xr-x 1 root root 37K 9月   5 20:18 id
  [root@instance-fj5pftdp y]# time truncate -s 10T id   // 將id程序稀疏成10T大小

  real  0m0.007s
  user  0m0.000s
  sys   0m0.007s
  [root@instance-fj5pftdp y]# ls -alh id
  -rwxr-xr-x 1 root root 10T 9月   5 20:02 id    // 文件大小已經變成10T
  [root@instance-fj5pftdp y]# ./id
  uid=0(root) gid=0(root) 組=0(root)

這種方式修改文件有兩個特點:

文件改動非常快,上面的例子中將id文件大小擴大到"10T"只用了1s不到

文件大小最大可以是10T以上,但不需要本地磁盤空間真的有10T

當你想下載或者讀這個文件(比如cat)時,卻是會有實實在在的10T流量。10T流量,按照"10M/s"的速度下載,也需要下載291個小時。

修改inode元數據

  • 為什么修改"inode元數據"就可以修改文件大小信息?

inode元數據包含了文件大小信息,而inode元數據也是存儲在磁盤扇區中的,所以應該可以通過修改inode元數據來"偽造"文件大小。

其實不光大小信息,inode元數據中還包括 文件是否刪除、創建時間、修改時間、訪問時間 等信息,所以這些都可以被偽造。

可以通過stat命令查看inode元數據:

  [root@instance-fj5pftdp y]# stat id
    文件:"id"
    大小:37400        塊:80         IO 塊:4096   普通文件
  設備:fd01h/64769d   Inode:171252      硬鏈接:1
  權限:(0755/-rwxr-xr-x)  Uid:(    0/    root)   Gid:(    0/    root)
  最近訪問:2021-09-06 20:27:26.224913458 +0800
  最近更改:2021-09-06 20:27:26.218913032 +0800
  最近改動:2021-09-06 20:27:26.224913458 +0800
  創建時間:-
  • 怎么修改"inode元數據"?

利用debugfs命令,如下:

  [root@instance-fj5pftdp ~]# debugfs -w /dev/vda1
  debugfs:  mi /tmp/y/id
                            Mode    [0100755]
                         User ID    [0]
                        Group ID    [0]
                            Size    [37400] 100000      // 這里修改文件大小為100000
                   Creation time    [1630929039]
               ...
  debugfs:  quit
  [root@instance-fj5pftdp ~]# ll /tmp/y/id
  -rwxr-xr-x 1 root root 37400 9月   6 19:50 /tmp/y/id
  [root@instance-fj5pftdp ~]# echo 3 > /proc/sys/vm/drop_caches   // 清理inode緩存后,修改才生效
  [root@instance-fj5pftdp ~]# ll /tmp/y/id
  -rwxr-xr-x 1 root root 100000 9月   6 19:50 /tmp/y/id    // 文件大小變成了100000
  [root@instance-fj5pftdp ~]# /tmp/y/id
  uid=0(root) gid=0(root) 組=0(root)

在測試過程中,需要讀者注意的是:

因為會對磁盤數據做寫操作,所以最好找一個沒數據的機器做測試

記得清理inode緩存

測試時如果使用文件當作設備,在掛載文件系統時去修改文件大小 會不生效。原因未知

向elf文件節中添加垃圾數據

  • 是什么?

elf文件中包含很多的,比如:

.text存放代碼

.data存放初始化的全局變量和靜態變量

關于elf的文件格式,更多信息可以參考 《程序員的自我修養—鏈接、裝載與庫》第三章 elf文件結構描述。

可以向elf的節(比如.data、.text、.bss等)中寫入垃圾數據,而不影響程序的正常運行。

這種方式和其他三種方式的區別在于:因為可以刪掉沒用的節,所以就很容易就把"其他三種方式"修改的elf給還原回來。

比如strip后,文件大小就還原了

  [root@instance-fj5pftdp y]# ll -h id
  -rwxr-xr-x 1 root root 10T 9月   6 20:03 id
  [root@instance-fj5pftdp y]# strip id
  [root@instance-fj5pftdp y]# ll -h id
  -rwxr-xr-x 1 root root 37K 9月   6 20:27 id
  • 怎么"向elf文件節中添加垃圾數據"?

沒有找到linux自帶的命令,找到 patch elf工具-patchkit

看文檔感覺有點麻煩,就沒有做測試了。

總結

"文件末尾追加數據"和"向elf文件節中填充垃圾數據"這兩種方式是真的修改了文件內容,所以受限于磁盤空間大小也不可能生成幾個T大小的文件。

"稀疏文件"這種方式,可以方便快速地生成幾個T大小的文件,并且讓上傳、下載此文件 耗費很多時間,甚至是不可能成功。

"修改inode元數據",雖然也可以快速地將文件大小修改為幾個T,但是并不會讓上傳、下載此文件 耗費很多時間,傳輸的文件大小還是實際大小。

如果應急時碰到超大的elf文件,就先用strip看看體積會不會變小。

本文提到的手段沒有在真實的對抗中實踐過,僅僅是我自己的研究,歡迎有對抗經驗的讀者與我交流。


Paper 本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/1708/