1. Trang chủ
  2. » Công Nghệ Thông Tin

Examination of Datagram Fields III

72 231 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Examination of datagram fields iii
Tác giả Judy Novak
Trường học Johns Hopkins University Applied Physics Laboratory
Chuyên ngành Network Traffic Analysis
Thể loại thesis
Năm xuất bản 2001
Thành phố laurel
Định dạng
Số trang 72
Dung lượng 387,88 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

For each new sending connection that the host attempts that is not a retry, a different ephemeral port should be selected... 7 Sequence Numbers • 32-bit number that uniquely identifies t

Trang 1

Examination of Datagram Fields III

All material Copyright  Novak, 2000, 2001 All rights reserved

Trang 3

options (if any)

data (if any)

16-bit source port number 16-bit destination port number

32-bit sequence number

32-bit acknowledgement number

4-bit

header

length

reserved (6-bits)

U A P R S F

R C S S Y I

G K H T N N

16-bit window size

16-bit checksum 16-bit urgent pointer

This page intentionally left blank

Trang 4

Initial source port ephemeral range > 1023

Multiple connections attempted, source ports

should change

The port fields are two separate 16-bit fields in the TCP header, one for source and another for destination ports The valid range of values is between 1 and 65535; the use of port 0 is typically a

“signature” of some sort

When a source host wishes to connect to a destination host, an ephemeral port is typically selected in the range of ports greater than 1023 For each new sending connection that the host attempts that is not a retry, a different ephemeral port should be selected

Trang 5

incrementing in the ephemeral port range.

Trang 6

6

Destination Port Mutation

hping2 –S sparky

09:44:13.882207 verbo.1788 > sparky 0 : S 1553132317:1553132317(0) win 512

09:44:14.876837 verbo.1789 > sparky 0 : S 1894028093:1894028093(0) win 512

09:44:15.876836 verbo.1790 > sparky 0 : S 2032501562:2032501562(0) win 512

09:44:16.876832 verbo.1791 > sparky 0 : S 851202745:851202745(0) win 512

09:44:17.876843 verbo.1792 > sparky 0 : S 1659659021:1659659021(0) win 512

09:44:18.876836 verbo.1793 > sparky 0 : S 731953738:731953738(0) win 512

Now, look at the default behavior that hping2 exhibits doing a SYN scan It increments the source port as we expect, however it uses destination port 0 as its default target The intent of this type of scan obviously is not to find a listening port This type of scan would be used to elicit a RESET response to see if a host is alive and in so doing perhaps examine other traits of the responding datagram

Trang 7

7

Sequence Numbers

32-bit number that uniquely identifies the initial

byte of segment data

Should change for each new (non-retry) TCP

segment sent

Initial sequence number (ISN) represents first

sequence number in TCP exchange

ISN used to fingerprint operating system

The TCP sequence numbers are used to uniquely identify the beginning byte of each TCP segment that is sent This is a way to keep track of all the TCP data that is sent and all that is received in a TCP stream Most times, there is more TCP data than can be sent with one TCP segment Since TCP is a connection-oriented, reliable protocol, we have to have a mechanism to account for data being sent and received In part, that is done using TCP sequence numbers

These sequence numbers should not be repeated unless there is a retry of the same connection The initial sequence number (ISN) is the first sequence number that is used in the TCP exchange between the sending hosts Each host in the exchange selects a unique initial sequence number when sending the initial SYN connection to the other host

The formula that hosts use to select their initial sequence number is examined by nmap to help fingerprint the operating system There is a file that comes with nmap, nmap-os-fingerprints, that has a list of different operating systems Given a set of tests that will be executed by nmap against a target host, if the received values exactly match the ones listed for the OS, it is classified as that particular OS

The first test executed by an OS fingerprinting nmap scan is one that examines the initial sequence numbers generated from sending connections to a listening port Different TCP/IP stacks use different formulas to generate the ISN Some of the older operating systems used a predictable increment for each new connection, but someone watching and sniffing could hijack a connection using this information as was done in the infamous Mitnick attack Other operating systems have a time-dependent formula that predictably increases the ISN based on a given time change

Trang 8

8

Sequence Number Prediction

nmap –O win98

Port State Service

139/tcp open netbios-ssn

TCP Sequence Prediction: Class=trivial time dependency

Difficulty=1 (Trivial joke)

Remote operating system guess: Windows NT4 / Win95 / Win98

Using nmap to scan the host win98 and identify the operating system using the –O option, it

discovers that the generation of initial sequence numbers is based on a formula using a “trivial time dependency” And, it reports that predicting a new TCP sequence number would be a “trivial joke”

Windows NT, Windows 95 and Windows 98 all use this same formula The best type of formula for generating unpredictable sequence numbers is one that is truly random which is what operating systems such as Linux 2.0 kernels use

Trang 10

received sequence number + 1)

07:48:09.134305 verbo.62638 > win98.netbios-ssn: S 3742735770:3742735770(0) win 2048

07:48:09.134515 win98.netbios-ssn > verbo.62638: S 3982854:3982854(0) ack

3742735771 win 8576 <mss 1460> (DF)

The method that TCP uses to ensure that data is received is via an acknowledgement This is done using the acknowledgement number which is a validation that the receiving host did indeed get the data The acknowledgement number sent by the receiving host actually represents the next expected sequence number

Because a SYN connection consumes one sequence number, and since the acknowledgement value

is one more than this sequence number, a valid acknowledgement number must be greater than 0.nmap can attempt to identify live hosts by sending a remote host a TCP connection with an

unsolicited ACK flag set The desired response to this is a RESET from the remote host which indeed indicates that the remote host is alive regardless of whether the scanned port is listening or not Current versions of nmap have a telltale signature because the ACK flag is set, yet the

acknowledgement number is 0

Above the sending host verbo, has an initial sequence number of 3742735770 The receiving host, win98, acknowledges this by indicating that the next sequence number it expects to receive is

374173577

Trang 11

11

TCP Flags

Tell the state of a given TCP segment

SYN – session establishment

FIN – session termination

RST – session abort

ACK – acknowledgement of received data

PUSH – send data

URG – send data with higher priority

Valid flag combinations

Invalid flag combinations

Done for detection evasion purposes

Mapping

Port scanning

Done for OS fingerprinting

Manifestation of packet corruption

TCP flags are used to indicate the state of a given TCP connection or session The SYN flag starts the session and the FIN flag terminates a session gracefully A RESET is used to abort a session The ACK flag is set to indicate an acknowledgement of data by the receiver The ACK flag is set on all connections after the initial SYN The PUSH flag is typically used to tell the sending host to write all of its buffered data to send to the destination host It is possible to send data without the PUSH flag set Finally, the URGENT flag is used to indicate that this data has the highest priority, for instance an interrupt by a CNTL-C to abort the current process and data exchange would require higher priority

The TCP flags have many different valid combinations And, there are many different invalid combinations that are used for different purposes Early on in the evolution of IDS’s, many would examine traffic for initial SYN attempts only Scanners realized this and would send a SYN/FIN combination that might elicit a response from a host Different OS TCP/IP stacks respond

differently to mutant flag settings so this is used to attempt to fingerprint the operating system Finally, just because you see mutant TCP flag combinations, it is not an indication of malicious behavior Packets can and do get corrupted and it is possible for TCP flags to be unnaturally set after some kind of corruption

Trang 12

12

TCP Byte Reserved Bits

URG ACK PSH RST SYN FIN Reserved

Unused: If set, possible indication of OS mapping

Until very recently, the two high-order bits of the TCP byte were known as the reserved bits They had no purpose and the value found in the bits should be 0 However, when tools such as Queso and nmap came along, it was discovered that these bits could be used to try to help fingerprint a remote system’s operating system Different operating system TCP/IP stacks would respond uniquely when these bits were set

Some would reset the bits to 0 and others would simply leave them with the current value Hence, some categorizations could be made of the remote host’s operating system TCP/IP stack This alone would not be enough to inform the scanner of the operating system, but used in conjunction with several other tests, the operating system could be conjectured with a high probability

Trang 13

13

Explicit Congestion Notification (ECN)

URG ACK PSH RST SYN FIN

Well, how exactly does that occur? Currently as discussed in the ECN RFC 2481, the only transport capable of reacting to that congestion notification is TCP So, TCP has to be prepared to deal with this The RFC suggests using the two high-order bits of the TCP flag byte as fields for ECN The bit to the right

of the high-order bit will be known as the ECN-echo bit This bit will be turned on when TCP receives a packet that has the TOS ECN-capable bit and the Congestion Experienced bits both set in the IP header This assumes that both end-points of the TCP conversation are ECN capable and that is determined during the three-way handshake

If TCP sets the ECN-echo bit, the purpose is to inform the sender to reduce the rate at which it is sending data because there is congestion between the sender and receiver Upon receipt of a TCP segment with the ECN-echo bit set, the sender will reduce its congestion window (loosely speaking – the size of the sending buffer) by half Once it reacts in this manner, it will turn on the Congestion Window Reduced (CWR) bit

to inform the other side of the conversation that remedial action to reduce congestion has occurred This bit is found in the high-order bit of the TCP byte flag

While this mechanism will help reduce the number of packets dropped, it is anticipated that many IDS’s that exist, will begin to alarm on these new TCP flag bytes being used Right now, most uses of these bits are for scanning purposes only Also, some packet-filtering devices will not allow in TCP segments with these bits set So, much customization will have to be done to smoothly introduce ECN

Trang 14

14

ECN Detection With

tcpdump 3.5

nmap –O sparky

verbo.60608 > sparky.discard: S [ ECN-Echo ]

1981655162:1981655162(0) win 2048 <wscale 10,nop,mss

R R A U P R S F R S TCP Flag Byte = 0x42

If this were an actual case of true ECN flag setting, the packet would have to have a non-zero Type

of Service (TOS) value Remember, that in order for ECN to be used for TCP talkers, the two hosts had to be ECN-capable This was signaled via the TOS bit that was to the left of the low-order bit

In other words, the TOS value would be a 0x02 So you begin to see the problem that packet capturing software and intrusion detection systems face; they must distinguish actual ECN traffic from fingerprinting traffic To date, this doesn’t appear to be happening

Trang 15

15

Filter Writing Exercise

URG ACK PSH RST SYN FIN Reserved

What would the tcpdump filter be to determine if

either/both of the TCP flag reserved bits is set?

Since it can be quite informative to know when a record has one or both of the TCP reserved bits set,

it would behoove us to have a tcpdump filter that would extract such records As a hint, you might want to try to use the greater than (>) sign to discover if one or both bits are set

Trang 16

We then take this filter and AND it with the value found in tcp[13] and look for a non-zero result.

Alternatively, we can use the greater than sign to try to see if we have a non-zero value in the order bits Thus if we turn on all the 6 low-order bits, we have a value of 0x3f This can also be expressed in decimal as 63

Trang 17

17

Sample Mutant Flags

nmap –O win98

nmap –O linux

20:44:50.370158 verbo.42318 > linux.ftp: SFP 1749165064:1749165064(0) win

1024 urg 0 <wscale 10,nop,mss 265,timestamp 1061109567 0,eol>

When nmap is placed in OS fingerprinting mode with the –O option, it will send some mutant flag combinations when an open port is discovered The mutant combination of SYN/FIN/PUSH is sent

to the Windows port 139 and amazingly enough it responds with an acknowledgement! When the same technique is attempted on a Solaris and Linux host, there is no response from the listening ports, which is the behavior that would conform to RFC specifications

Trang 18

18

TCP Connection Retries

Repeated attempt to connect to TCP port

If no RESET received, connection attempted

again

Destination host down, no ICMP message sent

Packet-filtering device silently dropping

RESET sent, but host doesn’t receive it

Number of additional retries sent - operating

system dependent

Will finally give up connection attempt

What if a TCP connection is attempted, yet the host attempting the connection doesn’t receive a response from the destination host? A destination host might not respond because it may not be up

or may not exist A router may deliver an ICMP message about the destination host being

unreachable, but if the router has been silenced from delivering unreachable messages, the sending host will never know that there is a problem A destination host might be sitting behind some kind of packet filtering device that blocks the connection inbound, yet silently drops the connection without informing the sending host It is also possible that the destination host responds positively

(SYN/ACK) or negatively (RESET/ACK), yet for some reason the sending host doesn’t receive these replies

Additional attempts will be made to contact the host in situations like this The number of attempts and the time intervals in which they are attempted varies by operating system Eventually, the sending host will cease the connection attempts

Trang 19

19

TCP Retries

Which set is a retry?

16:03:40.763603 my.net.39344 > your.net.6000: S 523285584:523285584(0) win

Trang 20

20

Multiple Different Connections

16:03:40.763603 my.net 39344 > your.net.6000: S 523285584:523285584 (0) win

source ports change sequence numbers change

The first set was the multiple different connections output Let’s examine how we know this

First of all, the source ports change; this is indicative of different connection attempts Second, the TCP sequence numbers also change, also indicative of different connection attempts So, these are unique connections from the same host to the the same destination host and port These may have been successful or not, we are looking at the SYN connections only in this output We would have

to examine all the traffic from the connection to determine if the connection were successful

Trang 21

source ports same sequence numbers same

The second set of connections was the series of retries The source ports remain the same and the TCP sequence numbers don’t change This is not a fail-safe detection method – it is also possible that the sender is crafting packets that use the same source ports and TCP sequence numbers

Trang 22

3 second time delta

6 second time delta

12 second time delta

Examining the set of retries a bit more – look at the time changes and the IP identification number changes above The IP identification numbers should change on a retry as well as a set of unique connections The sending host sends an entirely new datagram for the retry so the IP identification number should increment (or wrap)

Now, look at the time changes between attempted retries Between the first and second connection attempts the wait is approximately 3 seconds This doubles to 6 seconds between the second and third And, finally, this doubles again to 12 seconds between the third and fourth attempts This doubling of the backoff time might not always be seen – different operating systems use different time-retry algorithms for the subsequent retries

Trang 23

~.5 second time delta

~.5 second time delta

~.5 second time delta

This is another set of retries, but the time interval at which each new attempt is made is fairly constant at about half a second This seems to make less sense than the previous backoff algorithm

By doubling the time between retries, if the destination host is suffering some kind of temporary problem, it may respond if we continue to wait This algorithm has a more insistent approach of not really waiting much time at all before attempting a retry

Trang 24

24

TCP Options

Included at the end of TCP header

data sent to another host

window receive buffers to be > 65535

segments to be acknowledged

TCP options are optional parameters that can specify different behavior than the default These are included at the end of the TCP header The MSS can be sent on the SYN only and it represents the largest TCP payload that a host will send Remember that the total IP datagram will be at least 40 bytes more than this accounting for the IP header and the TCP header This is set once and not readjusted like the window size The optimum value for this is very close to the MTU – 40 This doesn’t account for header options, though If an MSS value is not announced, the communicating host will assume that it is 536 bytes The reason this is used is to inform the remote host of the number of the maximum number of bytes to send to avoid fragmentation

The window scale is a way to allow a receiving TCP buffer to be larger than the 16 bit maximum value of 65,535 There is a multiplicative factor applied to the window size to make it larger The timestamp is a mechanism to time and compute round trip time for TCP exchanges This is used to compute the

retransmission timer that helps recover from packet loss The timestamp can also be used to make sure a reused and old sequence number does not accidentally get included with a current exchange

A newer option is the selective acknowledgement Both sending and receiving hosts have to support this option for it to be used If selective acknowledgement is not used a host can only acknowledge the last chronological sequence number it received In other words, if a TCP segment is either lost or late in arriving, subsequent arriving segments cannot be acknowledged The selective acknowledgement allows for all received segments to be acknowledged

A couple of TCP non-options are supplied to pad the options to the required 4-byte boundaries The byte NOP can be used to pad in the middle of the options list, and the 1-byte eol option is used to pad and indicate the end of options

1-Finally, TCP options have to be perfectly formatted or they will be rejected by the end-host This represents another possible insertion attack if the NID doesn’t properly examine them

Trang 25

2262117253 win 8760 < mss 1460,nop,nop,sackOK > (DF)

nmap –O sparky

13:58:18.387461 verbo.1565 > sparky.ftp: S 2115515674:2115515674(0) win

The Windows host response to the options appears to indicate that it doesn’t support the timestamp

or wscale option The Solaris host responds to the options probe and appears to support all the options However, it reorders them giving additional classification clues away

Trang 26

Acts as flow control

Window size dynamically changes as data is

received

Window size of 0 tells sending host to

temporarily cease sending data

When host can receive additional data, window

size increases to greater than 0

Initial window size can be used for OS

fingerprinting

The TCP window size is the way a receiving host informs the sending host the buffer size for data sent for that connection This is a flow control mechanism because it is dynamic The window size becomes smaller for all data that has been received but not yet processed by the receiving host If the receiving buffer ever becomes full, the window size becomes 0 informing the sending host not to send any more data Once the receiving host has processed some of the data in the buffer, it will send a window size update to the sending host to inform it to resume sending data

Initial window sizes are used by nmap to determine the operating system Different operating systems select different initial window sizes and this is used to help fingerprint the OS

Trang 27

27

Dynamic Window Size

12:59:21.302481 win98.1090 > sambaserver.21: ack 1 win 8760 (DF)

12:59:21.313179 sambaserver.21 > win98.1090: P 1:81(80) ack 1 win 32120 (DF) 12:59:21.421038 win98.1090 > sambaserver.21: ack 81 win 8680 (DF)

12:59:23.885149 win98.1090 > sambaserver.21: P 1:14(13) ack 81 win 8680 (DF) 12:59:23.885458 sambaserver.21 > win98.1090: ack 14 win 32120 (DF)

12:59:23.886251 sambaserver.21 > win98.1090: P 81:116(35) ack 14 win 32120 (DF)

12:59:24.022024 win98.1090 > sambaserver.21: ack 116 win 8645 (DF)

12:59:25.684119 win98.1090 > sambaserver.21: P 14:29(15) ack 116 win 8645 (DF) 12:59:25.695559 sambaserver.21 > win98.1090: P 116:144(28) ack 29 win 32120

(DF) [tos 0x10]

12:59:25.821992 win98.1090 > sambaserver.21: ack 144 win 8617 (DF)

12:59:26.729110 win98.1090 > sambaserver.21: P 29:35(6) ack 144 win 8617 (DF)

Let’s examine the middle of a session between a Linux host known as sambaserver and a Windows

98 host We come in right after the 3-way handshake We see that that the Windows host has a window size of 8760 and the Linux host has a window size of 32120 On the second line, the Linux host sends the Windows host 80 bytes of data On the next line, you see the acknowledgement of receipt of this data, but you also see the Windows host window size decrease by 80 bytes, to 8680 This means that this data was received, but has yet to be processed by the Windows host The Windows host then sends 13 bytes of data back to the Linux host

The Linux host acknowledges receipt of this data, but its window size doesn’t decrease; it processed the data immediately The remainder of the session is very similar Data is pushed back and forth; the Linux host appears to process what it receives immediately because we see no change in the window size But the Windows host appears to be waiting for some type of trigger to push the data

to the TCP stack since it continues to decrement the window size for the received data

Trang 28

28

Data Sent on SYN

Normally, 0 bytes of data sent on initial SYN connection

client.com.38060 > server.com.telnet: S 3774957990:3774957990( 0 ) win 8760

<mss 1460> (DF)

• Data not supposed to be sent until after completion of

3-way handshake

• What would be the purpose of sending data on SYN?

Round-trip time measurement

Trang 29

In order to get a more accurate measurement or one that is likely to simulate an average web transfer, 64 bytes of zero-data/padding are sent This activity is not considered malicious, but it is definitely considered invasive It sets off many IDS – no wonder, TCP port 53 is generally regarded

as the port through which zone transfers are done

Trang 30

30

Evade Analysis

data after 3-way handshake?

If an IDS does not take this into account, it is possible that this data might go unrecognized and unanalyzed In the record above, 8 data bytes get sent on the SYN Depending on the behavior of both the NID and the destination host, this can be either an insertion or evasion attack If for some reason the end host’s TCP/IP stack does not include the data from the SYN connection in the stream, yet the NID does, this will be an insertion attack of the NID On the other hand, if the end-host accepts it, yet the NID rejects it, it will be an evasion attack of the NID

hping2 was used to generate this output The options used are –a to spoof the source IP, –p to send it

to destination port 21, -S to send a SYN, and –d to send 8 bytes of data to destination IP 10.10.10.10

Trang 32

32

UDP Header

0 15 16 3116-bit source port number 16-bit destination port number

16-bit UDP length 16-bit UDP checksum

data (if any)

This page intentionally left blank

Trang 33

Initial source port ephemeral range > 1023

Multiple connections attempted, source ports

should change

Just as with TCP ports, UDP port fields are two separate 16-bit fields in the TCP header, one for source and another for destination ports The valid range of values is between 1 and 65535; the use

of port 0 is typically a “signature” of some sort

When a source host wishes to connect to a destination host, an ephemeral port is typically selected in the range of ports greater than 1023 For each new sending connection that the host attempts that is not a retry, a different ephemeral port should be selected

Trang 34

34

UDP Port Scanning

Connection to listening UDP port does not elicit

positive response

Scan by eliciting negative response ICMP “port

unreachable”

Problems with this scan method – lack of

response can be confused with open port

Dropped packets from scanner to target

Sites might block outbound ICMP messages

Site blocks inbound UDP and blocks outbound

ICMP

Unlike TCP that responds with either a positive connection (SYN/ACK) to a listening port or a negative connection to a non-listening port (RESET/ACK), UDP doesn’t respond to an initial connection with any positive feedback unless you are at the application layer But, a live host will respond with a negative response of ICMP “port unreachable” to a non-listening port This is typically how scanners determine if the UDP port is listening or not

So, the absence of a negative response is construed as an open port What if the scanning datagram got dropped on its way to the target host? Or what if the target host responds with a port unreachable message, but the site blocks outbound ICMP messages? Or what if the site blocks inbound UDP and blocks outbound all ICMP or ICMP unreachable messages so that the scanner cannot receive an ICMP “admin prohibited” message to know this This can be misconstrued as a listening port nmap scans the same UDP ports many times to try to deal with the case of dropped packets If one packet

is dropped and the network is not under duress or having problems, chances are one of the repeated packets will not be dropped

Trang 35

35

UDP Port Scan

nmap –sU sparky –p 32770-34000

WARNING: -sU is now UDP scan for TCP FIN scan use -sF

Starting nmap V 2.12 by Fyodor (fyodor@dhp.com, www.insecure.org/nmap/) Interesting ports on sparky (1.1.1.100):

Port State Protocol Service

32771 open udp unknown

32772 open udp unknown

32773 open udp unknown

32774 open udp unknown

32782 open udp unknown

32783 open udp unknown

32784 open udp unknown

32785 open udp unknown

32786 open udp unknown

32797 open udp unknown

This is a UDP port scan in the 32700 - 34000 range to look for open Remote Procedure Call (RPC) ports on a Solaris host nmap found many of these ports open It assumes that a port is open if no

“port unreachable” message was returned, which as we’ve discussed is not necessarily true

Trang 36

36

tcpdump Output From Scan

07:09:08.286810 verbo.62865 > sparky.32787: udp 0

07:09:08.286847 verbo.62865 > sparky.32775: udp 0

07:09:08.286878 verbo.62865 > sparky.32788: udp 0

07:09:08.286924 verbo.62865 > sparky.32789: udp 0

07:09:08.286969 verbo.62865 > sparky.32791: udp 0

07:09:08.287000 verbo.62865 > sparky.32799: udp 0

07:09:08.287046 verbo.62865 > sparky.32774: udp 0

07:09:08.287094 verbo.62865 > sparky.32781: udp 0

07:09:08.287162 verbo.62865 > sparky.32772: udp 0

07:09:08.287229 verbo.62865 > sparky.32789: udp 0

07:09:08.287296 verbo.62865 > sparky.32800: udp 0

07:09:08.287793 sparky > verbo: icmp: sparky udp port 32788 unreachable (DF)

07:09:08.977544 sparky > verbo: icmp: sparky udp port 32791 unreachable (DF)

07:09:09.657361 sparky > verbo: icmp: sparky udp port 32781 unreachable (DF)

07:09:10.157301 sparky > verbo: icmp: sparky udp port 32787 unreachable (DF)

07:09:10.817315 sparky > verbo: icmp: sparky udp port 32789 unreachable (DF)

This is an excerpt of the results of the nmap scan What this fails to show are the repeated port scans

of the same port But, all the ports were scanned multiple times Ports that were not listening responded with port unreachable messages All other ports were assumed to be open

Ngày đăng: 04/11/2013, 13:15

TỪ KHÓA LIÊN QUAN

w