Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 12/08/14 in all areas

  1. Abstract This article is especially designed to show how to crack a Java executable by disassembling the corresponding bytes code. Disassembling of Java bytecode is the act of transforming Java bytecode to Java source code. Disassembling is an inherent issue in the software industry, causing revenue loss due to software piracy. Security engineers have made an effort to resist disassembling techniques, including software watermarking, code obfuscation, in the context of Java bytecode disassembling. A huge allotment of this paper is dedicated to tactics that are commonly considered to be reverse engineering. The methods presented here, however, are intended for professional software developers and each technique is based on custom created application. We are not encouraging any kind of malicious hacking approach by presenting this article; in fact the contents of this paper help to pinpoint the vulnerability in the source code and learn the various methods developers can use in order to shield their intellectual property from reverse engineering. We shall explain the process of disassembling in terms of obtaining sensitive information from source code and cracking a Java executable without having the original source code. Prerequisite I presume that the aspirant would have thorough understanding of programming, debugging and compiling in JAVA on various platforms such as Linux and Windows and, of course, knowledge of JVM’s inner workings. Apart from that, the following tools are required to manipulate bytecode reverse engineering; JDK Toolkit (Javac, javap) Eclipse JVM JAD Java Bytecode Engineers usually construct software in a high-level language such as Java, which is comprehensible to them but which in fact, cannot be executed by the machine directly. Such a textual form of a computer program, known as source code, is converted into a form that the computer can directly execute. Java source code is compiled into an intermediate language known as Java bytecode, which is not directly executed by the CPU but rather, is executed by a Java virtual machine (JVM). Compilation is typically the act of transforming a high-level language into a low-level language such as machine code or bytecode. We do not need to understand Java bytecode, but doing so can assist debugging and can improve performance and memory convention. The JVM is essentially a simple stack-based machine that can be separated into a couple of segments; for instance, stack, heap, registers, method area, and native method stacks. An advantage of the virtual machine architecture is portability: Any machine that implements the Java virtual machine specification is able to execute Java bytecode in a manner of “Write once, run anywhere.” Java bytecode is not strictly linked to the Java language and there are many compilers, and other tools, available that produce Java bytecode, such as the Eclipse IDE, Netbeans, and the Jasmin bytecode assembler. Another advantage of the Java virtual machine is the runtime type safety of programs. The Java virtual machine defines the required behavior of a Java virtual machine but does not specify any implementation details. Therefore the implementation of the Java virtual machine specification can be designed different ways for diverse platforms as long as it adheres to the specification. Sample Cracked Application The subsequent Java console application “LoginTest” is developed in order to explain Java bytecode disassembling. This application typically tests valid users by passing them through a simple login user name and password mechanism. We have got this application from other resources as an unregistered user and obviously we don’t possess the source code of this application. As a result, we do not know a valid user name and password, which are only provided to the registered user. Without having the source code of the application or login credential sets, we still can manage to login into this mechanism, by disassembling its bytecode where we can expose sensitive information related to user login. Disassemble Bytecode Disassembling is the reverse approach, due to the standard and well-documented structure of bytecode, which is an act of transforming a low-level language into a high-level language. It basically generates the source code from Java bytecode. We typically run a disassembler to obtain the source code for the given bytecode, just as running a compiler yields bytecode from the source code. Disassembling is utilized to ascertain the implementation logic despite the absence of the relevant documentation and the source code, which is why vendors explicitly prohibit disassembling and reverse engineering in the license agreement. Here are some of the reasons to decompile: Fixing critical bugs in the software for which no source code exists. Troubleshooting a software or jar that does not have proper documentation. Recovering the source code that was accidentally lost. Learning the implementation of a mechanism. Learning to protect your code from reverse engineering. The process of disassembling Java bytecode is quite simple, not as complex as native c/c++ binary. The first step is to compile the Java source code file, which has the *.java extension through javac utility that produce a *.class file from the original source code in which bytecode typically resides. Finally, by using javap, which is a built-n utility of the JDK toolkit, we can disassemble the bytecode from the corresponding *.class file. The javap utility stores its output in *.bc file. Opening a *.class file does not mean that we access the entire implementation logic of a mechanism. If we try to open the generated bytecode file through notepad or any editor after compiling the Java source code file using javac utility, we surprisingly find some bizarre or strange data in the class file which are totally incomprehensible. The following figure displays the .class files data: So the idea of opening the class file directly isn’t at all successful, hence we shall use WinHex editor to disassemble the bytecode, which will produce the implementation logic in hexadecimal bytes, along with the strings that are manipulated in the application. Although we can reverse engineer or reveal sensitive information of a Java application using WinHex editor, this operation is sophisticated because unless we have the knowledge to match the hex byte reference to the corresponding instructions in the source code we can’t obtain much information. Reversing Bytecode It is relatively easy to disassemble the bytecode of a Java application, compared to other binaries. The javap in-built utility that ships with the JDK toolkit plays a significant role in disassembling Java bytecode, as well as helping to reveal sensitive information. It typically accepts a *.class file as an argument, as following: Drive:> Javap LoginTest Once this command is executed, it shows the real source code behind the class file; but remember one thing: It does display only the methods signature used in the source code, as follows: Compiled from “LoginTest.java” public class LoginTest { public LoginTest(); public static void main(java.lang.String[]); static boolean verify(java.lang.String, char[]); } The entire source code of the Java executable, even if it contains methods related to opcodes, would be showcased by the javap –c switch, as following: Drive:> Javap –c LoginTest This command dumps the entire bytecode of the program in the form of a special opcode instruction. The meaning of each instruction in the context of this program will be explained in a later section of this paper. I have highlighted the important section, from which we can obtain critical information. Compiled from "LoginTest.java" public class LoginTest { public LoginTest(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: invokestatic #2 // Method java/lang/System.console:()Ljava/io/Console; 3: astore_1 4: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream; 7: ldc #4 // String Login Verification 9: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 12: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream; 15: ldc #6 // String ************************ 17: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 20: aload_1 21: ldc #7 // String Enter username: 23: iconst_0 24: anewarray #8 // class java/lang/Object 27: invokevirtual #9 // Method java/io/Console.printf:(Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/Console; 30: pop 31: aload_1 32: invokevirtual #10 // Method java/io/Console.readLine:()Ljava/lang/String; 35: astore_2 36: aload_1 37: ldc #11 // String Enter password: 39: iconst_0 40: anewarray #8 // class java/lang/Object 43: invokevirtual #9 // Method java/io/Console.printf:(Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/Console; 46: pop 47: aload_1 48: invokevirtual #12 // Method java/io/Console.readPassword:()[C 51: astore_3 52: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream; 55: ldc #13 // String ------------------------- 57: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 60: aload_2 61: aload_3 62: invokestatic #14 // Method verify:(Ljava/lang/String;[C)Z 65: ifeq 79 68: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream; 71: ldc #15 // String Status::Login Succesfull 73: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 76: goto 87 79: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream; 82: ldc #16 // String Status::Login Failed 84: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 87: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream; 90: ldc #13 // String ------------------------- 92: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 95: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream; 98: ldc #17 // String !!!Thank you!!! 100: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 103: return … } From line 62, we can easily conclude that the login mechanism is implemented using a method called verify that typically checks either the user-entered username and password. If the user enters the correct password, then the “Login success” message flashes, otherwise: 62: invokestatic #14 // Method verify:(Ljava/lang/String;[C)Z 65: ifeq 79 68: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream; 71: ldc #15 // String Status::Login Succesfull 73: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 76: goto 87 79: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream; 82: ldc #16 // String Status::Login Failed But still we are unable to grab the username and password information. But, if we analyze the verify methods instruction, we can easily find that the username and password are hard-coded in the code itself, highlighted in the colored box as following: static boolean verify(java.lang.String, char[]); Code: 0: new #18 // class java/lang/String 3: dup 4: aload_1 5: invokespecial #19 // Method java/lang/String."<init>":([C)V 8: astore_2 9: aload_0 10: ldc #20 // String ajay 12: invokevirtual #21 // Method java/lang/String.equals:(Ljava/lang/Object;)Z 15: ifeq 29 18: aload_2 19: ldc #22 // String test 21: invokevirtual #21 // Method java/lang/String.equals:(Ljava/lang/Object;)Z 24: ifeq 29 27: iconst_1 28: ireturn 29: iconst_0 30: ireturn } We finally come to the conclusion that this program accepts ajay as the username and test as the password, which is mentioned in the ldc instruction. Now launch the application once again and enter the aforesaid credentials. Bingo!!!! We have successfully subverted the login authentication mechanism without even having the source code: Bytecode Instruction Specification Like Assembly programming, Java machine code representation is done via bytecode opcodes, which are the forms of instruction that the JVM executes on any platform. Java bytecodes typically offer 256 diverse mnemonic and each is one byte in length. Java bytecodes instructions fall into these major categories: Load and store Method invocation and return Control transfer Arithmetical operation Type conversion Object manipulation Operand stack management We shall only discuss the opcode instructions that are used in the previous Java binary. The following table illustrates the usage meanings as well as the corresponding hex value: Java Opcodes Meaning Hex value Aload Load a reference onto the stack from a local variable 19 Aload_0 Load a reference onto the stack from local variable 0 2a Aload_1 Load a reference onto the stack from local variable 1 2b Aload_2 Load a reference onto the stack from local variable 2 2c anewarray Create a new array of references of length count and component type identified by the class reference index in the constant pool. bd Astore Store a reference into a local variable 3a astore_0 Store a reference into local variable 0 4b astore_1 Store a reference into local variable 1 4c astore_2 Store a reference into local variable 2 4d dup Duplicate the value on top of the stack 59 getstatic Get a static field value of a class, where the field is identified by field reference in the constant pool index B2 goto Goes to another instruction at branch offset A7 invokespecial Invoke instance method on object objectref, where the method is identified by method reference index in constant pool B7 invokestatic Invoke a static method, where the method is identified by method reference index in constant pool B8 invokevirtual Invoke virtual method on object objectref, where the method is identified by method reference index in constant pool B6 ifeq If value is 0, branch to instruction atbranchoffset 99 Iconst_0 Load the int value 0 onto the stack 03 Iconst_1 Load the int value 1 onto the stack 04 ireturn Return an integer from a method ac ldc Push a constant index from a constant pool 12 pop Discard the top value on the stack 57 return Return void from method B1 In Brief This paper illustrates the mechanism of disassembling Java bytecode in order to reveal sensitive information when you do not have the source of the Java binary. We have come to an understanding of how to implement such reverse engineering tactics by using JDK utilities. This article also unfolds the importance of bytecode disassembling and JVM internal workings in the context of reverse bytecode and it also explains the meaning of essential bytecode opcode in detail. Finally, we have seen how to subvert login authentication on a live Java console application by applying disassembly tactics. In the forthcoming paper, we shall explain how to patch Java bytecode in the context of revere engineering. Reference Demystifying Java Internals (An introduction) - InfoSec Institute Source
    1 point
  2. Implanting malicious code in the form of spyware to an existing running process is one of the more sophisticated tasks. Before the advent of disassembler or patching tools, the malevolent code is usually invoked from the hard-core programming code, which is a very exhaustive process in itself, because we had gone through with programming code written especially in C or VC++. This paper demonstrates exclusively the invoking of a covert code along with the foremost executable by using OllyDbg and IDA Pro disassemblers. Such covert malicious code is triggered without the having the assent of the user; more precisely, the moment when the specific methods are executed from the leading EXE, the spyware becomes automatically activated surreptitiously. Essential The subsequent operation requires an exhaustive understanding of Hexadecimal Code and Assembly Programming. This operation lists the following tools of the trade as: The Victim Binary Spyware Executable OllyDbg IDA Pro Interactive Dissembler The Target Binary (Victim) We shall deploy the spyware in a simple Game Registration executable to showcase the code injections mechanism. The Game Registration typically requires serial keys to validate the authentic copy of this product and register or enable the full version as shown below. Figure 1.1: Target GUI This EXE is chosen to be a victim infected with a covert spyware. It doesn’t matter what is the actual name and serial keys of that program. We are in fact not provided with such sensitive information. The key matter of interest for the reverse engineer is the subsequent Error box which typically appears when a serial key is not validated. Figure 1.2: Error Message in Target This Error message box would become the entry point of the malicious covert code. The moment when the user is confronted with the aforesaid Error message box, the spyware becomes executed. That is what we are trying to achieve in this paper. Spyware Code The following spyware program typically shows the machine name and IP address of the computer where it runs and sends back such critical information to the hacker server. We don’t need to go into details of the spyware code. It could be any EXE program which injects into a binary. After compiling that code, it will look like as the following figure. It is showing a fake value of the computer name and IP address because crucial values are not disclosed due to a security point view. Figure 1.3: The Spyware GUI Victim Binary Analysis One question might bother you: why do we need IDA Pro, while we can perform code injection using OllyDbg itself? IDA Pro assists you to identify the entry point instruction code of the jump statement from where the message box assembly instruction starts to execute. As we have described earlier, the prime matter of interest is to get the details about the message box activation code. Here, we can easily identify the first message box occurrence after the 0040115E offset. Well, this code manipulates a couple of other message boxes indeed. But we have to recognize the very first message box. Figure 1.4: Message Box invoking instruction in Target So, we will search at 0040115E offset in the OllyDbg to find the message box assembly code in order to modify it to suit our need. We can duly confirm the message box occurrence by placing a breakpoint at 0040115E in IDA Pro and start debugging. If we entered a short name, then the graph view of the assembly code clearly indicates the execution flow toward the message box code as follows: Figure 1.5: Target Execution Flow Spyware Injection Now, it’s show time. Open the victim.exe binary in the OllyDbg to inject the spyware code. Here, the $ sign at offset 004015ED indicates the entry point of the executable as follows: Figure 1.6: Target Entry Point in OllyDbg Every executable has some empty space referred to as Code Caves where we can place or inject any external binary code. So, if you scroll down a little bit, you will easily identify the blank area named as DB 00 or NOP in the assembly code. Figure 1.7: Empty Regions (Code caves) in Target As from the aforesaid figure 1.7, the DB 00 instruction starts from the 00405188 offset. So, we shall place our external spyware code in these code caves. Select a couple code caves instructions and right click, choose Binary and then edit as follows: Figure 1.8: Binary Editing in Target NOTE: place both victim.exe and spyware.exe into single directory folder Now, label the spyware program executable as spyware.exe in the ASCII box, as we have selected code caves from 0040518A, which means start editing from this instruction. Its corresponding hex code is automatically generated and placed at the 0040518A offset. Figure 1.9: Placing Spyware Name in Target NOTE: Assembly is strict Case-Sensitive language. So be cautious while entering the names in ASCII box. After pressing the OK button in figure 1.9, some raw uncomprehend-able code is generated at offset 0040518A in the RED COLOR as follows: Figure 1.10: Injected Spyware code in Target Don’t worry, just analyze the code by pressing CTRL+ A now, and this time, we get the original entered code which virtually shows the spyware victim.exe name as follows: Figure 1.11: Analysis in Target Now, we have to write the spyware offset address value into memory. However, move forward just one step and at offset 00405195, press space bar button. Here, we found assemble code box. Just enter PUSH 1 here and click on the Assemble button. Figure 1.12: Injecting PUSH instruction Target Again come to the 00405197 offset and press the space bar; here enter the PUSH 40518A code which pushes the spyware EXE instruction into memory. Figure 1.13: Injecting Spyware name in PUSH Here, notice that we are giving the reference of spyware.exe located at offset 0040518A to 00405198 as follows: Figure 1.14: Giving Spyware name in PUSH Our spyware program is having an *.exe format. So we have to instruct the Assembly code by calling the CALL WinExec instruction: we are injecting an external executable which has of course .exe extension. Figure 1.15: Calling Exe in Assembly Language After finishing with arbitrary code injection related to spyware, the modified assembly looks like the following: igure 1.16: Injected Assembly Code Now we have to connect that new injected code with a message box occurrence instruction, otherwise it won’t be executed. As referenced in figure 1.4, press CTRL +G and enter the 0040115E offset. Figure 1.17: Jump to 0040115E via Expression This action directly lets us reach the entry point of the first message box as follows. Here, we have to perform some significant modifications. Figure 1.18: Message Box code entry point Now, select the 0040115E offset and press space bar, then copy the JNB 00401189 instruction into the clipboard as follows: Figure 1.19: Copy the code Thereafter, come back to inject code by pressing the “-”(minus) button, there select offset 004051A1 to assemble new code and press the space button and paste the JNB 00401189 instruction. We shall discuss shortly what we are doing. Figure 1.20: Paste instruction Ok, now copy the offset address 00405196 in the clipboard from the First PUSH 1 in the new injected code. Figure 1.21: Copy offsets Again go to offset 0040115E where the message box code is located, select the instruction set at 0040115E, and press the space bar. Finally, replace the existing code with new. Assemble the JNB 00405196 instruction here. igure 1.22: Assemble instruction So, what are we actually doing here? First we are giving the reference of the PUSH 1 instruction offset (00405196) to the jump instruction located at offset 0040115E. Secondly, pasting the JNB 00401189 instruction to the 004051A1 offset as follows: Figure 1.23: Graph diagram of offsets jumping Basically, the aforesaid figure indicates that after entering the user name and serial key in the victim.exe, first the error message box would display and then our spyware program would activate. We have finished with the code injections tactics. Now make changes permanent and write the modified bytes into memory by right clicking on the ASM code and select the Copy to Executable option, where we choose All Modifications as follows: Figure 1.24: Saving changes Now, select the Copy all option in the forthcoming dialog box, which produces a separate dialog box as follows, where the final assemble code collectively resides. Figure 1.25: New Assemble code Finally, close the dialog box in figure 1.25. The moment you close the dialog box, the Save as dialog box appears and it asks to get new name to the patched EXE file. We shall provide victim_Patched.exe as follows: Figure 1.26: Save As binary Now, run the victim_Patched.exe and enter any fake values as a user name and serial key. It is obvious that such entered credentials are invalidated and an Error message would display. Figure 1.27: Testing The moment the Error message appears about invalid credentials and we move forward by clicking the OK button, the spyware program is automatically activated and shows the machine name and IP address on which it is running and later sends this information back to a remote server. Figure 1.28: Spyware program Final Note This article presents a step by step tutorial of injecting a malicious spyware program into any executable by using IDA Pro and OllyDbg. The IDA Pro was basically employed in order to identify the entry point message box occurrence and OllyDbg implanted the existing EXE. Basically, this tutorial demonstrates how to place an EXE into another EXE. The idea behind code injection is to identify the occurrence of an entry point which is referred to as a triggering point to an injected EXE, and later modify the JUMP statements in order to divert the execution toward the injected code. Source
    1 point
  3. TLS (thread local storage) calls are subroutines that are executed before the entry point . There is a section in the PE header that describes the place of a TLS callback. Malwares employ TLS callbacks to evade debugger messages. When a particular malware employed with TLS callbacks is loaded into a debugger, the malware finishes its work before the debugger stops at the entry point. Let’s start with a simple example of a TLS callback in C: /***************************************** TLS Example Program Compile With MSVC ********************************************/ #include #pragma comment(linker, "/INCLUDE: tls_used") void NTAPI TlsCallBac(PVOID h, DWORD dwReason, PVOID pv); #pragma data_seg(".CRT$XLB") PIMAGE_TLS_CALLBACK p_thread_callback = TlsCallBac; #pragma data_seg() void NTAPI TlsCallBac(PVOID h, DWORD dwReason, PVOID pv) { MessageBox(NULL, "In TLS", "In TLS", MB_OK); return; } int main(int argc , char**argv) { MessageBox(NULL, "In Main", "In Main", MB_OK); return 0; } After running this program, the “In TLS” Message box will pop up first rather than “In Main.” This proves that TLS callbacks are executed before the entry point. Following is the dumpbin output of the exe compiled using the above code: FILE HEADER VALUES 14C machine (x86) 4 number of sections 52C01E9D time date stamp Sun Dec 29 18:37:41 2013 0 file pointer to symbol table 0 number of symbols E0 size of optional header 103 characteristics Relocations stripped Executable 32 bit word machine OPTIONAL HEADER VALUES 10B magic # (PE32) 8.00 linker version 7000 size of code 5000 size of initialized data 0 size of uninitialized data 1256 entry point (00401256) 1000 base of code 8000 base of data 400000 image base (00400000 to 0040CFFF) 1000 section alignment 1000 file alignment 4.00 operating system version 0.00 image version 4.00 subsystem version 0 Win32 version D000 size of image 1000 size of headers 0 checksum 3 subsystem (Windows CUI) 0 DLL characteristics 100000 size of stack reserve 1000 size of stack commit 100000 size of heap reserve 1000 size of heap commit 0 loader flags 10 number of directories 0 [ 0] RVA [size] of Export Directory 9524 [ 3C] RVA [size] of Import Directory 0 [ 0] RVA [size] of Resource Directory 0 [ 0] RVA [size] of Exception Directory 0 [ 0] RVA [size] of Certificates Directory 0 [ 0] RVA [size] of Base Relocation Directory 0 [ 0] RVA [size] of Debug Directory 0 [ 0] RVA [size] of Architecture Directory 0 [ 0] RVA [size] of Global Pointer Directory 9260 [ 18] RVA [size] of Thread Storage Directory 9218 [ 40] RVA [size] of Load Configuration Directory 0 [ 0] RVA [size] of Bound Import Directory 8000 [ F8] RVA [size] of Import Address Table Directory 0 [ 0] RVA [size] of Delay Import Directory 0 [ 0] RVA [size] of COM Descriptor Directory 0 [ 0] RVA [size] of Reserved Directory The Thread Storage Directory is filled up. The TLS directory is defined in MSDN as (http://msdn.microsoft.com/en-us/magazine/cc301808.aspx): typedef struct _IMAGE_TLS_DIRECTORY { UINT32 StartAddressOfRawData; UINT32 EndAddressOfRawData; PUINT32 AddressOfIndex; PIMAGE_TLS_CALLBACK *AddressOfCallBacks; UINT32 SizeOfZeroFill; UINT32 Characteristics; } IMAGE_TLS_DIRECTORY, *PIMAGE_TLS_DIRECTORY Let’s try to look at a sample that employs TLS callbacks. Supplying it to PEID says it has been packed with NULLSoft packer. Note: The first layer packer is irrelevant to this analysis, This packer basically creates injects inside a new process, which is the unpacked image: . This is a valid MZ image. If you look at the MZ image, you will notice a weird thing about the address of the entry point: 00000108 00000000 DD 00000000 ; AddressOfEntryPoint = 0 0000010C 00100000 DD 00001000 ; BaseOfCode = 1000 00000110 00800000 DD 00008000 ; BaseOfData = 8000 00000114 00004000 DD 00400000 ; ImageBase = 400000 As you can see, over there the address of the entry point is 0 but, at the same time, the TLS table is supplied: 000001A0 60920000 DD 00009260 ; TLS Table address = 9260 000001A4 18000000 DD 00000018 ; TLS Table size = 18 (24.) Here is the dump of the TLS table E4 96 00 00 F2 96 00 00 FE 96 00 00 0E 97 00 00 24 97 00 00 40 97 00 00 5A 97 00 00 72 97 00 00 8C 97 00 00 A2 97 00 00 B2 97 00 00 CC 97 00 00 DE 97 00 00 EC 97 00 00 FE 97 00 00 16 98 00 00 24 98 00 00 30 98 00 00 3E 98 00 00 48 98 00 00 that gives us the location of TLS entry point . There are two ways to catch TLS calls: 1 : Change the Ollydbg setting to the system breakpoint: 2 : Set up a hardware breakpoint at 0x7C9011A4 We will use the second method, which is more preferable. After loading the TLS application, it will stop here in the debugger: 7C901194 8BEC MOV EBP,ESP 7C901196 56 PUSH ESI 7C901197 57 PUSH EDI 7C901198 53 PUSH EBX 7C901199 8BF4 MOV ESI,ESP 7C90119B FF75 14 PUSH DWORD PTR SS:[EBP+14] 7C90119E FF75 10 PUSH DWORD PTR SS:[EBP+10] 7C9011A1 FF75 0C PUSH DWORD PTR SS:[EBP+C] 7C9011A4 FF55 08 CALL DWORD PTR SS:[EBP+8] ; TLS Callback 7C9011A7 8BE6 MOV ESP,ESI 7C9011A9 5B POP EBX 7C9011AA 5F POP EDI 7C9011AB 5E POP ESI 7C9011AC 5D POP EBP 7C9011AD C2 1000 RETN 10 Stepping inside the call leads us here. Now, to fix the PE header, we need fix the entry point of the application to the exact location of the TLS callback and the Zero TLS table value: 00401350 |. 56 PUSH ESI 00401351 |. 56 PUSH ESI 00401352 |. 56 PUSH ESI 00401353 |. 56 PUSH ESI 00401354 |. 56 PUSH ESI 00401355 |. C700 16000000 MOV DWORD PTR DS:[EAX],16 0040135B |. E8 57170000 CALL me.00402AB7 00401360 |. 83C4 14 ADD ESP,14 00401363 |. 6A 16 PUSH 16 00401365 |. 58 POP EAX 00401366 |. 5E POP ESI 00401367 |. C3 RETN 00401368 |> 3935 D4AC4000 CMP DWORD PTR DS:[40ACD4],ESI 0040136E |.^74 DB JE SHORT me.0040134B 00401370 |. 8B0D E0AC4000 MOV ECX,DWORD PTR DS:[40ACE0] 00401376 |. 8908 MOV DWORD PTR DS:[EAX],ECX 00401378 |. 33C0 XOR EAX,EAX 0040137A |. 5E POP ESI 0040137B . C3 RETN Change entry point = 0×0401350; 000000FC 00700000 DD 00007000 ; SizeOfCode = 7000 (28672.) 00000100 00500000 DD 00005000 ; SizeOfInitializedData = 5000 (20480.) 00000104 00000000 DD 00000000 ; SizeOfUninitializedData = 0 00000108 50134000 DD 00401350 ; AddressOfEntryPoint = 401350 0000010C 00100000 DD 00001000 ; BaseOfCode = 1000 00000110 00800000 DD 00008000 ; BaseOfData = 8000 00000114 00004000 DD 00400000 ; ImageBase = 400000 After this step, TLS callbacks won’t be called and you can start debugging your application from entry point. Source
    1 point
  4. Nmap, also (Network Mapper), is a free and open source port and security scanner for network security professionals, and apparently also for world’s IT hijackers. Although there are similar tools like portqry for scanning ports, they are not as much capable as Nmap. It is used to discover hosts, services and network resources on a computer networks. Some of the features that Nmap has include host discovery, port scanning, detection of services and applications running on target system, OS and hardware detection of remote hosts. All in all, it's very useful tool that can detect any opened, closed or filtered (firewalled) ports on remote system and determine which services may be running, thus creating network "map" that can help in understanding or enhancing networking security. Because Nmap is a very powerfull tool that can be misused, informations presented in this article are provided only to assist computer users in scanning their own networks, or networks for which they have been given permission to scan, in order of determining and enhancing network security, or simply for the learning process and better understanding of computer networks... Usage - scanning options Since most of todays modern firewalls and (IDS) Intrusion detection systems consider scaning or sniffing as a prelude to possible atack, scanning of remote systems for opened ports or running services is regarded as an unauthorized act. Therfore, such attemps from scanning tools might be blocked. In such situations, Nmap comes realy handy, because it can listen responses from victim's system and terminate connection even before it is established (SYN stealth scan). In this way, by properly configured nmap query, it is possible to successfuly sniff remote system and get useful informations. Nmap has a lot of scaning options that can be used with s option switch. (-sT -> TCP ports scan , -sU -> UDP ports scan, -sS -> SYN or Stealth scan, -sV -> Version Detection, etc...) Example of scanning internal network 192.168.10.0 for alive hosts: linux-box# nmap -sP 192.168.100.0/24 Starting Nmap 5.00 ( http://nmap.org ) at 2012-11-28 13:51 CET Host 192.168.100.10 is up (0.0013s latency). MAC Address: C0:D0:44:E6:1E:04 (Unknown) Host 192.168.100.102 is up (0.0091s latency). MAC Address: 00:4F:6A:08:4F:44 (Unknown) Host 192.168.100.200 is up. Nmap done: 256 IP addresses (3 hosts up) scanned in 3.21 seconds (As a result we can se IP and MAC addresses of alive hosts in scanned network.) Using stealth scan, "-sS" and "-A" options we can avoid that firewall detects our scan and see that 192.168.100.10 is actualy a gateway, an ADSL broadband router: linux-box# nmap -sS -A 192.168.100.10 Starting Nmap 5.00 ( http://nmap.org ) at 2012-11-28 14:00 CET Stats: 0:00:43 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan Service scan Timing: About 75.00% done; ETC: 14:01 (0:00:14 remaining) Interesting ports on 192.168.10.1: Not shown: 996 closed ports PORT STATE SERVICE VERSION 21/tcp open ftp US Robotics ADSL router firmware update ftpd 22/tcp open ssh Dropbear sshd 0.46 (protocol 2.0) |_ ssh-hostkey: 1040 9a:fb:c1:06:5c:05:70:bc:a5:54:d7:b7:c2:3a:b6:3f (RSA) 23/tcp open telnet? 80/tcp open http Comtrend ADSL http config (micro_httpd) |_ html-title: 401 Unauthorized | http-auth: HTTP Service requires authentication |_ Auth type: Basic, realm = DSL Router 1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at http://www.insecure.org/cgi-bin/servicefp-submit.cgi : SF:ty\.txt%2ebak\x20HTTP/1\.0\r\n\r\nPassword:\x20"); MAC Address: C0:D0:44:E6:1E:04 (Unknown) Device type: general purpose Running: Linux 2.6.X OS details: Linux 2.6.9 - 2.6.19 Network Distance: 1 hop Service Info: Device: broadband router OS and Service detection performed. Please report any incorrect results at http://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 117.51 seconds (By using "-A" option we enable OS fingerprinting and version detection.) Example of Operating system detection (fingerprinting) of scanned system: linux-box# nmap -O 192.168.100.202 Starting Nmap 5.00 ( http://nmap.org ) at 2012-11-28 14:35 CET Interesting ports on 192.168.100.202: Not shown: 993 filtered ports PORT STATE SERVICE 135/tcp open msrpc 139/tcp open netbios-ssn 445/tcp open microsoft-ds 902/tcp open iss-realsecure 912/tcp open unknown 5357/tcp open unknown 8443/tcp open https-alt MAC Address: 00:4F:6A:08:4F:44 (Unknown) Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port Device type: general purpose Running: Microsoft Windows Vista|2008 OS details: Microsoft Windows Vista or Windows Server 2008 SP1, Microsoft Windows Vista SP0 or SP1 or Server 2008 SP1 Network Distance: 1 hop OS detection performed. Please report any incorrect results at http://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 6.91 seconds Operating system detection (fingerprinting) on local internal network 192.168.100.0 255.255.255.0: linux-box# nmap -O -T insane 192.168.100.0/24 Starting Nmap 5.00 ( http://nmap.org ) at 2012-11-28 15:03 CET Interesting ports on 192.168.100.1: Not shown: 996 closed ports PORT STATE SERVICE 21/tcp open ftp 22/tcp open ssh 23/tcp open telnet 80/tcp open http MAC Address: C0:D0:44:E6:1E:04 (Unknown) Device type: general purpose|bridge|WAP|media device|PBX|webcam|phone Running (JUST GUESSING) : Linux 2.6.X|2.4.X (99%), Perle embedded (97%), FON Linux 2.6.X (96%), Toshiba embedded (94%), AXIS Linux 2.6.X (94%), RGB Spectrum embedded (93%), HTC Linux 2.6.X (93%) Aggressive OS guesses: Linux 2.6.22 (99%), Linux 2.6.9 - 2.6.19 (99%), Linux 2.6.13 - 2.6.27 (97%), Linux 2.6.9 - 2.6.28 (97%), Perle IOLAN DS1 Ethernet-to-serial bridge (97%), DD-WRT v24 (Linux 2.6.22) (96%), Linux 2.6.22 - 2.6.23 (96%), Linux 2.6.23 (96%), Linux 2.6.5 - 2.6.12 (96%), Linux 2.6.9 - 2.6.27 (96%) No exact OS matches for host (test conditions non-ideal). Network Distance: 1 hop Interesting ports on 192.168.100.102: Not shown: 993 filtered ports PORT STATE SERVICE 135/tcp open msrpc 139/tcp open netbios-ssn 445/tcp open microsoft-ds 902/tcp open iss-realsecure 912/tcp open unknown 5357/tcp open unknown 8443/tcp open https-alt MAC Address: 00:4F:6A:08:4F:44 (Unknown) Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port Device type: general purpose Running: Microsoft Windows Vista|2008 OS details: Microsoft Windows Vista SP0 or SP1 or Server 2008 SP1 Network Distance: 1 hop Interesting ports on 192.168.100.200: Not shown: 997 closed ports PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 111/tcp open rpcbind Device type: general purpose|WAP Running (JUST GUESSING) : Linux 2.6.X|2.4.X (95%), Gemtek embedded (90%), Siemens embedded (90%), Nokia Linux 2.6.X (89%) Aggressive OS guesses: Linux 2.6.17 - 2.6.28 (95%), Linux 2.6.19 - 2.6.26 (95%), Linux 2.6.22 (95%), Linux 2.6.19 - 2.6.24 (94%), Linux 2.6.22 (Ubuntu 7.10, x86_64) (94%), Linux 2.6.26 (94%), Linux 2.6.15 - 2.6.27 (92%), Linux 2.6.22 - 2.6.23 (92%), Linux 2.6.17 - 2.6.26 (92%), Linux 2.6.20-grml (92%) No exact OS matches for host (test conditions non-ideal). Network Distance: 0 hops OS detection performed. Please report any incorrect results at http://nmap.org/submit/ . Nmap done: 256 IP addresses (3 hosts up) scanned in 19.04 seconds (The "-T Insane" option tels nmap to do a very fast scan. This type of scan gets detected by firewalls and IDS, but since we're scanning our own local network this is ok.) Scanning 192.168.100.202 target system's UDP 5556 port: linux-box# nmap -sT -p 5556 192.168.100.202 Starting Nmap 5.00 ( http://nmap.org ) at 2012-11-28 14:48 CET Interesting ports on 192.168.10.102: PORT STATE SERVICE 5556/tcp open unknown MAC Address: 00:4F:6A:08:4F:44 (Unknown) Nmap done: 1 IP address (1 host up) scanned in 0.53 seconds Scanning range of UDP ports from 130 tp 135, and TCP ports from 18 to 23 on target system 192.168.100.200: linux-box# nmap -sU -sS -p U:130-135,T:18-23 192.168.100.200 Starting Nmap 5.00 ( http://nmap.org ) at 2012-11-28 14:59 CET Interesting ports on 192.168.100.200: PORT STATE SERVICE 18/tcp closed unknown 19/tcp closed chargen 20/tcp closed ftp-data 21/tcp closed ftp 22/tcp open ssh 23/tcp closed telnet 130/udp closed cisco-fna 131/udp closed cisco-tna 132/udp closed cisco-sys 133/udp closed statsrv 134/udp closed ingres-net 135/udp closed msrpc Nmap done: 1 IP address (1 host up) scanned in 0.21 seconds Source
    1 point
  5. Improper handling of session variables in asp.NET websites is considered a serious threat and opens various doors to malicious hackers. For instance, a session variable could be manipulated in a way to subvert login authentication mechanisms. However, this article illustrates a session fixation bug in a .NET website by demonstrating various live scenarios which usually leads to a website becoming vulnerable, in terms of session hijacking. Moreover, the article circulates detailed information about exploiting vulnerable websites, as well as recommendations of practices for protecting them against session fixation attacks. Internal Session Fixation A session fixation attack allows spoofing another valid user and working on behalf of their credentials. It typically fixates another person’s session identifier to breach currently happening communication. The asp.NET base website usually keeps session variables to track the user by creating a cookie called asp.NET_SessionId in the browser. A session variable is typically used to record a currently logged-in user, and such a cookie value is validated on each round-trip to ensure that the data being served is specific to that user. Here the following image is describing the process of cookies-based authentication, where the user performs the login operation to a vulnerable website, and in return, the server issues this particular user a cookie token value for session management. Figure: 1.1 Websites usually engage session management to construct a user-friendly environment. But this mechanism is vulnerable to some extent, because session IDs present an attractive target for attackers, as they are stored on a server and associated with respective users by unique session identifier values. There are a couple of approaches applied by the attacker to perform a session fixation attack, depending on the session ID transport mechanism (cookies, hidden fields, and URL arguments) and the loopholes identified on the target system. The mechanics of session management is that the server generates a unique session identifier value during user authentication, and sends this session ID back to the client browser and makes sure that this same ID will be sent back by the browser along with each forthcoming request. Hence, such a unique session ID value thereby becomes an identification token for users, and servers can use them to maintain session data. Figure: 1.2 An asp.NET_SessionID cookie is only configured by the server whenever working on behalf of any page request of the website. So when the login page is first accessed, the asp.NET_SessionID cookie value is set by the client browser and server uses this cookie value for all subsequent requests. Even after authentication is successful and logged out, the asp.NET_SessionID value does not change. This results in the possibility of a session fixation attack, where a hacker can potentially sniff the traffic across the wire or physically access the victim machine in order to get the stored cookie values in the browser and fix a victim’s session by accessing the login page, even if they don’t have the actual user name or password. The following image shows the real time session fixation attack scenario where a potential hacker sits somewhere in the network and intercepts the traffic happening between a server and client. Here, the hacker employs a packet sniffer to capture a valid token session and then utilizes the valid token session to gain unauthorized access to the web server. Finally, the hacker successfully accesses the asp.NET_SessionID value and logs in successfully to the website’s sensitive zone. Figure: 1.3 Vulnerable Code Scenario Session fixation bugs usually occur on websites which manipulate sensitive data while transacting or incorporating with the login page to authenticate valid users with correct user name and password. This paper illustrates this crucial bug in detail by presenting this vulnerable login authentication code as follows: if (txtUsr.Text.Equals("frank") && txtPwd.Text.Equals("password")) { Session["LIn"] = txtU.Text.Trim(); Server.Transfer("<a title="Home" href="http://resources.infosecinstitute.com/">Home</a>.aspx"); } else { lblMessage.Text = "Wrong username or password"; } When a user browses this website and enters the valid credentials for authentication, the internal mechanism flashes the server message that either the user name and password are correct or incorrect as follows: Figure: 1.4 The user typically assumes that this transaction is safe and there are fewer possibilities of other website-related attacks, but still, a couple of serious attacks such as spoofing, replay and session hijacking attacks could be possible, even if managing the user name and password correctly. We shall see this in a forthcoming segment of this article. Stealing Cookies Valid session IDs are not only recognized to be identification tokens, but also employed as an authenticators. Users are authenticated based on their login credentials (e.g. user names and passwords) and are issued session IDs that will effectively serve as temporary static passwords for accessing their sessions, which makes session IDs a very appealing target for attackers. The moment a user enters his credentials on login to authenticate, these data are stored in the session and cookies are generated in the client browser. The user is typically over-confident that when he is logged out, all the data would be scrubbed automatically and the session is terminated, but unfortunately, the cookie values are not deleted from the client browser, even if the session is ended, and such cookie values could be exploited by a hacker to breach into the website’s sensitive zone, without being aware of user name and password. As the following figure shows, when a user is logged in, the browser shows cookie values which are generated during authentication as: Figure: 1.5 Now log out and refresh the page. It is generally assumed that cookie values should be wiped-out automatically at the time of ending the current session, but even after proper sign-out from the current session, which is performing Session.Abandon(), Session.Clear() implicitly, the browser is still showing the previous session’s generated cookies values as follows: Figure: 1.6 Hence, revealing cookie values even without being logged in could be considered a serious threat and opens the doors to a session hijacking attack. A malicious hacker could directly access the sensitive zone of a website without being logged in by adding such retrieved cookie details manually to the browser. Here, the attacker typically uses this technique to inject the stolen cookies in the browser to hijack the someone else’s current session as follows: Defense (Securing Cookies) Countermeasures combine several approaches to overcome such session hijacking attacks. For instance, making cookie values bullet-proof by HttpOnly, explicitly removing session cookie values, employing HTTPS/ TLS (via Secure Attribute) and proper configuration. This section fixes the session hijacking vulnerability in the aforesaid code, where cookie values are not discarded even after logout, by generating another cookie having a unique value which is compared to the session value at each round-trip. Resemblance of both of these values could allow the user to enter into the website’s sensitive zone; otherwise the user is redirected to the login page. This generates a unique value never to be duplicated and there is a very low chance that the value of the new GUID is all zeroes or equal to any other GUID. Hence, such an applied random token ensures protection against a CSRF attack in a website. protected void Page_Load(object sender, EventArgs e) { if (Session["LIn"] != null && Session["AuthToken"] != null && Request.Cookies["AuthToken"] != null) { if (!Session["AuthToken"].ToString().Equals( Request.Cookies["AuthToken"].Value)) { lblMessage.Text = "You are not logged in."; } else { .. } } .. } This time in the sign-in button, another unique value GUID is generated and stored with the session variable AuthToken which is added to cookies later as follows: protected void btnLogin_Click(object sender, EventArgs e) { if (txtUsr.Text.Equals("frank") && txtPwd.Text.Equals("password")) { Session["LIn"] = txtU.Text.Trim(); string guid = Guid.NewGuid().ToString(); Session["AuthToken"] = guid; // now create a new cookie with this guid value Response.Cookies.Add(new HttpCookie("AuthToken", guid)); } .. } Finally, the logout button has the code to expire the session cookie values explicitly, which removes them from the client browser permanently. Here, we shall have to remove both session asp.NET_SessionId and AuthToken variables as follows: protected void btnLogout_Click(object sender, EventArgs e) { Session.Clear(); Session.Abandon(); Session.RemoveAll(); if (Request.Cookies["asp.NET_SessionId"] != null) { Response.Cookies["asp.NET_SessionId"].Value = string.Empty; Response.Cookies["asp.NET_SessionId"].Expires = DateTime.Now.AddMonths(-20); } if (Request.Cookies["AuthToken"] != null) { Response.Cookies["AuthToken"].Value = string.Empty; Response.Cookies["AuthToken"].Expires = DateTime.Now.AddMonths(-20); } } Okay, now browse the website again and login with the correct credentials and compare the output in the firebug with the previous output shown in figure 1.5. Here another session value AuthToken with new cookies is generated as follows: Figure: 1.7 Thereafter, sign out from the current session as earlier and refresh the page and notice the cookies section in the firebug again. Bingo! This time the browser doesn’t retain any previously stored cookie values. Hence, making cookie values bullet-proof ensures to protect against session fixation attack. Figure: 1.8 Final Note This article has explained the session fixation attack on asp.NET website in detail by giving the real time code scenario, and also pinpoints the common glitches committed by programmer at time of coding of sensitive parts like login pages. We have seen how a potential hacker can access the cookies values stored in the client browser in order to execute a session hijacking attack and breach into the sensitive zone of a website, even without being aware or having a real user name and password. Finally, we have come to an understanding to secure or make bullet-proof the cookie session values to protect our website from session fixation attack. Source
    1 point
  6. Samurai Web Testing Framework [h=2]Description[/h] The Samurai Web Testing Framework is a LiveCD focused on web application testing. We have collected the top testing tools and pre-installed them to build the perfect environment for testing applications. Samurai Web Site Download: Download Samurai from SourceForge.net Sursa: Samurai | SourceForge.net
    1 point
×
×
  • Create New...