首页 -> 安全研究
安全研究
绿盟月刊
绿盟安全月刊->第8期->安全文摘
主页:http://www.nsfocus.com
日期:2000-04-12
作者:scz < mailto: scz@nsfocus.com >
主页:http://www.nsfocus.com
测试:
RedHat6.0
程序:
/*
File Name: rpcscan.c
Author : unknown
Test : Linux 2.2.5
Compile : gcc -pipe -O3 -o rpcscan rpcscan.c
Date : 2000/02/22
*/
#include <stdio.h>
#include <netdb.h>
#include <stdlib.h>
#include <signal.h>
#include <rpc/rpc.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <rpc/pmap_prot.h>
#include <rpc/pmap_clnt.h>
void doNothing ( int arg )
{
return;
} /* end of doNothing */
u_long resolveHost ( char * host )
{
struct hostent * he;
unsigned long ip;
if( ( he = gethostbyname( host ) ) == NULL )
{
ip = inet_addr( host ); /* 网络字节顺序 */
if ( ip == INADDR_NONE )
{
ip = 0;
}
}
else
{
bcopy( he->h_addr_list[0], &ip, sizeof( unsigned long ) );
}
return( ip );
} /* end of resolveHost */
int rpcServerDump ( char * host, char * rpcServerName )
{
struct sockaddr_in server_addr;
struct pmaplist * head = NULL;
int rpcsocket = RPC_ANYSOCK;
struct timeval minutetimeout;
register CLIENT * clientHandle;
struct rpcent * rpc;
server_addr.sin_addr.s_addr = resolveHost( host ); /* 获得远程主机IP地址 */
server_addr.sin_family = AF_INET; /* 只能是这个地址族 */
server_addr.sin_port = htons( PMAPPORT ); /* 111端口 */
minutetimeout.tv_sec = 15;
minutetimeout.tv_usec = 0;
/* cause clnttcp_create uses connect() */
signal( SIGALRM, doNothing );
alarm( 15 );
/* 创建句柄 */
if ( ( clientHandle = clnttcp_create( &server_addr, PMAPPROG,
PMAPVERS, &rpcsocket, 50, 500 ) ) == NULL )
{
alarm( 0 );
signal( SIGALRM, SIG_DFL );
return( 0 );
}
alarm( 0 );
signal( SIGALRM, SIG_DFL );
/* portmapper本身是一个rpc server,提供远程过程PMAPPROC_DUMP */
if ( clnt_call( clientHandle, PMAPPROC_DUMP, ( xdrproc_t )xdr_void, NULL,
( xdrproc_t )xdr_pmaplist, ( caddr_t )&head, minutetimeout ) != RPC_SUCCESS )
{
return( 0 );
}
if ( head != NULL )
{
for ( ; head != NULL; head = head->pml_next )
{
if ( ( rpc = getrpcbynumber( head->pml_map.pm_prog ) ) ) /* 可以考虑修改这里 */
{
if ( strcmp( rpc->r_name, rpcServerName ) == 0 )
{
return( 1 );
}
}
}
}
return( 0 );
} /* end of rpcServerDump */
void rpcServerScan ( char * inputFileName, char * rpcServerName )
{
FILE * inputFile;
char buffer[512];
if ( ( inputFile = fopen( inputFileName, "rt" ) ) == NULL )
{
return;
}
while ( fgets ( buffer, 512, inputFile ) != NULL )
{
if ( buffer[ strlen( buffer ) - 1 ] == '\n' )
{
buffer[ strlen( buffer ) - 1 ] = '\0';
}
if ( rpcServerDump( buffer, rpcServerName ) )
{
buffer[ strlen( buffer ) + 1 ] = '\0';
buffer[ strlen( buffer ) ] = '\n';
fprintf( stderr, "%s", buffer );
}
} /* end of while */
fclose( inputFile );
return;
} /* end of rpcServerScan */
int main ( int argc, char * argv[] )
{
if ( argc < 3 )
{
fprintf( stderr, "Usage: %s <hostListFile> <rpcServerName>\n", argv[0] );
exit( -1 );
}
rpcServerScan( argv[1], argv[2] );
return( 0 );
} /* end of main */
[scz@ /home/scz/src/rpc]> gcc -pipe -O3 -o rpcscan rpcscan.c
[scz@ /home/scz/src/rpc]> strip rpcscan
[scz@ /home/scz/src/rpc]> ./rpcscan
Usage: ./rpcscan <hostListFile> <rpcServerName>
[scz@ /home/scz/src/rpc]> ./rpcscan hostlist rpcbind
higgs.*.*.*
server.*.*.*
[scz@ /home/scz/src/rpc]>
原理:
signal和alarm函数的使用就不用我解释了吧,W.Richard.Stevens的经典著作
看得还不够么,尤其是华南木棉站socket版的朋友,你一定不要问我这个程序
怎么理解,否则要倒。
前面的系列中我们已经再三强调,portmapper本身就是一个rpc server。
程序利用了portmapper提供的远程过程PMAPPROC_DUMP。实际上rpcinfo -p就是这样实现的。
然后在dump出来的远程主机上的rpc server注册信息中根据关键字查找我们所关心的特定
的rpc server。这和先用rpcinfo -p后用grep的道理是一致的。
远程过程PMAPPROC_DUMP,顾名思义,就是dump出所有rpc server注册信息。
hostListFile的格式如下:
server.*.*.*
higgs.*.*.*
192.168.67.152
192.168.67.124
至于命令行上的rpcServerName如何指定,你用rpcinfo -p先看看就知道了。rpcbind正是
portmapper本身的rpc server name。
可以写出各种各样的rpc scan程序,后面的系列中还会给出一些,完全可以根据自己的需
要适当修改加以利用。
注意,一切rpc scan都是非常容易暴露自己的扫描过程,除非敢保证敌人没有条件过来修
理你,否则还是悠着好。作为网络管理人员,一旦发现rpc scan,应该警惕,rpc scan
是rpc remote attack的前奏,这种攻击的危害性相当大。比如前段时间攻击日本站点,
大量使用过的rpc.cmsd,chat* sigh
版权所有,未经许可,不得转载