mirror of
https://github.com/fdiskyou/Zines.git
synced 2025-03-09 00:00:00 +01:00
1193 lines
52 KiB
Text
1193 lines
52 KiB
Text
![]() |
==Phrack Inc.==
|
||
|
|
||
|
Volume 0x0b, Issue 0x3e, Phile #0x03 of 0x10
|
||
|
|
||
|
|=-----------------------------------------------------------------------=|
|
||
|
|=---------------------=[ L I N E N O I S E ]=---------------------------=|
|
||
|
|=-----------------------------------------------------------------------=|
|
||
|
|
||
|
1 - Mistakes in the RFC Guidelines on DNS Spoofing Attacks
|
||
|
2 - Injecting Signals by Shaun
|
||
|
3 - Pirating A Radio Station
|
||
|
|
||
|
|
||
|
|=------=[ The Impact of RFC Guidelines on DNS Spoofing Attacks ]=------=|
|
||
|
by have2Banonymous
|
||
|
|
||
|
|
||
|
--[ Contents
|
||
|
|
||
|
|
||
|
1 - Executive Summary
|
||
|
2 - Overview of Basic DNS Spoofing Attacks
|
||
|
3 - Proposed Criteria for DNS Reply Acceptance
|
||
|
4 - Impact of RFC Guidelines on DNS Reply Acceptance Criteria
|
||
|
5 - Example DNS Spoofing Attack
|
||
|
6 - Practical Impact of RFC Guidelines on DNS Spoofing Attacks
|
||
|
7 - Implementation Comparison
|
||
|
8 - Conclusion
|
||
|
|
||
|
|
||
|
--[ 1 - Executive Summary
|
||
|
|
||
|
|
||
|
This article provides a brief overview of basic Domain Name System (DNS)
|
||
|
spoofing attacks against DNS client resolvers. Technical challenges are
|
||
|
proposed that should help to both identify attempted attacks and prevent
|
||
|
them from being successful. Relevant Request for Comments (RFC)
|
||
|
guidelines, used by programmers to help ensure their DNS resolver code
|
||
|
meets specifications, are reviewed. This results in the realisation that
|
||
|
the RFC guidelines are not adequately specific or forceful to help
|
||
|
identify or prevent DNS spoofing attacks against DNS client resolvers.
|
||
|
Furthermore, the RFC guidelines actually simplify such attacks to a level
|
||
|
that has not previously been discussed in the public domain until now.
|
||
|
|
||
|
To highlight the consequences of merely conforming to the RFC guidelines
|
||
|
without considering security ramifications, an example DNS spoofing attack
|
||
|
against the DNS resolver in Microsoft Windows XP is provided. This
|
||
|
illustrates serious weaknesses in the Windows XP DNS resolver client
|
||
|
implementation. For example, Windows XP will accept a DNS reply as being
|
||
|
valid without performing a thorough check that the DNS reply actually
|
||
|
matches the DNS request. This allows an attacker to create malicious
|
||
|
generic DNS replies that only need to meet a couple of criteria with
|
||
|
predictable values in order to be accepted as a valid DNS reply by the
|
||
|
targeted user.
|
||
|
|
||
|
This article discusses the practical impact of the issues raised, such as
|
||
|
the ability to perform a successful and reasonably undetectable DNS
|
||
|
spoofing attack against a large target base of Windows XP users, without
|
||
|
the attacker requiring knowledge of the DNS requests issued by the
|
||
|
targeted users. Finally, a comparison with the DNS resolver in Debian
|
||
|
Linux is supplied.
|
||
|
|
||
|
|
||
|
|
||
|
--[ 2 - Overview of Basic DNS Spoofing Attacks
|
||
|
|
||
|
|
||
|
When a user types the web site name www.somewebsite.org into their web
|
||
|
browser, their computer issues a DNS request to their Internet Service
|
||
|
Provider's (ISP) DNS server to resolve the web site name to an IP address.
|
||
|
An attacker may attempt to subvert this process by sending the user a DNS
|
||
|
reply containing an incorrect IP address, resulting in the user's computer
|
||
|
connecting to a computer of the attacker's choice instead of the desired
|
||
|
web site.
|
||
|
|
||
|
|
||
|
|
||
|
--[ 3 - Proposed Criteria for DNS Reply Acceptance
|
||
|
|
||
|
|
||
|
RFC 2535 (Domain Name System Security Extensions) otherwise known as
|
||
|
DNSSEC discusses how cryptographic digital signatures can be used to
|
||
|
authenticate DNS transactions to help mitigate DNS spoofing attacks.
|
||
|
However, the adoption of this technology has been extremely slow. Even
|
||
|
without this level of security, it would initially appear that a DNS
|
||
|
spoofing attack against a DNS client resolver would be challenging to
|
||
|
perform. This challenge results from the following proposed criteria of
|
||
|
the DNS reply that must be met for it to be accepted by the computer
|
||
|
performing the DNS lookup.
|
||
|
|
||
|
Proposed criteria of a DNS reply for it to be accepted:
|
||
|
|
||
|
1) The source IP address must match the IP address that the DNS request
|
||
|
was sent to.
|
||
|
|
||
|
2) The destination IP address must match the IP address that the DNS
|
||
|
request was sent from.
|
||
|
|
||
|
3) The source port number must match the port number that the DNS request
|
||
|
was sent to.
|
||
|
|
||
|
4) The destination port number must match the port number that the DNS
|
||
|
request was sent from.
|
||
|
|
||
|
5) The UDP checksum must be correctly calculated. This may require the
|
||
|
attacker to spend more time and effort per attack, although some packet
|
||
|
generation utilities have the ability to automatically calculate this
|
||
|
value.
|
||
|
|
||
|
6) The transaction ID must match the transaction ID in the DNS request.
|
||
|
|
||
|
7) The domain name in the question section must match the domain name in
|
||
|
the question section of the DNS request.
|
||
|
|
||
|
8) The domain name in the answer section must match the domain name in the
|
||
|
question section of the DNS request.
|
||
|
|
||
|
9) The requesting computer must receive the attacker's DNS reply before it
|
||
|
receives the legitimate DNS reply.
|
||
|
|
||
|
|
||
|
|
||
|
--[ 4 - Impact of RFC Guidelines on DNS Reply Acceptance Criteria
|
||
|
|
||
|
|
||
|
According to the RFC guidelines, it is not necessary for all of these
|
||
|
criteria to be met in order for a DNS reply to be accepted. Specifically,
|
||
|
criteria 1, 2, 3, 5, 7 and 8 do not have to be met, while criteria 4, 6
|
||
|
and 9 must be met. The following is a devil's advocate interpretation of
|
||
|
the RFC guidelines and a detailed discussion of their effect on each
|
||
|
criteria.
|
||
|
|
||
|
Criteria 1 (source IP address) does not have to be met according to RFC
|
||
|
791 (Internet Protocol) which states that "In general, an implementation
|
||
|
must be conservative in its sending behavior, and liberal in its receiving
|
||
|
behavior. That is, it must be careful to send well-formed datagrams, but
|
||
|
must accept any datagram that it can interpret (e.g., not object to
|
||
|
technical errors where the meaning is still clear)". RFC 1035 (Domain
|
||
|
names - implementation and specification) states that "Some name servers
|
||
|
send their responses from different addresses than the one used to receive
|
||
|
the query. That is, a resolver cannot rely that a response will come from
|
||
|
the same address which it sent the corresponding query to". The source IP
|
||
|
address can therefore be set to an arbitrary IP address. Regardless, if
|
||
|
desired, the attacker can set the source IP address of their DNS replies
|
||
|
to that of the targeted user's DNS server. This is especially easy if the
|
||
|
targeted user is a dialup ISP user since the ISP may have a friendly "How
|
||
|
to setup your Internet connection" web page that specifies the IP address
|
||
|
of their DNS server.
|
||
|
|
||
|
Criteria 2 (destination IP address) does not have to be met according to
|
||
|
RFC 1122 (Requirements for Internet Hosts -- Communication Layers) which
|
||
|
states that "For most purposes, a datagram addressed to a broadcast or
|
||
|
multicast destination is processed as if it had been addressed to one of
|
||
|
the host's IP addresses". Using a broadcast destination address would be
|
||
|
most useful for attacking computers on a Local Area Network. Furthermore,
|
||
|
a DNS reply may be accepted if it is addressed to any of the IP addresses
|
||
|
associated with a network interface.
|
||
|
|
||
|
Criteria 3 (source port number) does not have to be met according to RFC
|
||
|
768 (User Datagram Protocol) which states that "Source Port is an optional
|
||
|
field". The source port can therefore be set to an arbitrary value such
|
||
|
as 0 or 12345. Since the source port number of the DNS reply affects
|
||
|
packet dissection by utilities such as Ethereal, a value of 137 is a
|
||
|
devious choice since it will be dissected as the NetBIOS Name Service
|
||
|
(NBNS) protocol which is based on DNS. As a result, the malicious DNS
|
||
|
replies can be made to appear like NetBIOS traffic which is likely to be
|
||
|
discarded by the system administrator or investigator as typical NetBIOS
|
||
|
background noise.
|
||
|
|
||
|
Criteria 4 (destination port number) must be met according to RFC 768
|
||
|
(User Datagram Protocol). However, this value may be predictable
|
||
|
depending on the requesting computer's operating system. During testing,
|
||
|
Windows XP always used port number 1026 to perform DNS queries, though
|
||
|
this value depends on when the DNS Client service started during the boot
|
||
|
process.
|
||
|
|
||
|
Criteria 5 (UDP checksum) does not have to be met according to RFC 1122
|
||
|
(Requirements for Internet Hosts -- Communication Layers) which states
|
||
|
that "the UDP checksum is optional; the value zero is transmitted in the
|
||
|
checksum field of a UDP header to indicate the absence of a checksum".
|
||
|
|
||
|
Criteria 6 (transaction ID) must be met according to RFC 1035 (Domain
|
||
|
names - implementation and specification) which states that the
|
||
|
transaction ID is used "to match up replies to outstanding queries".
|
||
|
However, this value may be predictable depending on the requesting
|
||
|
computer's operating system. During testing, Windows XP did not randomly
|
||
|
choose the 16 bit transaction ID value. Rather, Windows XP always used a
|
||
|
transaction ID of 1 for the first DNS query performed after the computer
|
||
|
was turned on, with the transaction ID simply incremented for subsequent
|
||
|
DNS queries. Transaction ID 1 and 2 were used by the operating system to
|
||
|
perform a DNS query of time.windows.com.
|
||
|
|
||
|
Criteria 7 and 8 (domain name in question and answer section) do not have
|
||
|
to be met according to RFC 1035 (Domain names - implementation and
|
||
|
specification) which states that the transaction ID is used "to match up
|
||
|
replies to outstanding queries" and recommends as a secondary step "to
|
||
|
verify that the question section corresponds to the information currently
|
||
|
desired". RFC recommendations do not have to be followed, and in the case
|
||
|
of an absent question section, the principal that an implementation must
|
||
|
accept any datagram that it can interpret appears to apply. Therefore, a
|
||
|
DNS reply containing a single answer in the form of an IP address can be
|
||
|
matched to the corresponding DNS request based on the transaction ID,
|
||
|
without requiring a question section and without resorting to the overhead
|
||
|
of processing the domain information in the answer section. Furthermore,
|
||
|
an answer section is not even necessary if an Authority section is
|
||
|
provided to refer the requesting computer to an authoritative name server
|
||
|
(or a DNS server under the attacker's control).
|
||
|
|
||
|
Criteria 9 (requesting computer must receive the attacker's DNS reply
|
||
|
before it receives the legitimate DNS reply) must be met and remains as
|
||
|
the greatest challenge to the attacker. This restriction is difficult
|
||
|
to bypass unless the legitimate DNS server is taken out of action to
|
||
|
prevent competition with the spoofed DNS reply, or numerous spoofed DNS
|
||
|
replies are sent to the targeted user. However, as discussed above,
|
||
|
criteria 1 to 8 either do not have to be met or may have predictable
|
||
|
values. Therefore an attacker may require no knowledge of the victim's
|
||
|
DNS request to have a reasonable chance of performing a successful attack
|
||
|
by sending the requesting computer a small number of generic DNS replies.
|
||
|
Furthermore, there is a viable workaround to the restrictive nature of
|
||
|
this criteria. If the attacker is not trying to compromise a specific
|
||
|
computer, a "spray and pray" approach can be used. This approach involves
|
||
|
sending a very small number (twenty) of spoofed DNS replies to a maximum
|
||
|
number of potential target computers, instead of trying to compromise a
|
||
|
specific user and only once they have been compromised then trying to
|
||
|
compromise another specific user. This "spray and pray" approach won't
|
||
|
compromise every potential victim, and every packet the attacker sends
|
||
|
won't result in a compromise, but enough of the attacker's malicious DNS
|
||
|
replies will be accepted by enough potential victims to make the exercise
|
||
|
worthwhile.
|
||
|
|
||
|
|
||
|
|
||
|
--[ 5 - Example DNS Spoofing Attack
|
||
|
|
||
|
|
||
|
A DNS spoofing attack using the concepts discussed in this article was
|
||
|
performed against a Windows XP computer. The test Windows XP computer
|
||
|
was a default install of the operating system followed by the application
|
||
|
of Service Pack 1. The Microsoft Internet Connection Firewall shipped
|
||
|
with Windows XP was then enabled, and configured to perform full logging
|
||
|
of dropped packets and successful connections.
|
||
|
|
||
|
The Windows XP user typed the web site URL www.somewebsite.org into
|
||
|
Internet Explorer, resulting in a DNS request being sent from the user's
|
||
|
computer (IP address 192.168.1.1) to the user's DNS server (IP address
|
||
|
192.168.1.254).
|
||
|
|
||
|
A spoofed DNS reply disguised as NetBIOS data was sent to the user from
|
||
|
the fake (spoofed) nonexistent IP address 10.10.10.1, specifying that
|
||
|
whatever name the user was attempting to resolve had the IP address
|
||
|
192.168.1.77. The IP address 192.168.1.77 was actually a web server
|
||
|
under the attacker's control.
|
||
|
|
||
|
Internet Explorer connected to 192.168.1.77 and requested the web page.
|
||
|
This revealed that the designers of the DNS resolver in Microsoft Windows
|
||
|
XP also interpreted the RFC guidelines as described in the previous
|
||
|
section, significantly simplifying DNS spoofing attacks.
|
||
|
|
||
|
The following network packet decoded by Ethereal version 0.10.3
|
||
|
illustrates the malicious DNS reply and demonstrates how Ethereal can be
|
||
|
confused into decoding the packet as NetBIOS traffic.
|
||
|
|
||
|
Frame 1 (102 bytes on wire, 102 bytes captured)
|
||
|
Ethernet II, Src: 00:50:56:c0:00:01, Dst: 00:0c:29:04:7d:25
|
||
|
Internet Protocol, Src Addr: 10.10.10.1 (10.10.10.1), Dst Addr:
|
||
|
192.168.1.1 (192.168.1.1)
|
||
|
User Datagram Protocol, Src Port: 137 (137), Dst Port: 1026 (1026)
|
||
|
Source port: 137 (137)
|
||
|
Destination port: 1026 (1026)
|
||
|
Length: 68
|
||
|
Checksum: 0x0000 (none)
|
||
|
NetBIOS Name Service
|
||
|
Transaction ID: 0x0003
|
||
|
Flags: 0x8580 (Name query response, No error)
|
||
|
Questions: 0
|
||
|
Answer RRs: 1
|
||
|
Authority RRs: 0
|
||
|
Additional RRs: 0
|
||
|
Answers
|
||
|
WORKGROUP<1b>: type unknown, class inet
|
||
|
Name: WORKGROUP<1b>
|
||
|
Type: unknown
|
||
|
Class: inet
|
||
|
Time to live: 1 day
|
||
|
Data length: 4
|
||
|
Data
|
||
|
|
||
|
0000 00 0c 29 04 7d 25 00 50 56 c0 00 01 08 00 45 00 ..).}%.PV.....E.
|
||
|
0010 00 58 bf 58 00 00 00 11 25 89 0a 0a 0a 01 c0 a8 .X.X....%.......
|
||
|
0020 01 01 00 89 04 02 00 44 00 00 00 03 85 80 00 00 .......D........
|
||
|
0030 00 01 00 00 00 00 20 46 48 45 50 46 43 45 4c 45 ...... FHEPFCELE
|
||
|
0040 48 46 43 45 50 46 46 46 41 43 41 43 41 43 41 43 HFCEPFFFACACACAC
|
||
|
0050 41 43 41 43 41 42 4c 00 00 01 00 01 00 01 51 80 ACACABL.......Q.
|
||
|
0060 00 04 c0 a8 01 4d .....M
|
||
|
|
||
|
|
||
|
This packet was created using the following parameters passed to the
|
||
|
freely available netwox packet creation utility:
|
||
|
|
||
|
netwox 38 --ip4-src 10.10.10.1 --ip4-dst 192.168.1.1 --ip4-protocol 17
|
||
|
--ip4-data 008904020044000000038580000000010000000020464845504643454c45484
|
||
|
643455046464641434143414341434143414341424c0000010001000151800004c0a8014d
|
||
|
|
||
|
Alternatively, the following parameters could be used since netwox
|
||
|
automatically calculates the UDP checksum:
|
||
|
|
||
|
netwox 39 --ip4-src 10.10.10.1 --ip4-dst 192.168.1.1 --udp-src 137
|
||
|
--udp-dst 1026 --udp-data 00038580000000010000000020464845504643454c45484
|
||
|
643455046464641434143414341434143414341424c0000010001000151800004c0a8014d
|
||
|
|
||
|
The following shows that the spoofed DNS reply has been added to the
|
||
|
user's DNS resolver cache for a period of 1 day, causing future
|
||
|
resolutions of www.somewebsite.org to map to the web server under the
|
||
|
attacker's control. The cache duration value can be decreased by the
|
||
|
attacker so that the entry is either not cached or is immediately removed
|
||
|
from the cache in order to remove evidence of the attack.
|
||
|
|
||
|
C:\>ipconfig /displaydns
|
||
|
|
||
|
Windows IP Configuration
|
||
|
|
||
|
1.0.0.127.in-addr.arpa
|
||
|
----------------------------------------
|
||
|
Record Name . . . . . : 1.0.0.127.in-addr.arpa.
|
||
|
Record Type . . . . . : 12
|
||
|
Time To Live . . . . : 604393
|
||
|
Data Length . . . . . : 4
|
||
|
Section . . . . . . . : Answer
|
||
|
PTR Record . . . . . : localhost
|
||
|
|
||
|
|
||
|
www.somewebsite.org
|
||
|
----------------------------------------
|
||
|
Record Name . . . . . : FHEPFCELEHFCEPFFFACACACACACACABL
|
||
|
Record Type . . . . . : 1
|
||
|
Time To Live . . . . : 86364
|
||
|
Data Length . . . . . : 4
|
||
|
Section . . . . . . . : Answer
|
||
|
A (Host) Record . . . : 192.168.1.77
|
||
|
|
||
|
|
||
|
localhost
|
||
|
----------------------------------------
|
||
|
Record Name . . . . . : localhost
|
||
|
Record Type . . . . . : 1
|
||
|
Time To Live . . . . : 604393
|
||
|
Data Length . . . . . : 4
|
||
|
Section . . . . . . . : Answer
|
||
|
A (Host) Record . . . : 127.0.0.1
|
||
|
|
||
|
|
||
|
The following log file from Microsoft's Internet Connection Firewall
|
||
|
reveals that it did not provide any protection against the attack, though
|
||
|
it is not designed to inspect and correlate DNS traffic. If the firewall
|
||
|
was not configured to log successful connections, then there would not
|
||
|
have been any log entries.
|
||
|
|
||
|
#Verson: 1.0
|
||
|
#Software: Microsoft Internet Connection Firewall
|
||
|
#Time Format: Local
|
||
|
#Fields: date time action protocol src-ip dst-ip src-port dst-port size
|
||
|
tcpflags tcpsyn tcpack tcpwin icmptype icmpcode info
|
||
|
|
||
|
2004-05-10 20:34:56 OPEN UDP 192.168.1.1 192.168.1.254 1026 53 - - - - - -
|
||
|
- -
|
||
|
2004-05-10 20:34:57 OPEN-INBOUND UDP 10.10.10.1 192.168.1.1 137 1026 - - -
|
||
|
- - - - -
|
||
|
2004-05-10 20:34:57 OPEN TCP 192.168.1.1 192.168.1.77 3010 80 - - - - - -
|
||
|
- -
|
||
|
2004-05-10 20:35:30 CLOSE TCP 192.168.1.1 192.168.1.77 3010 80 - - - - - -
|
||
|
- -
|
||
|
2004-05-10 20:36:30 CLOSE UDP 192.168.1.1 192.168.1.254 1026 53 - - - - -
|
||
|
- - -
|
||
|
2004-05-10 20:36:30 CLOSE UDP 10.10.10.1 192.168.1.1 137 1026 - - - - - -
|
||
|
- -
|
||
|
|
||
|
It can be seen that when the Windows XP computer sent a UDP packet from
|
||
|
port 1026 to port 53 of the DNS server, the firewall allowed all incoming
|
||
|
UDP traffic to port 1026, regardless of the source IP address or source
|
||
|
port of the incoming traffic. Such incoming traffic was allowed to
|
||
|
continue until the firewall decided to block access to port 1026, which
|
||
|
occurred when there was no incoming traffic to port 1026 for a defined
|
||
|
period of time. This timeframe was between 61 seconds and 120 seconds, as
|
||
|
it appeared that the firewall checked once per minute to determine if
|
||
|
access to ports should be revoked due to more than 60 seconds of
|
||
|
inactivity. Assuming that users connected to the Internet would typically
|
||
|
perform a DNS query at least every minute, incoming access to port 1026
|
||
|
would always be granted. An attacker on the Internet could therefore send
|
||
|
the Windows XP computer spoofed DNS replies without worrying that they
|
||
|
might be blocked by the firewall. Such traffic would not generate any
|
||
|
logs if the firewall was configured to only Log Dropped Packets. If the
|
||
|
firewall was configured to also Log Successful Connections as in this
|
||
|
example, these log entries would disappear among the thousands of other
|
||
|
log entries. Since the firewall logs connections and not traffic, if the
|
||
|
source IP address was set to the Windows XP computer's DNS server, no
|
||
|
extra firewall log entries would be created as a result of the DNS
|
||
|
spoofing attack.
|
||
|
|
||
|
The netstat command revealed that the Windows XP computer was always
|
||
|
listening on UDP port 1026, and as a result, extra DNS replies were
|
||
|
silently discarded and did not generate an error message in the event log
|
||
|
or an ICMP port unreachable packet. This behaviour, and the reuse of the
|
||
|
same source port number for DNS requests, was attributed to the DNS Client
|
||
|
service.
|
||
|
|
||
|
|
||
|
|
||
|
--[ 6 - Practical Impact of RFC Guidelines on DNS Spoofing Attacks
|
||
|
|
||
|
|
||
|
The attacker does not require information about the targeted user's DNS
|
||
|
requests, such as the IP address of the user's DNS server, the source port
|
||
|
of the user's DNS request, or the name that the user was attempting to
|
||
|
resolve to an IP address. Therefore the attacker does not require access
|
||
|
to the communication link between the targeted user and their DNS server.
|
||
|
|
||
|
Windows XP SP1 matches DNS replies to DNS requests by only the transaction
|
||
|
ID and the UDP port number, and both of these values are very predictable.
|
||
|
Since the name to be resolved is not matched between the DNS request and
|
||
|
the DNS reply, the attacker does not care what domain name the user
|
||
|
queried since this domain name does not have to be placed in the
|
||
|
attacker's DNS reply. As a result, the attacker can create generic
|
||
|
malicious DNS replies that will successfully subvert the targeted user's
|
||
|
DNS lookup process regardless of the name the targeted user was attempting
|
||
|
to resolve, and regardless of the targeted user's network configuration
|
||
|
such as the IP address of their DNS server.
|
||
|
|
||
|
An attacker desiring to compromise as many computers as possible with the
|
||
|
least amount of effort and in the shortest timeframe could send twenty DNS
|
||
|
replies that look similar to the generic DNS reply used in the example
|
||
|
attack on Windows XP in this article, though with the transaction ID
|
||
|
ranging from 3 to 22. To be more thorough, the attacker could instead
|
||
|
send one hundred DNS replies with the destination port number ranging from
|
||
|
1025 to 1029. The attacker would use a "spray and pray" approach by
|
||
|
sending these DNS replies to every IP address in the IP address range
|
||
|
belonging to a large dialup Internet Service Provider, and when finished,
|
||
|
repeating the process.
|
||
|
|
||
|
A level of success is guaranteed in such an attack scenario considering
|
||
|
the huge target base of potential victims awaiting a DNS reply, and
|
||
|
considering that Windows XP accepts anything vaguely resembling a DNS
|
||
|
reply as a valid DNS reply.
|
||
|
|
||
|
A recipient of the attacker's twenty DNS replies will accept one of them
|
||
|
as being valid, resulting in a successful attack, if the recipient:
|
||
|
- is using Windows XP with its poorly implemented DNS client resolver
|
||
|
(most dialup Internet users are in this category).
|
||
|
- recently connected to the Internet within the last 10-20 minutes or so
|
||
|
and therefore haven't performed more than twenty DNS requests (a
|
||
|
reasonable proportion of dialup Internet users are in this category).
|
||
|
- recently performed a DNS request and is awaiting a DNS reply (a
|
||
|
reasonable number of the huge target base of dialup Internet users are
|
||
|
in this category).
|
||
|
|
||
|
The targeted Windows XP users would be unlikely to notice the attack,
|
||
|
especially if they were relying on Microsoft Internet Connection Firewall
|
||
|
to protect them. Analysis of the logs of a more sophisticated firewall
|
||
|
and inspection of network traffic would not readily reveal a DNS spoofing
|
||
|
attack since the source IP address would not be that of the legitimate DNS
|
||
|
server. Furthermore, the source port number and content of the spoofed
|
||
|
DNS replies can be crafted to make them appear to be typical NetBIOS
|
||
|
background noise which would probably be discarded by the user as useless
|
||
|
network traffic floating around the Internet. Finally, the targeted IP
|
||
|
address range of a dialup ISP would consist mainly of home Internet users
|
||
|
who are not educated in advanced network security concepts.
|
||
|
|
||
|
The IP address in the spoofed DNS replies could be a computer on the
|
||
|
Internet under the attacker's control, which is running proxy software for
|
||
|
email (SMTP and POP3) and HTTP traffic. The attacker would be able to
|
||
|
collect sensitive information including email sent and received as well as
|
||
|
passwords for future email retrieval. Web based email and unencrypted
|
||
|
login details to web sites would also be collected. The attacker could
|
||
|
add content to HTML pages before returning them to the user. Such content
|
||
|
could include banner ads to generate money, or a hidden frame with a link
|
||
|
to a file on a third party web site effectively causing a distributed
|
||
|
denial of service attack against the third party. More seriously, the
|
||
|
attacker could increase the scope of the compromise by adding HTML content
|
||
|
that exploited one of the publicly known vulnerabilities in Internet
|
||
|
Explorer that allows the execution of arbitrary code, but for which there
|
||
|
is no vendor patch. For example, vulnerabilities discussed at the web
|
||
|
site http://www.computerworld.com.au/index.php?id=117316298&eid=-255
|
||
|
The "spray and pray" attack approach is useful for creating a network of
|
||
|
semi-randomly chosen compromised computers under the attacker's control,
|
||
|
otherwise known as a botnet.
|
||
|
|
||
|
Proxying of HTTP/1.1 traffic could be performed by inspecting the HOST
|
||
|
header to determine which web site the user wanted to visit. However, for
|
||
|
the purpose of easily and seamlessly proxying traffic, an attacker may
|
||
|
decide not to place an Answer section in the spoofed DNS replies. Rather,
|
||
|
the attacker may send a non-authoritative spoofed DNS reply using the
|
||
|
Authority and Additional sections of DNS replies to refer the requesting
|
||
|
computer to a DNS server under the attacker's control. This would allow
|
||
|
the attacker to know exactly what domain the victim computer was
|
||
|
attempting to query, and furthermore such spoofed DNS replies may have a
|
||
|
long lasting and widespread effect on the victim's computer. A detailed
|
||
|
discussion of DNS referrals and testing whether Windows XP could handle
|
||
|
them is outside the scope of this article.
|
||
|
|
||
|
|
||
|
|
||
|
--[ 7 - Implementation Comparison
|
||
|
|
||
|
|
||
|
Contributors to the Linux operating system appear to have taken a hardline
|
||
|
security conscious approach to interpreting the RFC guidelines, bordering
|
||
|
on non-conformance for the sake of security. The Mozilla web browser
|
||
|
running on the author's Debian Linux computer was very restrictive and
|
||
|
required DNS replies to meet all of the above nine criteria except for
|
||
|
criteria 5, where a UDP checksum value of zero was accepted. An incorrect
|
||
|
UDP checksum was accepted when the packet was sent over a local network
|
||
|
but not when sent over the Internet. Reviewing the kernel source code
|
||
|
indicated that for local networks, the UDP checksum was deliberately
|
||
|
ignored and hardware based checking was performed instead for performance
|
||
|
reasons. This appeared to be a feature and not a bug, even though it did
|
||
|
not comply with RFC 1122 (Requirements for Internet Hosts -- Communication
|
||
|
Layers) which states that "If a UDP datagram is received with a checksum
|
||
|
that is non-zero and invalid, UDP MUST silently discard the datagram".
|
||
|
|
||
|
During testing, the Linux computer used source port numbers 32768 and
|
||
|
32769 to perform DNS queries. The transaction ID was randomly generated,
|
||
|
complicating DNS spoofing attacks, though the transaction ID used in the
|
||
|
retransmission of an unanswered DNS request was not as random. The choice
|
||
|
of transaction ID values appeared robust enough to help defend against DNS
|
||
|
spoofing attacks on the Internet since the initial transaction ID value
|
||
|
was unpredictable, and the first DNS request would typically be answered
|
||
|
resulting in no need for retransmissions.
|
||
|
|
||
|
The iptables firewall on the Linux computer was configured so that the
|
||
|
only allowed UDP traffic was to/from port 53 of the legitimate DNS server.
|
||
|
When a DNS query was performed and a DNS reply was received, iptables was
|
||
|
unable to block extra (spoofed) incoming DNS replies since it is not
|
||
|
designed to inspect DNS traffic and allow one incoming DNS reply per
|
||
|
outgoing DNS request. However, since the port used to send the DNS query
|
||
|
was closed once a valid DNS reply was received, ICMP port unreachable
|
||
|
messages were generated for the extra (spoofed) incoming DNS replies.
|
||
|
iptables was configured to block and log outgoing ICMP network traffic.
|
||
|
Reviewing the logs revealed ICMP port unreachable messages that were
|
||
|
destined to the legitimate DNS server, which were a good indication of a
|
||
|
DNS spoofing attack. Further to this evidence of a DNS spoofing attack,
|
||
|
since the DNS replies must come from port 53, analysis of the network
|
||
|
traffic using a packet dissector such as Ethereal revealed traffic that
|
||
|
looked like DNS replies apparently originating at the legitimate DNS
|
||
|
server.
|
||
|
|
||
|
|
||
|
|
||
|
--[ 8 - Conclusion
|
||
|
|
||
|
|
||
|
The RFC guidelines simplify DNS spoofing attacks against DNS client
|
||
|
resolvers since the attacker does not require information such as the IP
|
||
|
address of the potential victim's DNS server or the contents of DNS
|
||
|
queries sent by the potential victim. Microsoft Windows XP is more
|
||
|
susceptible to DNS spoofing attacks than Linux due to its poor
|
||
|
implementation of the RFC guidelines. Further simplifying DNS spoofing
|
||
|
attacks are Windows XP's inadequate matching of DNS requests to DNS
|
||
|
replies, and the predictable port number and transaction ID values -
|
||
|
behaviour that could be changed without violating the RFC guidelines.
|
||
|
Evidence of DNS spoofing attacks is minimised by the ability to disguise
|
||
|
DNS replies as NetBIOS traffic, the lack of configuration granularity and
|
||
|
traffic inspection of some firewalls, and Windows XP's failure to generate
|
||
|
ICMP error messages for excessive DNS replies.
|
||
|
|
||
|
RFC 791 (Internet Protocol) stating that a program must be "liberal in its
|
||
|
receiving behavior" and "must accept any datagram that it can interpret"
|
||
|
may have been acceptable in 1981 when the RFC was created and
|
||
|
interoperability was more important than security. However, the Internet
|
||
|
has changed from a somewhat trustworthy user base of representatives from
|
||
|
educational institutions and the US Department of Defense to now include
|
||
|
hackers and scammers, making security a high profile consideration.
|
||
|
Perhaps it is time for software based on this outdated perception of the
|
||
|
Internet to be changed as well.
|
||
|
|
||
|
The Internet community continues to wait for widespread adoption of
|
||
|
cryptographic digital signatures used to authenticate DNS transactions,
|
||
|
as discussed in RFC 2535 (Domain Name System Security Extensions). In the
|
||
|
meantime, the threat of DNS spoofing attacks could be minimised by
|
||
|
Microsoft improving the DNS implementation in all of their affected
|
||
|
operating systems. Such improvements include using random transaction ID
|
||
|
values, checking that the name in a DNS reply matches the name to be
|
||
|
resolved in the DNS request, and using a random source port for DNS
|
||
|
requests. These improvements would make attacks against DNS client
|
||
|
resolvers significantly more difficult to perform, and such improvements
|
||
|
would not violate the RFC guidelines.
|
||
|
|
||
|
|
||
|
|
||
|
|=----------------------------------------------------------------------=|
|
||
|
|=----------------------------------------------------------------------=|
|
||
|
|
||
|
########################################
|
||
|
# Injecting signals for Fun and Profit #
|
||
|
########################################
|
||
|
|
||
|
by shaun2k2 <shaunige@yahoo.co.uk>
|
||
|
|
||
|
|
||
|
--[ 1 - Introduction
|
||
|
|
||
|
More secure programming is on the rise, eliminating more generic program
|
||
|
exploitation vectors, such as stack-based overflows, heap overflows and symlink
|
||
|
bugs. Despite this, subtle vulnerabilities are often overlooked during code
|
||
|
audits, leaving so-called "secure" applications vulnerable to attack, but in a
|
||
|
less obvious manner. Secure design of signal-handlers is often not considered,
|
||
|
but I believe that this class of security holes deserves just as much attention
|
||
|
as more generic classes of bugs, such as buffer overflow bugs.
|
||
|
|
||
|
This paper intends to discuss problems faced when writing signal-handling
|
||
|
routines, how to exploit the problems, and presents ideas of how to avoid such
|
||
|
issues. A working knowledge of the C programming language and UNIX-like
|
||
|
operating systems would benefit the reader greatly, but is certainly not
|
||
|
essential.
|
||
|
|
||
|
|
||
|
--[ 2 - Signal Handling: An Overview
|
||
|
|
||
|
To understand what signal handlers are, one must first know what exactly a
|
||
|
signal is. In brief, signals are notifications delivered to a process to alert
|
||
|
the given process about "important" events concerning itself. For example,
|
||
|
users of an application can send signals using common keyboard Ctrl
|
||
|
combinations, such as Ctrl-C - which will send a SIGINT signal to the given
|
||
|
process.
|
||
|
|
||
|
Many different signals exist, but some of the more common (or useful) ones are:
|
||
|
SIGINT, SIGHUP, SIGKILL, SIGABRT, SIGTERM and SIGPIPE. Many more exist,
|
||
|
however. A list of available signals, according to the POSIX.1 standard,
|
||
|
can be found in the unix manual page signal(7).
|
||
|
|
||
|
It is worth noting that the signals SIGKILL and
|
||
|
SIGSTOP cannot be handled, ignored or blocked. Their 'action' can
|
||
|
not be changed.
|
||
|
|
||
|
"What are signal handlers", one might ask. The simple answer is that signal
|
||
|
handlers are small routines which are typically called when a pre-defined
|
||
|
signal, or set of signals, is delivered to the process it is running under
|
||
|
before the end of program execution - after execution flow has been directed to
|
||
|
a signal handling function, all instructions within the handler are executed in
|
||
|
turn. In larger applications, however, signal handling routines are often
|
||
|
written to complete a more complex set of tasks to ensure clean termination of
|
||
|
the program, such as; unlinking of tempory files, freeing of memory buffers,
|
||
|
appending log messages, and freeing file descriptors and/or sockets. Signal
|
||
|
handlers are generally defined as ordinary program functions, and are then
|
||
|
defined as the default handler for a certain signal usually near to the
|
||
|
beginning of the program.
|
||
|
|
||
|
Consider the sample program below:
|
||
|
|
||
|
--- sigint.c ---
|
||
|
#include <stdio.h>
|
||
|
#include <signal.h>
|
||
|
|
||
|
void sighndlr() {
|
||
|
printf("Ctrl-C caught!\n");
|
||
|
exit(0);
|
||
|
}
|
||
|
|
||
|
int main() {
|
||
|
signal(SIGINT, sighndlr);
|
||
|
|
||
|
while(1)
|
||
|
sleep(1);
|
||
|
|
||
|
|
||
|
/* should never reach here */
|
||
|
return(0);
|
||
|
}
|
||
|
--- EOF ---
|
||
|
|
||
|
'sigint.c' specifies that the function 'sighndlr' should be given control of
|
||
|
execution flow when a SIGINT signal is received by the program. The program
|
||
|
sleeps "forever", or until a SIGINT signal is received - in which case the
|
||
|
"Ctrl-C caught!" message is printed to the terminal - as seen below:
|
||
|
|
||
|
--- output ---
|
||
|
[root@localhost shaun]# gcc test.c -o test
|
||
|
[root@localhost shaun]# ./test
|
||
|
[... program sleeps ...]
|
||
|
Ctrl-C caught!
|
||
|
[root@localhost shaun]#
|
||
|
--- EOF ---
|
||
|
|
||
|
|
||
|
Generally speaking, a SIGINT signal is delivered when a user hits the Ctrl-C
|
||
|
combination at the keyboard, but a SIGINT signal can be generated by the
|
||
|
kill(1) utility.
|
||
|
|
||
|
However simple or complex the signal handler is, there are several potential
|
||
|
pitfalls which must be avoided during the development of the handler. Although
|
||
|
a signal handler may look "safe", problems may still arise, but may be
|
||
|
less-obvious to the unsuspecting eye. There are two main classes of problems
|
||
|
when dealing with signal-handler development - non-atomic process
|
||
|
modifications, and non-reentrant code, both of which are potentially critical
|
||
|
to system security.
|
||
|
|
||
|
|
||
|
--[ 3 - Non-atomic Modifications
|
||
|
|
||
|
Since signals can be delivered at almost any moment, and privileges often need
|
||
|
to be maintained (i.e root privileges in a SUID root application) for obvious
|
||
|
reasons (i.e for access to raw sockets, graphical resources, etc), signal
|
||
|
handling routines need to be written with extra care. If they are not, and
|
||
|
special privileges are held by the process at the particular time of signal
|
||
|
delivery, things could begin to go wrong very quickly. What is meant by
|
||
|
'non-atomic' is that the change in the program isn't permanant - it will
|
||
|
just be in place temporarily. To illustrate this, we will discuss a sample
|
||
|
vulnerable program.
|
||
|
|
||
|
Consider the following sample program:
|
||
|
|
||
|
--- atomicvuln.c ---
|
||
|
#include <stdio.h>
|
||
|
#include <signal.h>
|
||
|
|
||
|
void sighndlr() {
|
||
|
printf("Ctrl-C caught!\n");
|
||
|
printf("UID: %d\n", getuid());
|
||
|
/* other cleanup code... */
|
||
|
}
|
||
|
|
||
|
int showuid() {
|
||
|
printf("UID: %d\n", getuid());
|
||
|
return(0);
|
||
|
}
|
||
|
|
||
|
|
||
|
int main() {
|
||
|
int origuid = getuid();
|
||
|
signal(SIGINT, sighndlr);
|
||
|
|
||
|
|
||
|
setuid(0);
|
||
|
sleep(5);
|
||
|
|
||
|
setuid(origuid);
|
||
|
|
||
|
showuid();
|
||
|
return(0);
|
||
|
}
|
||
|
--- EOF ---
|
||
|
|
||
|
The above program should immediately spark up any security concious
|
||
|
programmer's paranoia, but the insecurity isn't immediately obvious
|
||
|
to everyone. As we can see from above, a signal handler is declared for
|
||
|
'SIGINT', and the program gives itself root privileges (so to speak). After
|
||
|
a delay of around five seconds, the privileges are revoked, and the
|
||
|
program is exited with success. However, if a SIGINT signal is received,
|
||
|
execution is directed to the SIGINT handler, 'sighdlr()'.
|
||
|
|
||
|
Let's look at some sample outputs:
|
||
|
|
||
|
--- output ---
|
||
|
[root@localhost shaun]# gcc test.c -o test
|
||
|
[root@localhost shaun]# chmod +s test
|
||
|
[root@localhost shaun]# exit
|
||
|
exit
|
||
|
[shaun@localhost shaun]$ ./test
|
||
|
[... program sleeps 5 seconds ...]
|
||
|
UID: 502
|
||
|
[shaun@localhost shaun]$ ./test
|
||
|
[... CTRL-C is typed ...]
|
||
|
Ctrl-C caught!
|
||
|
UID: 0
|
||
|
UID: 502
|
||
|
[shaun@localhost shaun]$
|
||
|
--- EOF ---
|
||
|
|
||
|
If you hadn't spotted the insecurity in 'atomicvuln.c' yet, the above output
|
||
|
should make things obvious; since the signal handling routine, 'sighdlr()', was
|
||
|
called when root privileges were still possessed, the friendly printf()
|
||
|
statements kindly tell us that our privileges are root (assuming the binary is
|
||
|
SUID root). And just to prove our theory, if we simply allow the program to
|
||
|
sleep for 5 seconds without sending an interrupt, the printf() statement kindly
|
||
|
tells us that our UID is 502 - my actual UID - as seen above.
|
||
|
|
||
|
With this, it is easy to understand where the flaw lies; if program execution
|
||
|
can be interrupted between the time when superuser privileges are given,
|
||
|
and the time when superuser privileges are revoked, the signal handling
|
||
|
code *will* be ran with root privileges. Just imagine - if the signal
|
||
|
handling routine included potentially sensitive code, compromisation of
|
||
|
root privileges could occur.
|
||
|
|
||
|
Although the sample program isn't an example of privilege escalation, it at
|
||
|
least demonstrates how non-atomic modifications can present security issues
|
||
|
when signal handling is involved. And do not assume that code similar to the
|
||
|
sample program above isn't found in popular security critical applications in
|
||
|
wide-spread use - it is. An example of vulnerable code similar to that of
|
||
|
above which is an application in wide-spread use, see [1] in the bibliography.
|
||
|
|
||
|
|
||
|
Non-reentrant Code
|
||
|
###################
|
||
|
|
||
|
Although it may not be obvious (and it's not), some glibc functions just
|
||
|
weren't designed to be reentered due to receipt of a signal, thus causing
|
||
|
potential problems for signal handlers which use them. An example of such a
|
||
|
function is the 'free()' function. According to 'free()'s man page, free()
|
||
|
|
||
|
"frees the memory space pointed to by ptr, which must have been
|
||
|
returned by a previous call to malloc(), calloc() or realloc(). Other-
|
||
|
wise, or if free(ptr) has already been called before, undefined
|
||
|
behaviour occurs. If ptr is NULL, no operation is performed."
|
||
|
|
||
|
As the man page snippet claims, free() can only be used to release memory which
|
||
|
was allocated using 'malloc()', else "undefined behavior" occurs. More
|
||
|
specifically, or in usual cases, the heap is corrupted, if free() is called on
|
||
|
a memory area which has already been free()d. Because of this implementation
|
||
|
design, reentrant signal routines which use 'free()' can be attacked.
|
||
|
|
||
|
Consider the below sample vulnerable program:
|
||
|
|
||
|
--- reentry.c ---
|
||
|
#include <stdio.h>
|
||
|
#include <signal.h>
|
||
|
#include <syslog.h>
|
||
|
#include <string.h>
|
||
|
#include <stdlib.h>
|
||
|
|
||
|
void *data1, *data2;
|
||
|
char *logdata;
|
||
|
|
||
|
void sighdlr() {
|
||
|
printf("Entered sighdlr()...\n");
|
||
|
syslog(LOG_NOTICE,"%s\n", logdata);
|
||
|
free(data2);
|
||
|
free(data1);
|
||
|
sleep(10);
|
||
|
exit(0);
|
||
|
}
|
||
|
|
||
|
int main(int argc, char *argv[]) {
|
||
|
logdata = argv[1];
|
||
|
data1 = strdup(argv[2]);
|
||
|
data2 = malloc(340);
|
||
|
signal(SIGHUP, sighdlr);
|
||
|
signal(SIGTERM, sighdlr);
|
||
|
sleep(10);
|
||
|
|
||
|
/* should never reach here */
|
||
|
return(0);
|
||
|
|
||
|
}
|
||
|
--- EOF ---
|
||
|
|
||
|
The above program defines a signal handler which frees allocated heap memory,
|
||
|
and sleeps for around 10 seconds. However, once the signal handler has been
|
||
|
entered, signals are not blocked, and thus can still be freely delivered. As
|
||
|
we learnt above, a duplicate call of free() on an already free()d memory area
|
||
|
will result in "undefined behavior" - possibly corruption of the heap memory.
|
||
|
As we can see, user-defined data is taken, and syslog() is also called fromo
|
||
|
the sig handler function - but how does syslog() work? 'syslog()' creates a
|
||
|
memory buffer stream, using two malloc() invokations - the first one allocates
|
||
|
a 'stream description structure', whilst the other creates a buffer suitable
|
||
|
for the actual syslog message data. This basis is essentially used to maintain
|
||
|
a tempory copy of the syslog message.
|
||
|
|
||
|
But why can this cause problems in context of co-usage of non-reentrant
|
||
|
routines? To find the answer, let's experiment a little, by attempting to
|
||
|
exploit the above program, which happens to be vulnerable.
|
||
|
|
||
|
--- output ---
|
||
|
[shaun@localhost shaun]$ ./test `perl -e 'print
|
||
|
"a"x100'` `perl -e 'print
|
||
|
"b"x410'` & sleep 1 ; killall -HUP test ; sleep 1 ;
|
||
|
killall -TERM test
|
||
|
[1] 2877
|
||
|
Entered sighdlr()...
|
||
|
Entered sighdlr()...
|
||
|
[1]+ Segmentation fault (core dumped) ./test
|
||
|
`perl -e 'print "a"x100'`
|
||
|
`perl -e 'print "b"x410'`
|
||
|
[shaun@localhost shaun]$ gdb -c core.2877
|
||
|
GNU gdb 5.2.1-2mdk (Mandrake Linux)
|
||
|
Copyright 2002 Free Software Foundation, Inc.
|
||
|
GDB is free software, covered by the GNU General
|
||
|
Public License, and you are
|
||
|
welcome to change it and/or distribute copies of it
|
||
|
under certain conditions.
|
||
|
Type "show copying" to see the conditions.
|
||
|
There is absolutely no warranty for GDB. Type "show
|
||
|
warranty" for details.
|
||
|
This GDB was configured as "i586-mandrake-linux-gnu".
|
||
|
Core was generated by `./test
|
||
|
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'.
|
||
|
Program terminated with signal 11, Segmentation fault.
|
||
|
#0 0x4008e9bb in ?? ()
|
||
|
(gdb) info reg
|
||
|
eax 0x61616161 1633771873
|
||
|
ecx 0x40138680 1075021440
|
||
|
edx 0x6965fa38 1768290872
|
||
|
ebx 0x4013c340 1075036992
|
||
|
esp 0xbfffeccc 0xbfffeccc
|
||
|
ebp 0xbfffed0c 0xbfffed0c
|
||
|
esi 0x80498d8 134519000
|
||
|
edi 0x61616160 1633771872
|
||
|
eip 0x4008e9bb 0x4008e9bb
|
||
|
eflags 0x10206 66054
|
||
|
cs 0x23 35
|
||
|
ss 0x2b 43
|
||
|
ds 0x2b 43
|
||
|
es 0x2b 43
|
||
|
fs 0x2b 43
|
||
|
gs 0x2b 43
|
||
|
fctrl 0x0 0
|
||
|
fstat 0x0 0
|
||
|
ftag 0x0 0
|
||
|
fiseg 0x0 0
|
||
|
fioff 0x0 0
|
||
|
foseg 0x0 0
|
||
|
fooff 0x0 0
|
||
|
---Type <return> to continue, or q <return> to quit---
|
||
|
fop 0x0 0
|
||
|
xmm0 {f = {0x0, 0x0, 0x0, 0x0}} {f = {0, 0, 0, 0}}
|
||
|
xmm1 {f = {0x0, 0x0, 0x0, 0x0}} {f = {0, 0, 0, 0}}
|
||
|
xmm2 {f = {0x0, 0x0, 0x0, 0x0}} {f = {0, 0, 0, 0}}
|
||
|
xmm3 {f = {0x0, 0x0, 0x0, 0x0}} {f = {0, 0, 0, 0}}
|
||
|
xmm4 {f = {0x0, 0x0, 0x0, 0x0}} {f = {0, 0, 0, 0}}
|
||
|
xmm5 {f = {0x0, 0x0, 0x0, 0x0}} {f = {0, 0, 0, 0}}
|
||
|
xmm6 {f = {0x0, 0x0, 0x0, 0x0}} {f = {0, 0, 0, 0}}
|
||
|
xmm7 {f = {0x0, 0x0, 0x0, 0x0}} {f = {0, 0, 0, 0}}
|
||
|
mxcsr 0x0 0
|
||
|
orig_eax 0xffffffff -1
|
||
|
(gdb) quit
|
||
|
[shaun@localhost shaun]$
|
||
|
--- EOF ---
|
||
|
|
||
|
Interesting. As we can see above, our large string of 'a's has found its way
|
||
|
into several program registers on stack - EAX and EDI. From this, we can
|
||
|
assume we are witnessing the "undefined behavior" we discussed earlier, when
|
||
|
the signal handler is reentered.
|
||
|
|
||
|
When the sample vulnerable program receives the second signal (SIGTERM), since
|
||
|
signals are not being ignored, the signal handler is reentered to handle this
|
||
|
second signal, causing something to go very wrong.
|
||
|
But why is this happening?
|
||
|
|
||
|
Since the second memory region (*data2) was free()d during the first entry of
|
||
|
the signal handler, syslog() re-uses this released memory for its own
|
||
|
purposes - storing its syslog message, because as the short syslog()
|
||
|
explanation above stated, two malloc() calls are present in most syslog()
|
||
|
implementations, and thus it re-uses the newly free()d memory - *data2.
|
||
|
After the usage of the memory once held as data2 by syslog(), a second
|
||
|
'free()' call is made on the memory region, because of reentry of the signal
|
||
|
handler function. As the free(3) man page stated, undefined behavior *will*
|
||
|
occur if the memory area was already free()d, and we happen to know that this
|
||
|
was the case. So when 'free()' was called again on *data2, free() landed
|
||
|
somewhere in the area containing the 'a's (hence 0x61 in hex), because
|
||
|
syslog() had re-used the freed area to store the syslog message, temporarily.
|
||
|
|
||
|
As the GDB output above illustrates, as long as user-input is used by
|
||
|
'syslog()' (and it is in this case), we have some control over the program
|
||
|
registers, when this "undefined behavior" (corruption of heap in most
|
||
|
cases) occurs. Because of this ability, exploitation is most likely a
|
||
|
possibility - it is left as an exercise to the reader to play with this sample
|
||
|
vulnerable program a little more, and determine if the vulnerability is
|
||
|
exploitable.
|
||
|
|
||
|
|
||
|
For the interested reader, 'free()' is not the only non-reentrant glibc
|
||
|
function. In general, it can be assumed that all glibc functions which are NOT
|
||
|
included within the following list are non-reentrant, and thus are not safe to
|
||
|
be used in signal handlers.
|
||
|
|
||
|
--
|
||
|
_exit(2), access(2), alarm(3), cfgetispeed(3), cfgetospeed(3),
|
||
|
cfsetispeed(3), cfsetospeed(3), chdir(2), chmod(2), chown(2),
|
||
|
close(2), creat(3), dup(2), dup2(2), execle(3), execve(2),
|
||
|
fcntl(2), fork(2), fpathconf(2), fstat(2), fsync(2), getegid(2),
|
||
|
geteuid(2), getgid(2), getgroups(2), getpgrp(2), getpid(2),
|
||
|
getppid(2), getuid(2), kill(2), link(2), lseek(2), mkdir(2),
|
||
|
mkfifo(2), open(2), pathconf(2), pause(3), pipe(2), raise(3),
|
||
|
read(2), rename(2), rmdir(2), setgid(2), setpgid(2), setsid(2),
|
||
|
setuid(2), sigaction(2), sigaddset(3), sigdelset(3),
|
||
|
sigemptyset(3), sigfillset(3), sigismember(3), signal(3),
|
||
|
sigpause(3), sigpending(2), sigprocmask(2), sigsuspend(2),
|
||
|
sleep(3), stat(2), sysconf(3), tcdrain(3), tcflow(3), tcflush(3),
|
||
|
tcgetattr(3), tcgetpgrp(3), tcsendbreak(3), tcsetattr(3),
|
||
|
tcsetpgrp(3), time(3), times(3), umask(2), uname(3), unlink(2),
|
||
|
utime(3), wait(2), waitpid(2), write(2)."
|
||
|
|
||
|
--
|
||
|
|
||
|
|
||
|
|
||
|
Secure Signal Handling
|
||
|
#######################
|
||
|
|
||
|
In general, signal handling vulnerabilities can be prevented by
|
||
|
|
||
|
--
|
||
|
|
||
|
1) Using only reentrant glibc functions within signal handlers -
|
||
|
|
||
|
This safe-guards against the possibility of "undefined behavior" or otherwise
|
||
|
as presented in the above example. However, this isn't *always* feasible,
|
||
|
especially when a programmers needs to accomplish tasks such as freeing
|
||
|
memory.
|
||
|
|
||
|
Other counter-measures, in this case, can protect against this. See below.
|
||
|
|
||
|
2) ignoring signals during signal handling routines -
|
||
|
|
||
|
As the obvious suggests, this programming practice will indefinately prevent
|
||
|
handling of signals during the execution of signal handling routines, thus
|
||
|
preventing signal handler reentry.
|
||
|
|
||
|
Consider the following signal handler template:
|
||
|
|
||
|
--- sighdlr.c ---
|
||
|
void sighdlr() {
|
||
|
signal(SIGINT, SIG_IGN);
|
||
|
signal(SIGABRT, SIG_IGN);
|
||
|
signal(SIGHUP, SIG_IGN);
|
||
|
/* ...ignore other signals ... */
|
||
|
|
||
|
/* cleanup code here */
|
||
|
|
||
|
exit(0);
|
||
|
}
|
||
|
--- EOF ---
|
||
|
|
||
|
As we can see above, signals are blocked before doing anything else in the
|
||
|
signal handling routine. This guarantees against signal handler reentry (or
|
||
|
almost does).
|
||
|
|
||
|
3) Ignoring signals whilst non-atomic process modifications are in place -
|
||
|
|
||
|
This involves blocking signals, in a similar way to the above code snippet,
|
||
|
during the execution of code with non-atomic modifications in place, such as
|
||
|
code execution with superuser privileges.
|
||
|
|
||
|
Consider the following code snippet:
|
||
|
|
||
|
--- nonatomicblock.c ---
|
||
|
/* code exec with non-atomic process modifications
|
||
|
starts here... */
|
||
|
signal(SIGINT, SIG_IGN);
|
||
|
signal(SIGABRT, SIG_IGN);
|
||
|
signal(SIGHUP, SIG_IGN);
|
||
|
/* block other signals if desired... */
|
||
|
|
||
|
setuid(0);
|
||
|
/* sensitive code here */
|
||
|
|
||
|
setuid(getuid());
|
||
|
/* sensitive code ends here */
|
||
|
|
||
|
signal(SIGINT, SIG_DFL);
|
||
|
signal(SIGABRT, SIG_DFL);
|
||
|
signal(SIGHUP, SIG_DFL);
|
||
|
|
||
|
/* ...code here... */
|
||
|
--- EOF ---
|
||
|
|
||
|
Before executing privileged code, signals are blocked. After execution of the
|
||
|
privileged code, privileges are dropped, and the signal action is set back to
|
||
|
the default action.
|
||
|
|
||
|
There are probably more ways of preventing signal vulnerabilities, but the
|
||
|
three above should be enough to implement semi-safe signal handlers.
|
||
|
|
||
|
|
||
|
|
||
|
Conclusion
|
||
|
###########
|
||
|
|
||
|
I hope this paper has at least touched upon possible problems encountered when
|
||
|
dealing with signals in C applications. If nothing else can be taken away from
|
||
|
this paper, my aim is to have outlined that secure programming practices should
|
||
|
always be applied when implementing signal handlers.
|
||
|
Full stop. Remember this.
|
||
|
|
||
|
If I have missed something out, given inaccurate information, or otherwise,
|
||
|
please feel free to drop me a line at the email address at the top of the
|
||
|
paper, providing your comments are nicely phrased.
|
||
|
|
||
|
Recommended reading is presented in the Bibliography below.
|
||
|
|
||
|
|
||
|
|
||
|
Bibliography
|
||
|
#############
|
||
|
|
||
|
Recommended reading material is:
|
||
|
|
||
|
--
|
||
|
"Delivering Signals for Fun and Profit" -
|
||
|
http://razor.bindview.com/publish/papers/signals.txt,
|
||
|
Michal Zalewski. Michal's
|
||
|
|
||
|
paper was a useful resource when writing this paper, and many ideas were gained
|
||
|
from this paper. Thanks Michal.
|
||
|
|
||
|
"Introduction To Unix Signals Programming" -
|
||
|
http://users.actcom.co.il/~choo/lupg/tutorials/signals/signals-programming.html,LUGPs.
|
||
|
|
||
|
"Procmail insecure signal handling vulnerability" -
|
||
|
http://xforce.iss.net/xforce/xfdb/6872
|
||
|
|
||
|
"Traceroute signal handling vulnerability" -
|
||
|
http://lwn.net/2000/1012/a/traceroute.php3
|
||
|
|
||
|
"signal(2) man page" -
|
||
|
http://techpubs.sgi.com/library/tpl/cgi-bin/getdoc.cgi?coll=linux&db=man&fname=/usr/share/catman/man2/signal.2.html&srch=signal
|
||
|
|
||
|
"signal(7) man page" -
|
||
|
http://techpubs.sgi.com/library/tpl/cgi-bin/getdoc.cgi?coll=linux&db=man&fname=/usr/share/catman/man7/signal.7.html&srch=signal
|
||
|
|
||
|
--
|
||
|
|
||
|
|
||
|
|
||
|
Greets
|
||
|
#######
|
||
|
|
||
|
Greets to:
|
||
|
|
||
|
--
|
||
|
Friends at HDC (or former HDC members), excluded.org,
|
||
|
#hackcanada, all @ GSO,
|
||
|
rider (happy be-lated birthday!).
|
||
|
|
||
|
All the other great people that I have met online.
|
||
|
--
|
||
|
|
||
|
Thanks guys.
|
||
|
|
||
|
|
||
|
Thank you for your time.
|
||
|
Shaun.
|
||
|
|
||
|
|=----------------------------------------------------------------------=|
|
||
|
|=----------------------------------------------------------------------=|
|
||
|
|
||
|
|=------------------=[ Pirating A Radio Station ]=----------------------=|
|
||
|
by j kuinga" <kuinga@hotmail.com>
|
||
|
|
||
|
At many Radio Stations to cut costs they now do what is called "central
|
||
|
casting." This is where many feeds are produced from one building and
|
||
|
handled by a group of engineers.
|
||
|
|
||
|
Why is this important? You could, disrupt the broadcast from the Central
|
||
|
Site, to the tower site, and create your own programming, without the
|
||
|
hassles of buying a transmitter, getting the FCC licensing, and that type
|
||
|
of thing. We're showing you two different ways to have some fun--by
|
||
|
interrupting remote broadcasts, and by overtaking the radio station.
|
||
|
|
||
|
Radio Stations typically have Martis which are mini-transmitters, and
|
||
|
Marti Repeaters, typically in the 425-455 MHz Range. Some Ham Transmitters
|
||
|
will work in this range, and if not, check your local radio surplus store.
|
||
|
|
||
|
Martis are typically used to rebroadcast High School Football and
|
||
|
basketball games, as well as commercial "live events" and its something as
|
||
|
simple as over-powering the signal, in order to get your message through.
|
||
|
Be forewarned, there typically is a live person on the other end of that
|
||
|
transmitterXtheyre probably not paying attention, because theyre
|
||
|
getting paid $5.50/hourXbut, they have they ability to turn you off.
|
||
|
|
||
|
How to find the frequency? Well, you could always SE the engineer at the
|
||
|
station and ask, however, most of them are grumpy old radio buffs, so you
|
||
|
might not get anywhere. I suggest a good copy of Police Call, which has
|
||
|
a LOT of frequencies in there for things like radio stations.
|
||
|
|
||
|
I use a home-made setup for finding particular frequencies out. Having some
|
||
|
essential tools like a good, directional antenna, frequency counter, and
|
||
|
very accurate transmitter, along with breadboard and essential components,
|
||
|
typically are common in finding what you need to know. I also drive a Big
|
||
|
White Van, complete with Mast and Bucket, so I can optimally 'place' the
|
||
|
antenna at the right height and direction, that I obtained at a school
|
||
|
auction for reallly cheap. (e.g., under $500, even had 18" racks in it and a
|
||
|
nice generator)
|
||
|
|
||
|
Most Radio Stations doing this have what they call a STL, or Studio to
|
||
|
Transmitter Link. This is typically in the 800 or 900 Mhz range, and the
|
||
|
same, general ideas apply. You find the general direction in which the
|
||
|
antenna is pointed, then you overpower the signal. Since you
|
||
|
(idealistically) would be within a few miles of the transmitter, not 30 or
|
||
|
50 miles like the Central-Casting spot, you would overpower the transmitter,
|
||
|
and start your own pirate radio station. Most stations however, have an
|
||
|
Air monitor, and can turn the remote transmitter off by pressing a
|
||
|
button on their STL. However, if youre closer to it, youve got control
|
||
|
until the station engineer comes down to manually pull the plug on your
|
||
|
transmitter.
|
||
|
|
||
|
If you see black vans with antennas and they look like they're doing sweeps,
|
||
|
chances are, they're either a) with the audit crew of the local cable
|
||
|
company, or b) looking for your ass.
|
||
|
|
||
|
kuinga@hotmail.com
|
||
|
|
||
|
|
||
|
|=[ EOF ]=---------------------------------------------------------------=|
|
||
|
|