|
Windows firewall TCP deviations
After I ported Ncrack to Windows and conducted some tests, I came across a really bizzare TCP behaviour,
which completely violates RFC 793 rules. In summary, when the Windows default firewall is enabled and
the peer we are connected to, sends a FIN to close the connection on his side then Windows acknowledges
the FIN (as it should) and then immediately sends an RST to the peer completely killing the connection!
This practically doesn't allow ourselves to send any additional data (which is perfectly legal to do, since
we haven't closed the connection on our part) and also potentially disallows us from reading any last data
that the peer had sent before closing the connection. The latter might happen if we haven't called read(2)
before the peer's FIN arrives, since after Windows sends the RST any receive-buffers for the connection
are nullified. There is an ongoing discussion about the issue at
nmap-dev
This illicit behaviour has caused a lot of frustration to
others as well. I am starting to think
about reporting this to Microsoft.
-- ithilgore, 27 June 2009
Exploiting TCP and the Persist Timer Infiniteness - Phrack #66
At last, the new phrack issue is out! A long time
ago, I had promised an article on exploiting the TCP Persist Timer. You can now read all about it
in phrack #66 here.
-- ithilgore, 13 June 2009
Ncrack
Plans have changed for this GSoC and I will be undertaking a more
challenging project on Nmap. Fyodor proposed a new network authentication
cracker, under the name Ncrack
which will be written from scratch but based on Nsock - an optimized parallel sockets library used
by NSE (Nmap Scripting Engine) as well as Nmap's service-scanner and parallel rDNS resolver.
At this stage, an initial overall planning about Ncrack's architecture is being carried out.
I have proposed a draft which can be found here.
-- ithilgore, 5 May 2009
IDS, UDP and DoS
I was taking a look at various papers on distributed intrusion detection
systems to get ideas for my own and happened to study this
one.
One of the main design decisions one has to make, is on which transport protocol
the agents are going to communicate with one another and with the central node
which collects all the data. The authors of the paper suggested using UDP and
multicasting. As far as multicasting is concerned, it is a fairly good practice
since it gives many benefits without adding overly much to the complexity. And as
we know, TCP can't be combined with multicasting. However using UDP can have really,
really negative security implications, especially with DoS attacks. The authors suggest
that in face of a DoS attack, TCP will probably fail to deliver any important data
due to ACK loss. They state in particular:
"Consider a LAN experiencing a DoS attack. If the LAN's intrusion detection system tried to
communicate with the central node using TCP through the LAN's upstream link, the connection
would probably fail to be established. Although the packets transmitted by the IDS would
reach their destination, the ACK packets would likely be dropped."
However, if TCP loses some ACK packets, it has many chances that it will later be able to
retransmit the packet successfully. TCP has a fairly robust congestion-avoidance algorithm
(which varies among implementations) and a retransmission mechanism that is far more reliable
than UDP can ever dream of acquiring. To implement a sufficiently reliable UDP delivery mechanism,
one has to at least reinvent the wheel, and probably fail in the process of doing so, since
TCP has been thoroughly tested over the years from this aspect.
A DoS attack can be easily carried through, with complete IP spoofing when UDP is used.
Any authentication (for example using digital signatures) has to be done, after
the datagram has been received in the process' receive socket buffer. So the attacker can
pretty easily craft a packet, spoofed with an IP of an agent and flood the ids with bogus
packets. If TCP was used, then at least IP spoofing would go as far as triggering the syn-cookies
mechanism which is not as terrible nowadays. Using TCP will complement a firewall's filtering to thwart such
an attack since any attempt to spoof the IP with that of an agent (suppose the firewall only allows
communication through a strict IP ACL that includes only the agent's IP addresses), will result in
at most filling the SYN queue, partially completing the 2way TCP handshake and thus at worst triggering
the syn-cookie mechanism as we said before. No such thing will happen with UDP. The specially crafted
packets will get through the firewall's ACL and will be delivered in the socket receive buffer flooding
it and thus disallowing any additional communication, unless other measures are taken.
-- ithilgore, 22 April 2009
Nmap GSoC
I was accepted in Google Summer of Code
and will be working on Nmap improving Ncat,
introducing raw socket support for IPv6 and creating an application abusing engine!
I am pretty excited about working officially on one of my favourite projects, the
best network exploration tool out there.
-- ithilgore, 20 April 2009
Asm raw sockets
I decided to post some simple old code that demonstrates that raw sockets can
be easily programmed in assembly, even if that sounds a bit crazy. Or maybe
not. Shellcode that uses raw sockets is nothing new, after all. The code
is pretty well commented, so I will provide no additional guide whatsoever.
It's really small anyway.
.section .data
.equ AF_INET, 2
.equ SOCK_RAW, 3
.equ IPPROTO_RAW, 255
IPd:
.asciz "127.0.0.1" # dest ip daddress
IPs:
.asciz "127.0.0.1" # source ip daddress
DATA:
.ascii "RAW SOCKETS IN ASM!"
.section .bss
.lcomm sock, 4
.lcomm saddr, 16
.lcomm daddr, 16
.lcomm sockargs, 12 # 3 ints for socket (int domain, int type, int protocol)
.lcomm sendargs, 24 # 6 ints for sendto()
.lcomm iph, 40 # ip header + data
.section .text
.globl main
main:
nop # debugging purposes
movl $sockargs, %edi # point edi to sockargs
movl $AF_INET, (%edi) # family = AF_INET
movl $SOCK_RAW, 4(%edi) # type = SOCK_RAW
movl $IPPROTO_RAW, 8(%edi) # protocol = 255
movl $102, %eax # 102 = sys_socketcall which is a demultiplexor for all socket syscalls
movl $1, %ebx # this is the call argument - SYS_SOCKET is 1
movl %edi, %ecx # a pointer to the arguments of socket()
int $0x80 # socket(2) through sys_socketcall
movl %eax, sock # save socket descriptor
movl $daddr, %edi # point edi to our sockdaddr_in daddr
movl $2, (%edi) # daddr.sin_daddr = AF_INET
push $8000 # htons() for port - apparently htons doesn't mess up with %edi
call htons
movl %eax, 2(%edi) # daddr.sin_port = 8000
movl $0, 8(%edi) # daddr.sin_zero = 0 - we might not need this - TODO: check
movl $0, 12(%edi) # daddr.sin_zero = 0
# call inet_pton -daddr
addl $4, %edi # must give address of daddr.sin_addr
push %edi # argument: void *dst
push $IPd # argument: const char *src
push $AF_INET # argument: int family
call inet_pton
# call inet_pton -saddr
movl $saddr, %edi
movl $2, (%edi) # saddr.sin_daddr = AF_INET
addl $4, %edi # must give address of saddr.sin_addr
push %edi # argument: void *dst
push $IPs # argument: const char *src
push $AF_INET # argument: int family
call inet_pton
# create ip header and data
movl $iph, %ebx
movw $0x0045, (%ebx) # version, header length, TOS (total length filled by kernel)
movl $0x0000ffff, 4(%ebx) # identification number, frag offset = 0
movb $0x40, 8(%ebx) # TTL
movb $IPPROTO_RAW, 9(%ebx) # Protocol (checksum will be filled by kernel)
movl $saddr, %eax
addl $4, %eax
movl (%eax), %eax
movl %eax, 12(%ebx) # source ip address
movl $daddr, %eax
addl $4, %eax
movl (%eax), %eax
movl %eax, 16(%ebx) # destination ip address
movl $DATA, %esi # data
movl $iph+20, %edi
movl $19, %ecx
cld
rep movsb
# sendto() through sys_socketcall
movl $sockargs, %edi
movl sock, %eax
movl %eax, (%edi) # arg1: int sockfd
movl $iph, %eax
movl %eax, 4(%edi) # arg2: const void *buf
movl $50, %eax
movl %eax, 8(%edi) # arg3: size_t len
movl $0, %eax
movl %eax, 12(%edi) # arg4: int flags = 0
movl $daddr, %eax
movl %eax, 16(%edi) # arg5: const struct sockaddr *servaddr
movl $16, %eax
movl %eax, 20(%edi) # arg6: socklen_t addrlen
movl $102, %eax
movl $11, %ebx # SYS_SENDTO = 11
movl %edi, %ecx # arguments to sendto(2)
int $0x80
movl $1, %eax
movl $0, %ebx
int $0x80
Demonstration:
$ gcc raw.s -o raw
# ./raw
# tcpdump -i lo -n -X
16:57:48.495821 IP 127.0.0.1 > 127.0.0.1: ip-proto-255 30
0x0000: 4500 0032 ffff 0000 40ff 7bcb 7f00 0001 E..2....@.{.....
0x0010: 7f00 0001 5241 5720 534f 434b 4554 5320 ....RAW.SOCKETS.
0x0020: 494e 2041 534d 2100 0000 0000 0000 0000 IN.ASM!.........
0x0030: 0000 ..
-- ithilgore, 19 April 2009
Socket Internals
I will begin writing a series of posts concerning the internals of the
socket mechanism based on a 2.6.* Linux kernel. I was recently refreshing
my memory on some parts of Unix Network Programming vol 1 by Unix guru
Stevens and thought it would be fruitful to share some thoughts and
tinkering about the often misunderstood socket world.
Value-result magic
I will begin by analysing a simple example of the length value-result
argument as seen in many socket-related system calls like recvfrom(2) and
accept(2). Anyone who has some basic experience with network programming
should already know that these routines require a pointer of type
socklen_t argument as well as a pointer to a sockaddr struct (usually
cast to a protocol-family-dependent structure like sockaddr_in - blame pre-ANSI
C). Initially, the socklen_t argument is set by the program to a value that
denotes the actual length of the sockaddr struct that the kernel will fill
in with relevant information. However, the userspace application's say on
the type and thus size of sockaddr struct used may, under really obscure
circumstances, be different than the one that the kernel decides is suitable.
For example, suppose you provided a unix domain sockaddr_un struct for a UDP
socket. Then, the kernel would write far less bytes (16) at the userspace
struct and will update the length variable to denote the real size of the
sockaddr as it should be. That is why these kind of variables are called
value-result. They act as both an initial value as well as a returning value.
Let's see an example from recvfrom(2):
linux-2.6.26/net/socket.c
/*
* Receive a frame from the socket and optionally record the address of the
* sender. We verify the buffers are writable and if needed move the
* sender address from kernel to user space.
*/
asmlinkage long sys_recvfrom(int fd, void __user *ubuf, size_t size,
unsigned flags, struct sockaddr __user *addr,
int __user *addr_len)
{
struct socket *sock;
struct iovec iov;
struct msghdr msg;
char address[MAX_SOCK_ADDR];
int err, err2;
int fput_needed;
sock = sockfd_lookup_light(fd, &err, &fput_needed);
if (!sock)
goto out;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_iovlen = 1;
msg.msg_iov = &iov;
iov.iov_len = size;
iov.iov_base = ubuf;
msg.msg_name = address;
msg.msg_namelen = MAX_SOCK_ADDR;
if (sock->file->f_flags & O_NONBLOCK)
flags |= MSG_DONTWAIT;
err = sock_recvmsg(sock, &msg, size, flags);
if (err >= 0 && addr != NULL) {
err2 = move_addr_to_user(address, msg.msg_namelen, addr, addr_len);
if (err2 < 0)
err = err2;
}
fput_light(sock->file, fput_needed);
out:
return err;
}
The arguments correspond to the ones shown in recv(2):
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr,
socklen_t *addrlen);
The first task that sys_recvfrom does is find the relevant socket given
the file descriptor. Thus it calls sockfd_lookup_light() which is shown below:
socket.c:
static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed)
{
struct file *file;
struct socket *sock;
*err = -EBADF;
file = fget_light(fd, fput_needed);
if (file) {
sock = sock_from_file(file, err);
if (sock)
return sock;
fput_light(file, *fput_needed);
}
return NULL;
}
As we can see, there are two calls inside it: fget_light() which returns a
file instance by searching in the descriptor table and then sock_from_file()
which references the file structure which has been initialiazed by
sock_map_fd() during the socket creation-allocation phase, to ultimately
return the socket structure that we need.
static struct socket *sock_from_file(struct file *file, int *err)
{
if (file->f_op == &socket_file_ops)
return file->private_data; /* set in sock_map_fd */
*err = -ENOTSOCK;
return NULL;
}
After getting the socket struct, sys_recvfrom() proceeds with filling in
the msghdr and iovec structs which are used for message and data passing inside
the kernel. Then sock_recvmsg() is called and is responsible to prepare for
passing control to the transport-layer specific handler (e.g the UDP specific
recvmsg - udp_recvmsg() from net/ipv4/udp.c):
err = sock_recvmsg(sock, &msg, size, flags);
We finally reach the point that interests us most.
err2 = move_addr_to_user(address, msg.msg_namelen, addr, addr_len);
This is the routine that will copy the sockaddr struct that has already
been filled with relevant information from the transport-layer specific
recvmsg() to the userspace application. The address of 'address' had
previously been passed to msg.msg_name and msg.msg_namelen was assigned a
MAX_SOCK_ADDR length. MAX_SOCK_ADDR is defined so large as to be able to
hold the lengthiest struct (unix domain sockaddr) available in the system:
#define MAX_SOCK_ADDR 128 /* 108 for Unix domain -
16 for IP, 16 for IPX,
24 for IPv6,
about 80 for AX.25
must be at least one bigger than
the AF_UNIX size (see net/unix/af_unix.c
:unix_mkname()).
*/
Let's uncover the internals of move_addr_to_user now:
/**
* move_addr_to_user - copy an address to user space
* @kaddr: kernel space address
* @klen: length of address in kernel
* @uaddr: user space address
* @ulen: pointer to user length field
*
* The value pointed to by ulen on entry is the buffer length available.
* This is overwritten with the buffer space used. -EINVAL is returned
* if an overlong buffer is specified or a negative buffer size. -EFAULT
* is returned if either the buffer or the length field are not
* accessible.
* After copying the data up to the limit the user specifies, the true
* length of the data is written over the length limit the user
* specified. Zero is returned for a success.
*/
int move_addr_to_user(void *kaddr, int klen, void __user *uaddr,
int __user *ulen)
{
int err;
int len;
err = get_user(len, ulen);
if (err)
return err;
if (len > klen)
len = klen;
if (len < 0 || len > MAX_SOCK_ADDR)
return -EINVAL;
if (len) {
if (audit_sockaddr(klen, kaddr))
return -ENOMEM;
if (copy_to_user(uaddr, kaddr, len))
return -EFAULT;
}
/*
* "fromlen shall refer to the value before truncation.."
* 1003.1g
*/
return __put_user(klen, ulen);
}
The author's comments are pretty informative though studying the code always
sheds more light. get_user() is nothing else than a mini-userspace-to-kernel
copier for small-sized variables. It writes the userspace ulen variable into
the local variable len, and later uses that to make all the comparisons -
obviously for performance reasons. We can see the sanitization checks that
follow: len gets truncated to a maximum of klen which is the actual number
of bytes that the kernel previously wrote to the sockaddr struct. Additionally,
if len is negative or larger than MAX_SOCK_ADDR, then an error of type EINVAL
is returned. The all-around-classic copy_to_user() routine copies the sockaddr
struct to the userspace and __put_user(), which is the opposite of get_user(),
copies the klen into ulen. We can deduce from the above the following:
- If the userspace application passes a socklen_t addrlen argument that is
more than the number of bytes actually written by the kernel, then addrlen
will be overwritten with the new size.
- If the userspace application passes a socklen_t addrlen argument that is
less than the number of bytes actually written by the kernel in the kernelspace
struct, then addrlen will be overwritten with the new size but only the first
addrlen userspace bytes will be filled in by the kernel.
That is expected behaviour, as we can see from the recv(2) manpage:
"The argument addrlen is a value-result argument,
which the caller should initialize before the call to the size of the
buffer associated with src_addr, and modified on return to indicate the
actual size of the source address. The returned address is truncated
if the buffer provided is too small; in this case, addrlen will return
a value greater than was supplied to the call."
Finally, let's see a simple example from UNP. It is a simple
protocol-independent function that echoes the message that it gets to the
one who initially sent it. Why did Stevens use the local variable len instead
of just passing the clilen argument directly? It's not for performance reasons
since both are variables that can be accessed locally through the stack. Only
clilen may be some bytes above or below, depending on the underlying
architecture, in memory. The real reason is defensive programming. Recvfrom()
could potentially change clilen any time. If that happened, then the next time
it was called, since clilen is a value-result variable, the next call would be
'infected' by the previous variable of clilen. To avoid that, a local variable
len is assigned clilen each time in the beginning of the loop.
#include "unp.h"
void
dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen)
{
int n;
socklen_t len;
char mesg[MAXLINE];
for ( ; ; ) {
len = clilen;
n = Recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len);
Sendto(sockfd, mesg, n, 0, pcliaddr, len);
}
}
The question is: is there any case that recvfrom() could actually return
different values for len each time it was called?
Remember that this function is meant to be protocol-agnostic. Inspecting the
TCP and UDP code will show that no such case exists. However, there may exist
other transport-layer protocols that have strange behaviours. In addition, there
are variable-length socket address structures like Unix domain (sockaddr_un) that
can return a length less than the maximum of the structure. Thinking so
far ahead to include any possible future end-case is truly the mark of a guru
like Stevens.
-- ithilgore, 19 April 2009
Digging through Snort
I have been studying the snort source code to get some
ideas for my upcoming distributed intrusion detection system and I will have to admit that it
is pretty easily readable. I have spotted some points though that should have no place in a
contemporary codebase.
void *InterfaceThread(void *arg)
{
int pcap_ret;
struct timezone tz;
int pkts_to_read = pv.pkt_cnt;
bzero((char *) &ptz, sizeof(tz));
...
}
We all know that bzero is deprecated though we keep seeing it very frequently.
What I didn't expect was that Snort in non-inline mode uses a single process to do
the whole work of getting the packets through libpcap, parse them, decode them and
later analyse them producing any subsequent alerts. I expected it to use more than one
thread for all these tasks but it seems that that would make things more complicated than
needed without any additional real gain.
By the way I added the rss feeds to the site.
-- ithilgore, 15 April 2009
~0xdead
I am still alive, though the site - I'll have to admit - has been unupdated for a while.
Though there are many reasons about it, I will not go into details and excuses. I have
been lately working on a distributed IDS as well as the extraction of the plaintext private
ssh key from /dev/mem. Have been digging through a lot of openssl code on that and have
been frustrated with all the abstraction layers there. I am very close to the solution
though. I am thinking about making some major design changes to the site too. Maybe also add
some rss feeds, since many asked for them. More later.
-- ithilgore, 14 April 2009
The TCP/IP Drinking Game
A new iteration of the TCP/IP Drinking Game
has officially started! The idea behind it is to delve into the network abyss
and find obscure, unheard of, or otherwise in general unknown details of networking
protocols and internet lore, transform them into a question-answer scheme and have fun.
Feel free to make your own contributions to the list by sending an
email and/or provide any other kind of feedback. Finally,
don't forget to sock_valbool_flag(sk, SOCK_BROADCAST, 1); it.
-- ithilgore, 10 February 2009
Backdooring OpenSSH Server
I recently made a quick implementation of a POC sshd backdoor,
based on the the idea of sending a fake authentication password that
gets decoded with a predefined 2-way algorithm revealing the real
passphrase only on the server side, in case you know someone is
mitm-ing you and still need to initiate a new ssh session. Of course,
it doesn't even compare with using public key authentication, but
nevertheless it still remains an original
idea.
-- ithilgore, 7 February 2009
Paranoid Filtering
I finished writing about the exploitation of the TCP Persist Timer and
coding of Nkiller2 but won't release it just yet, since it will
hopefully be first published elsewhere (at a known underground ezine).
Filtering access on ports that are meant for administrative purposes
only (e.g ssh), has always been a much debated issue. Techniques
ranging from port-knocking to complex IP filtering schemes are one
way, but a really generic way to accomplish slightly more protection
is to filter based on the source port. It is assumed that you have also
moved your service listening on a port other than the default. Combine
the above and a prospective attacker will have to send at worst a total
of 2^32 [2^16(dst)*2^16(src)] packets to find your hidden service. The
only hindrance will be having to always use the designated source port
for the client. To do this, without resorting to recompiling the client
and hardcoding the used port, you can use a tool like socat that lets
you perform port-forwarding in addition to allowing you to choose the
source port. Demonstration:
# iptables -A INPUT -p TCP -s 0/0 --dport 3333 --sport 2222 -j ACCEPT
$ socat TCP4-LISTEN:4444 TCP:<ip>:3333,sourceport=2222 & ssh ithilgore@localhost -p4444
Mark the above as an alias and you are done. To use scp you will need
to allow an additional source port. Say 7777. Then you would use a
function like this (function and not an alias this time, since we will
need to use the bash argument variable $@):
pscp () { a=$RANDOM; socat TCP4-LISTEN:$a TCP:<ip>:3333,sourceport=7777
& scp -P$a "$@" ithilgore@localhost:~; }
-- ithilgore, 1 February 2009
TCP vulnerabilities / New domain
Many things have happened since the last time I updated the site.
Lately, I have been experimenting with/reading about TCP
vulnerabilities. From the old blind RST bug
to congestion collapses with misbehaving receivers.
The most remarkable thing about the last attacks, or at least some of
them, is that the RFC 2581 (TCP Congestion Control) authors were actually
aware of their existence.Specifically, Section 5. Security Considerations
states:
"This document requires a TCP to diminish its sending rate in the
presence of retransmission timeouts and the arrival of duplicate
acknowledgments. An attacker can therefore impair the performance of
a TCP connection by either causing data packets or their
acknowledgments to be lost, or by forging excessive duplicate
acknowledgments."
Yes, these attacks (and more) exist and yes they work.
Upcoming is an update on Nkiller which exploits the TCP persist timer.
Details will be included later.
Some other news: sock-raw.org is the new domain for the
site. sock-raw.homeunix.org will still continue to work but I don't know for
how long I will keep it.
-- ithilgore, 15 January 2009
Nmap out-of-bounds mem access bug
I've been busy lately, dealing with many tenuous projects, but managed
to indulge myself by auditing some of the Nmap code. It was part of the
inspection I would do anyway for the upcoming paper. The idea came
while revisiting some chapters from the venerable security bible
"The art of software security assessment". The chapter on
networks, mentioned a list of basic rules that every low-level
network tool should follow as far as packet length validation is
concerned. So, I applied this set of checks upon the latest Nmap
release validation routines. The result was
this.
The funniest part about the whole thing was the fact that I needed
to change the Linux kernel source code, so that I could make packets of
arbitrary length (packets that had an overall real length that was less
than the one mentioned in the ip->ip_len field in the IP header).
-- ithilgore, 25 November 2008
Nkiller - a TCP stressing tool
The "arsenal" of networking tools now comprises of a new program which
I decided to call Nkiller.
It is based on an
idea
first posted at bugtraq in 2000 but still works until today, more or
less. As far as I have tried it in my own servers, I had 100% success
(though some option optimization was needed at times e.g more
aggressive timing). The targets included web servers running on Windows
Server 2003, Linux (2.6.22) and OpenBSD... The good thing is that it
combines both the exploitation of a mechanism that is perpetual on
every OS, and the idea of reverse syn cookies first introduced by
Dan Kaminsky's scanrand, which
adds to the overall speed. I have to warn you: I will not be held
responsible for any kind of abuse of this tool. It is to be used
on servers you own yourself to test their potential ability to
withstand such an attack.
-- ithilgore, 21 October 2008
Locating Stateless Firewalls
I finished writing another paper, this time concerning firewalls:
how to locate and possibly defeat stateless ones. The paper uses
more or less old methods (which *still* work however) to identify
the nature of a stateless firewall and further on bypass it exploiting
the fact that RFC 793 is ambiguous in one part about tcp flags, thus
allowing a margin for misconfigurations. The article can be found
here.
After I sharpen my low-level networking skills a bit more, I am
planning to write a paper on "analyzing the Nmap source code". This
will probably be a formidable task, considering the enormousness of
the Nmap codebase. It will probably resemble
SOCK_RAW Demystified in its extent and complexity.
Since firewalls was one of my research interests the last days, I
happened to come across some
guy on
nmap-dev asking about how he could identify which of four
firewalls along his way, was blocking his requests. The brief
theoretical explanation of the technique that could be used in such a
case is explained here.
Now that I give it a second thought, there is actually an out-of-the-box
tool that serves the purpose of firewall reconnaissance: It is the
venerable
Firewalk
by Mike Schiffman, the well-known TCP/IP guru and hacker.
I must not forget to mention
this
good reading that comments on the recent TCP DoS attack discovered
by Robert Lee (main developer of
Unicornscan) and his team
at Outpost24.
-- ithilgore, 6 October 2008
Port knocking module & nmap payload patch
I 've added some new material to the site:
1) pknf - pknf
is a loadable kernel module for linux, which implements a port knocking mechanism
using netfilter hooks. Nf hooks was a choice over other methods
since, although lower level and thus less portable, it is a stealthier and
perhaps more rootkit-friendly way.
2) Nmap payload patch - this patch intoduces a new option for the latest
version of Nmap (4.68 as of now), which lets you define your own
payload for Nmap's probes. Until now, you could only insert random
data by defining the --data-length option. I wrote it, after some user
on nmap-dev asked for such
functionality. Of course, as I noted
there and
as Michael Pattrick later mentioned
here,
payload handling is something NSE is more suitable for. Nevertheless,
it provides a nifty solution for someone who needs a quick and
protocol-agnostic way to manipulate extra payloads, since it uses the
existing build_<protocol>_raw (where <protocol> = tcp,udp,icmp
etc) functions defined in tcpip.cc of Nmap source code. You can
find the patch here.
There were some discussions lately about the daunting task of scanning
the whole internet. Fyodor
presented at Black Hat and Defcon 2008 some interesting results
based on his own findings from scanning most part of the internet
range 0.0.0.0 - 239.255.255.255. Another thought-provoking article
comes from thc -
Port Scanning the Internet.
-- ithilgore, 25 August 2008
Hacking Bash History
After quite a long time of absence from updating the site, I now
included in the papers section a new article I wrote about subverting
the bash_history mechanism when it is vainly used as a user monitoring
facility. I analyse both the strictest defensive measures that can be
taken to supposedly secure it and more than enough counter-attacks to
override it. In the end, a way to interface bash with syslog by hacking
its source code is examined. You can find the text
here.
-- ithilgore, 12 July 2008
SOCK_RAW Demystified
The site has just opened. You might want to take a look at my new paper
SOCK_RAW Demystified.
There is also some of my old work
Coding a Syn Scanner along with some nifty new (and old)
projects such as
TAP - the Tcpdump Analysing
Parser.
I will usually post stuff of lesser-scale in the
networking/security section.
-- ithilgore, May 2008
|