淋巴发炎挂什么科| 重金属中毒喝什么解毒| 案例是什么意思| 三高可以吃什么水果| 梦见别人家拆房子是什么预兆| 心穷是什么意思| 精子什么味| 右眼跳什么意思| 仓鼠能吃什么水果| 什么是敏感肌| 健康证都查什么| 喘不上气是什么原因| 瘘管是什么意思| cfa是什么证书| 爱出者爱返福往者福来是什么意思| 多五行属性是什么| 晚上睡眠不好有什么办法可以解决| 什么是干冰| 每天喝奶茶有什么危害| 呕吐吃什么药| 职场是什么意思| 晚上9点半是什么时辰| 水克什么| 不可翻转干燥是什么意思| 紫色裤子配什么上衣| 什么不生| 黄金微针是什么| 不约什么什么| xswl是什么意思| 鬼冢虎属于什么档次| 什么王| 惟妙惟肖是什么意思| 甲状腺4b级是什么意思| 小水滴会变成什么| 黑五是什么时候| 咳嗽痰多是什么原因| 膝盖小腿酸软无力是什么原因| 安宫牛黄丸什么时候吃| 尿比重偏低是什么原因| 左耳烫代表什么预兆| 1999年属兔是什么命| 支气管扩张是什么意思| 女性感染梅毒有什么症状| 吃什么补免疫力最快| 阴虚吃什么食补最快| 男生下巴长痘痘是什么原因| 餐边柜放什么东西| 女人什么血型最聪明| 白巧克力是什么做的| 对冲是什么意思| 3月23日什么星座| 淋巴癌有什么症状| 一什么秧苗| 洗衣机不出水是什么原因| 钢琴是什么乐器种类| 肺部结节灶是什么意思啊| 拉屎是绿色的是什么原因| 乳酸偏高是什么意思| 亚急性甲状腺炎吃什么药| 参商是什么意思| msi是什么比赛| 南宁晚上有什么好玩的地方| 59岁属什么| 月经不调吃什么药效果好| 天热出汗多是什么原因| 为什么一般不检查小肠| 痣发痒是什么原因| 卵巢早衰是什么意思| 保守治疗是什么意思| 淋巴用什么药可以消除| 心脏支架后吃什么药| 四物汤是什么| 提高免疫力吃什么食物| 什么少年| 前列腺炎吃什么药好| 浅粉色配什么颜色好看| 什么应外合| 99年属什么| 哎呀是什么意思| 悉心栽培什么意思| 老是觉得口渴是什么原因引起的| mlf操作是什么意思| 三楼属于五行属什么| 怎么知道自己缺什么五行| 便秘是什么症状| 遗精吃什么药最好| 猫鼬是什么动物| 睡觉做梦多是什么原因| 打劫是什么意思| 一什么颜色| 春梦是什么意思| 引狼入室是什么意思| 农历十月是什么星座| 湿热吃什么药好| 冠心病吃什么水果| 650是什么意思| 为什么晚上不能倒垃圾| 水逆退散是什么意思| 血糖高能吃什么蔬菜| 布五行属什么| 郁郁寡欢的意思是什么| 生目念什么| 龙凤呈祥的意思是什么| 333是什么意思| 什么物流寄大件便宜| 什么人不能喝绿豆汤| 八百里加急是什么意思| 朝秦暮楚是什么生肖| 方向盘重是什么原因| tide什么意思| 口臭是什么病| 妤是什么意思| 足跟痛挂什么科| 红色的菜叫什么| 吃什么排出全身毒素| 猪肝配什么菜炒好吃| 什么产品祛斑效果最好| 什么空调| 枸杞和什么一起泡水喝最好| 前列腺在哪里男人的什么部位| 癌胚抗原是什么| pigeon是什么牌子| 梦见谈恋爱很甜蜜是什么意思| 征字五行属什么| 补气血吃什么食物最好| 紫玫瑰代表什么意思| 维生素B1有什么副作用| anxiety什么意思| 龙虾和什么不能一起吃| 木丑念什么| 兔子怕什么| 散瞳是什么意思| 药店属于什么单位性质| 甲类传染病指什么| 冷暖自知是什么意思| 李连杰为什么不娶丁岚| 金多水浊什么意思| 阴茎是什么| 尿酸高看什么科室最好| 早上7点多是什么时辰| 眼睛一直跳是什么原因| 脚趾抽筋是什么原因引起的| 438是什么意思| 芡实适合什么人吃| 尿频尿急吃什么药效果最好| 3.19是什么星座| 醋泡黑豆有什么功效| 子宫切除后要注意什么| 皮肤长小肉粒是什么原因| 鱼腥草破壁饮片有什么功效| 脚趾痒是什么原因| 脑瘤早期什么症状| 什么叫环比什么叫同比| 三个句号代表什么意思| 过期橄榄油有什么用途| 什么时候不能喷芸苔素| 子宫癌是什么症状| 蒸米饭时加什么好吃| 分水岭是什么意思| 流清鼻涕是什么原因| 多动症吃什么药| 5.11什么星座| 跑路什么意思| 承受是什么意思| 什么的孙悟空| 女人银屑病一般都长什么地方| 学位证是什么| 快乐大本营为什么停播| 憋是什么意思| 白化病是什么原因引起的| 止语是什么意思| 痔疮挂什么科室| 咖啡对身体有什么危害| 防晒霜什么牌子好| 尿少是什么原因| 溺水是什么意思| 给孩子测骨龄应该挂什么科| 八一年属什么生肖| 药品gmp是什么意思| 肝内高回声是什么意思| 煮羊肉放什么调料| 苍蝇是什么味道| 膝盖里面痛什么原因引起的| 什么食物对肝有好处| 爱是什么感觉| 总胆固醇高有什么危害| 忌口不能吃什么| 50元人民币什么时候发行的| 白癜风有什么危害| 什么是同房| 尼特族是什么意思| 什么水果榨汁好喝| 肿大淋巴结是什么意思| hpv是什么原因引起的| 脖子出汗是什么原因| smt是什么意思| 蚂蚁上树是什么意思| 事宜是什么意思| 什么食物维生素b含量高| 秉承是什么意思| 蓝风铃香水什么味道| 做颈动脉彩超挂什么科| 微信转账为什么要验证码| 缺钾吃什么食物| 不容乐观是什么意思| 降压药什么时间吃最好| 投放是什么意思| 一什么树林| 五常大米是什么意思| 哺乳期牙龈肿痛可以吃什么药| max是什么意思| 肝在人体什么位置| 脚背痒是什么原因| 淡奶是什么| 胎盘能吃吗有什么作用与功效| 香菇炒什么好吃| 空调买什么品牌的好| 乳腺癌挂什么科| 肛门瘙痒用什么药| 尿少尿黄是什么原因引起的| 肚子里面跳动是什么原因| 铜钱癣用什么药| 梦见死去的亲人是什么意思| 洁字五行属什么| 为什么会血压低| 特派员是什么级别| 淋巴结是什么东西| 小孩口腔溃疡是什么原因引起的| 高原反应什么症状| 外感风寒是什么意思| 肉蒲团是什么| 淡淡的什么| 儿童流黄鼻涕吃什么药| 豫字五行属什么| 孕早期不能吃什么| 音召念什么| 9月29是什么星座| 送命题是什么意思| 夹腿综合症是什么| 民营经济属于什么经济| 西葫芦炒什么好吃| 水命和什么命最配| 头发少是什么原因| 脉搏快是什么原因| 林彪为什么要叛逃| 蜂蜜什么人不能吃| 存款准备金率是什么意思| 血压过低有什么危害| inr是什么意思医学| 田五行属什么| al是什么意思| 补气血吃什么药效果好| 海鲜不能和什么食物一起吃| 子字属于五行属什么| 排档是什么意思| 处女座跟什么星座最配| 嗓子哑了是什么原因| 棘人是什么意思| 金字旁土念什么字| 狮子男和什么星座最配| 131是什么意思| 为什么抽血要空腹| 周岁和虚岁是什么意思| 吃什么提高免疫力| 百度

Thursday, June 26, 2014

Raising Lazarus - The 20 Year Old Bug that Went to Mars

Twenty Years Old

Mars Curiosity Rover
It's rare that you come across a bug so subtle that it can last for two decades. But, that's exactly what has happened with the Lempel-Ziv-Oberhumer (LZO) algorithm. Initially written in 1994, Markus Oberhumer designed a sophisticated and extremely efficient compression algorithm so elegant and well architected that it outperforms zlib and bzip by four or five times their decompression speed.

As a result, Markus has made a successful and well deserved career out of optimizing code for various platforms. I was impressed to find out that his LZO algorithm has gone to the planet Mars on NASA devices multiple times! Most recently, LZO has touched down on the red planet within the Mars Curiosity Rover, which just celebrated its first martian anniversary on Tuesday.

Because of the speed and efficiency of the algorithm, LZO has made its way into both proprietary and open source projects world-wide. It's has lived in automotive systems, airplanes, and other embedded systems for over a decade. The algorithm has even made its way into projects we use on a daily basis, such as OpenVPN, MPlayer2, LibavFFmpeg, the Linux kernel, Juniper Junos, and much, much, more.

In the past few years, LZO has gained traction in file systems as well. LZO can be used in the Linux kernel within btrfs, squashfs, jffs2, and ubifs. A recent variant of the algorithm, LZ4, is used for compression in ZFS for Solaris, Illumos, and FreeBSD.

LZO is even enabled in kernels for Samsung Android devices to increase kernel loading speed and improve the user experience, as noted in the Android Hacker's Handbook.

With its popularity increasing, Lempel-Ziv-Oberhumer has been rewritten by many engineering firms for both closed and open systems. These rewrites, however, have always been based on Oberhumer's core open source implementation. As a result, they all inherited a subtle integer overflow. Even LZ4 has the same exact bug, but changed very slightly.

Engineered Genetics

Code reuse is a normal part of engineering, and is something we do every day. But, it can be dangerous. By reusing code that is known to work well, especially in highly optimized algorithms, projects can become subject to vulnerabilities in what is perceived as trusted code. Auditing highly optimized algorithms is a fragile endeavor. It is very easy to break these types of algorithms. Therefore, reused code that is highly specialized is often presumed safe because of its age, its proven efficiency, and its fragility.

This creates a sort of digital DNA, a digital genetic footprint that can be traced over time. Though there are certainly many instances of proprietary variants of LZO and LZ4, the following six implementations are available in open source software


Despite each implementation of the algorithm being noticeably different, each variant is vulnerable in the exact same way. Let's take a look at a version of the algorithm that is easy to read online, the Linux kernel implementation found here

In all variants of LZ[O4], the vulnerability occurs when processing a Literal Run. This is a chunk of compressed data that isn't compressed at all. Literals are uncompressed bytes that the user decided, for whatever reason, should not be compressed. A Literal Run is signaled by a state machine in LZO, and by a Mask in LZ4.


 56                         if (likely(state == 0)) {
 57                                 if (unlikely(t == 0)) {
 58                                         while (unlikely(*ip == 0)) {
 59                                                 t += 255;
 60                                                 ip++;
 61                                                 NEED_IP(1);
 62                                         }
 63                                         t += 15 + *ip++;
 64                                 }
 65                                 t += 3;

In the above sample, the integer overflow is evident. The variable 't' is incremented by 255 every time the compression payload contains a nil byte (0x00) when a Literal Run is detected. Regardless of whether the variable 't' is signed or unsigned, 255 will be added to it. The only check is to ensure that the input buffer contains another byte. This means that 't' can accumulate until it is a very large unsigned integer. If 't' is a 32bit integer, it only takes approximately sixteen (16) megabytes of zeroes to generate a sufficiently large value for 't'. Though 't' can overflow here, this is not where the attack occurs. There is another more important overflow just below this chunk of code. 


66 copy_literal_run:
67 #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
68                                 if (likely(HAVE_IP(t + 15) && HAVE_OP(t + 15))) {
69                                         const unsigned char *ie = ip + t;
70                                         unsigned char *oe = op + t;
71                                         do {
72                                                 COPY8(op, ip);
73                                                 op += 8;
74                                                 ip += 8;
75                                                 COPY8(op, ip);
76                                                 op += 8;
77                                                 ip += 8;
78                                         } while (ip < ie);
79                                         ip = ie;
80                                         op = oe;
81                                 } else
82 #endif

Above, we see the "copy_literal_run" chunk of code. This is the section of the LZO algorithm that uses the variable 't' as a size parameter. On line 68, the code ensures that the input buffer (IP) and output buffer (OP) are large enough to contain 't' bytes. However, in the Linux kernel implementation, they pad by 15 bytes to ensure the 16 byte copy does not overflow either buffer. This is where things fail.

The macros HAVE_IP and HAVE_OP validate that 't' bytes are available in the respective buffer. But, before the macro is called, the expression (t + 15) is evaluated. If the value of 't' is large enough, this expression will cause an integer overflow. The attacker can make this expression result in a value of zero (0) through fourteen (14) by forcing 't' to equal the values -15 to -1, respectively. This means that the HAVE macros will always believe that enough space is available in both input and output buffers.

On line 70, the pointer 'oe' will now point to before the 'op' buffer, potentially pointing to memory prior to the start of the output buffer. The subsequent code will copy sixteen (16) bytes from the input pointer to the output pointer, which does nothing as these pointers should point to a "safe" location in memory. However, there are two side effects here that the attacker must abuse: lines 78 and 80.

Because 'ie' will always have an address lower in memory than 'ip', the loop is immediately broken after the first sixteen (16) byte copy. This means that the value 't' did not cause a crash in the copy loop, making this copy essentially a no-op from the attacker's point of view. Most importantly, on line 80 (and 79), the buffer pointer is set to the overflown pointer. This means that now, the output pointer points to memory outside of the bounds of the output buffer. The attacker now has the capability to corrupt memory, or at least cause a Denial of Service (DoS) by writing to an invalid memory page.

The Impact of Raising Dead Code


Each variant of the LZO and LZ4 implementation is vulnerable in slightly different ways. The attacker must construct a malicious payload to fit each particular implementation. One payload cannot be used to trigger more than a DoS on each implementation. Because of the slightly different overflow requirements, state machine subtleties, and overflow checks that must be bypassed, even a worldwide DoS is not a simple task. 


This results in completely different threats depending on the implementation of the algorithm, the underlying architecture, and the memory layout of the target application. Remote Code Execution (RCE) is possible on multiple architectures and platforms, but absolutely not all. Denial of Service is possible on most implementations, but not all. Adjacent Object Over-Write (OOW) is possible on many architectures.

Lazarus raised from the dead
Because the LZO algorithm is considered a library function, each specific implementation must be evaluated for risk, regardless of whether the algorithm used has been patched. Why? We are talking about code that has existed in the wild for two decades. The scope of this algorithm touches everything from embedded microcontrollers on the Mars Rover, mainframe operating systems, modern day desktops, and mobile phones. Engineers that have used LZO must evaluate the use case to identify whether or not the implementation is vulnerable, and in what format.

Here is a list of impact based on each library. Implementations, or use cases of each library may change the threat model enough to warrant reclassification. So, please have a variant audited by a skilled third party, such as <shameless plug>.

  • Oberhumer LZO
    • RCE: Impractical 
    • DoS: Practical
    • OOW: Practical
    • NOTE: 64bit platforms are impractical for all attacks
  • Linux kernel LZO
    • RCE: Impractical
    • DoS: Practical
    • OOW: Practical
    • NOTE: Only i386/PowerPC are impacted at this time
  • Libav LZO
    • RCE: Practical
    • DoS: Practical
    • OOW: Practical
    • NOTE: ALL ARCHITECTURES/PLATFORMS are RCE capable
  • FFmpeg LZO
    • RCE: Practical
    • DoS: Practical
    • OOW: Practical
    • NOTE: ALL ARCHITECTURES/PLATFORMS are RCE capable
  • Linux kernel LZ4
    • RCE: Practical
    • DoS: Practical
    • OOW: Practical
    • NOTE: 64bit architectures are NOT considered practical
  • LZ4
    • RCE: Practical
    • DoS: Practical
    • OOW: Practical
    • NOTE: 64bit architectures are NOT considered practical
For a bug report on each implementation, please visit the Lab Mouse Security's vulnerability site. 

How Do You Know If You're Vulnerable

Projects Using LZO/LZ4

The easiest way to identify whether your specific implementation is vulnerable is to determine the maximum chunk size that is passed to the decompress routine. If buffers of sixteen (16) megabytes or more can be passed to the LZO or LZ4 decompress routine in one call, then exploitation of the integer overflow is possible. For example, ZFS constrains buffer sizes to 128k. So, even though they use a vulnerable implementation of LZ4, an attack is not possible without a second bug to bypass the buffer size constraint. 

The second easiest way is to identify the bit size of the count variable. If the count variable (for example, named 't' in the Linux kernel code shown above) is 64bit, it would take such a massive amount of data to trigger the overflow that the attack would likely be infeasible, regardless of how much data can be passed to the vulnerable function in one call. This is due to the fact that even modern computers do not have enough RAM available to store the data required to implement such an attack. 

However, there is a specific issue with the previous check. Validate that even if the count variable is 64bit in size, the value used is still 64bit when a length value is checked. If the actual length value is truncated to 32bits, the attack will still work with only sixteen (16) megabytes of data. 

Users

All users of FFmpeg, Libav, and projects that depend on them, should consider themselves at risk to remote code execution. Period. Please update your software from the FFmpeg and Libav websites, or refrain from using these applications until your distribution has an adequate patch. 

It should be noted that certain Linux distributions package Mplayer2 with the base system by default. MPlayer2 is vulnerable to RCE "out of the box". If your distribution packages MPlayer2 by default, be sure to disable the embedded media player plugin (gecko-mediaplayer) for your browser. Firefox/Iceweasel, Chromium, Opera, Konqueror, and other Linux-based browsers are vulnerable to RCE regardless of the platform/architecture when an MPlayer2 plugin is enabled. 

Vendor Status

Lab Mouse has reached out to and worked with each vendor of the vulnerable algorithm. As of today, June 26th, 2014, all LZO vendors have patches either available online, or will later today. Please update as soon as possible to minimize the existing threat surface.

In the near future, Lab Mouse will publish a more technical blog on why and how RCE is possible using this bug. We consider that information to be imperative for both auditors and engineers, as it assists in identifying, classifying, and prioritizing a threat. However, that report will be released once the patches have been widely distributed for a sufficient amount of time.

For more information, please visit our contact page. We are more than happy to help your team with their use case, or implementation of these algorithms.

Summary

Overall, this is how this bug release breaks down.

  • Vendors have patches ready or released
  • Distributions have been notified 
  • Vendors of proprietary variants have been notified (where they could be found)
  • All bug reports can be found here
  • RCE is not only possible but practical on all Libav/FFmpeg based projects
  • All others are likely impractical to RCE, but still possible given a sufficiently skilled attacker


It is always exciting to uncover a vulnerability as subtle as this issue, especially one that has persisted and propagated for two decades. But, it makes me pause and consider the way we look at engineering as a model.

Speed and efficiency are imperatives for modern projects. We're building technology that touches our lives like never before. I know that most engineers strive to build not only elegant, but safe code. But, we still see security as a disparate discipline from engineering. Security and engineering could not be more tightly bound. Without engineering, you can't provide security to users. Without security, engineering cannot provide a stable and provable platform.

Neil deGrasse Tyson famously claimed, God is in the gaps. There is a similar issue in engineering. The individual often sees stability where the individual doesn't have expertise. Our God is the algorithm. We "bless" certain pieces of code because we don't have the time or knowledge to evaluate it. When we, as engineers and analysts, take that perspective, we are doing a disservice to the people that use our projects and services.

Often the best eyes are fresh or untrained eyes. The more we stop telling ourselves to step over the gaps in our code bases, the more holes we'll be able to fill. All it takes is one set of eyes to find a vulnerability, there is no level of expertise required to look and ask questions. Just look. Maybe you'll find the next 20 year old vulnerability.

Thanks

I'd like to thank the following people for their great assistance patching, coordinating, and advising on this issue:

  • Greg Kroah-Hartman (Linux)
  • Linus Torvalds (Linux)
  • Kees Cook (Google)
  • Xin LI (FreeBSD)
  • Michael Niedermayer (FFmpeg)
  • Luca Barbato (Libav/Gentoo)
  • Markus Oberhumer
  • Christopher J. Dorros (NASA MSL)
  • Dan McDonald (Omniti)
  • Yves-Alexis Perez (Debian)
  • Kurt Seifried (Red Hat)
  • Willy Tarreau (Linux)
  • Solar Designer (Openwall)
  • The US-CERT team
  • The Oracle security team
  • The GE security team
  • Kelly Jackson Higgins (UBM)
  • Steve Ragan (IDG Enterprise)
  • Elinor Mills

Feeling Guilty?

Are you reading this post, thinking about all the administrators and engineers that are going to have to patch the LZO/LZ4 issue in your team's systems? Take some time to tell them how you feel with our hand crafted Lab Mouse Security custom Sympathy Card!

Hand crafted with the finest bits and bytes, our Sympathy Card shows your engineer what they mean to you and your team. This is a limited run of cards, and will proudly display the Linux kernel LZO exploit written by Lab Mouse on the card.

Best wishes,
Don A. Bailey
Founder / CEO
@InfoSecMouse
Lab Mouse Security
June 26th, 2014

1 comment:

  1. 20 years ago, such defects were not considered threats because the code works as expected for all valid scenarios. I assume that you can hack the compressed stream in other ways and trigger other defects.
    The general statement should probably be that if you have code that's been written more than 15 years ago, it probably has multiple vulnerabilities by today's standards. Start reviewing...

    ReplyDelete

外阴萎缩是什么症状 什么时候进伏 人参泡酒有什么功效和作用 归来是什么意思 舌头发麻是什么原因
灵芝孢子粉有什么用 女人下嘴唇厚代表什么 女性吃什么改善更年期 立春是什么生肖 子宫增厚是什么原因
血压低压高吃什么药 pcr检测是什么 没字去掉三点水念什么 2006属什么 腹股沟黑是什么原因
烟酰胺是什么东西 唐氏宝宝是什么意思 hyq什么意思 因人而异是什么意思 乳腺ca是什么意思
什么心什么气hcv9jop5ns9r.cn 什么病需要做透析hcv8jop2ns0r.cn 紫苏叶有什么功效hcv8jop5ns2r.cn 嘴唇淡紫色是什么原因hcv8jop1ns2r.cn 5月5号什么星座hcv8jop0ns4r.cn
肝火旺有什么症状hcv8jop6ns9r.cn BS是什么意思啊cj623037.com 免冠照什么意思hcv9jop3ns9r.cn 子时是什么时间hcv9jop2ns8r.cn d二聚体是查什么的hcv9jop3ns9r.cn
神采什么什么xinjiangjialails.com 芝士是什么味道hcv7jop9ns1r.cn 医生助理是做什么的hcv8jop4ns9r.cn 哭夫痣是什么意思naasee.com 宝宝干呕是什么原因hcv7jop5ns6r.cn
龄字五行属什么hcv9jop5ns7r.cn theme什么意思hcv8jop4ns4r.cn 什么病需要做手术helloaicloud.com 腹胀是什么原因引起的beikeqingting.com 眦是什么意思hcv8jop1ns1r.cn
百度