hydra扫描不出oracle中sys用户的弱密码

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qigaoqiang/article/details/83094410

sys用户需要以sysdba身份登录

我们知道,oracle数据库的用户是分权限的,其中sys用户权限最高,在登录时需要以sysdba的身份才可以成功登陆,否则会报错:ORA-28009: connection as SYS should be as SYSDBA or SYSOPER.(如图)
在这里插入图片描述

hydra登录oracle的代码

hydra登录oracle的代码在源文件hydra-oracle.c中的start_oracle函数中,使用的是OCI接口,登录时调用的接口是OCILogon,如图。
在这里插入图片描述

OCILogon接口原型

查询OCI官方文档,得知OCILogon接口原型如下:

sword OCILogon ( 
OCIEnv          *envhp,    //环境句柄
OCIError        *errhp,   //错误句柄
OCISvcCtx       **svchp,  //服务上下文句柄
CONST text      *username,   //用户名
ub4             uname_len,  //用户名长度
CONST text      *password,   //密码
ub4             passwd_len,   //密码长度
CONST text      *dbname,   //数据库名
ub4             dbname_len   //数据库名长度
); 

sword OCILogoff (  
OCISvcCtx      *svchp,  //服务上下文句柄
OCIError       *errhp  //错误句柄
);

可以看出,OCILogon接口中并不存在指定用户角色的参数,所以当调用此函数以sys用户登录时,就会报权限不足的错误。

使用其他接口替代OCILogon

既然问题出在OCILogon没有指定用户身份的参数,那么我们找个有指定身份参数的接口去代替。查询OCI官方文档可知,OCISessionBegin符合要求(如图)。这个接口是为某用户开始一个会话,既然能开始会话,当然也就表明该用户登录成功了。
在这里插入图片描述

hydra-oracle.c源码修正

经过上述讨论,决定改用OCISessionBegin接口来代替OCILogon接口。在调用时对sysdba类用户做判断(这里默认只处理sys用户),如图:
在这里插入图片描述

修正后的hydra-oracle.c在:

关于OCILogon和OCISessionBegin的接口测试代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <oci.h>

/*user name and password*/
#if 1
static text* username=(text *)"sys";
static text* password=(text *)"oracle11g";
#else
static text* username=(text *)"system";
static text* password=(text *)"oracle11g";
#endif

static text* oracle=(text *)"//172.16.7.30:1521/ORCL";


/*handle define*/
static OCIEnv           *p_env;                                        //OCI environment handle
static OCIError         *p_err;                                        //OCI error handle
static OCISvcCtx        *p_svc;                                        //OCI service context handel
static OCIServer        *p_ser;                                        //OCI server handle
static OCISession       *p_usr;                                        //OCI user session handle
static OCIStmt          *p_sql;                                        //OCI statement handle
static OCIDefine        *p_dfn = (OCIDefine *)NULL;                    //OCI define handle
static OCIBind          *p_bnd = (OCIBind *)NULL;                      //OCI bind handle

text o_errormsg[512];
sb4 o_errorcode;

/*create OCI environment*/
int create_env()
{
  int swResult;            //Return value
  if(swResult = OCIEnvCreate(&p_env,OCI_DEFAULT,NULL,NULL,NULL,NULL,0,NULL)) {
    printf("environment create error!\n\n");
    return -1;
  } else {
    printf("environment create success!\n\n");
    return 0;
  }
}

/*init handle*/
int init_handle()
{
  int swResult;
  if(swResult = OCIHandleAlloc(p_env,(dvoid *)&p_ser,OCI_HTYPE_SERVER,0,NULL)) {  //服务器句柄
    printf("init server handle error!\n\n");
    return -1;
  } else {
    printf("init server handle success!\n\n");
  }

  if(swResult = OCIHandleAlloc(p_env,(dvoid *)&p_err,OCI_HTYPE_ERROR,0,NULL)) {  //错误句柄
    printf("init error handle error!\n\n");
    return -1;
  } else {
    printf("init error handle success!\n\n");
  }
  if(swResult = OCIHandleAlloc(p_env,(dvoid *)&p_usr,OCI_HTYPE_SESSION,0,NULL)) {  //事务句柄
    printf("init session handle error!\n\n");
    return -1;
  } else {
    printf("init session handle success!\n\n");
  }
  if(swResult = OCIHandleAlloc(p_env,(dvoid *)&p_svc,OCI_HTYPE_SVCCTX,0,NULL)) {  //上下文句柄
    printf("init service context handle error!\n\n");
    return -1;
  } else {
    printf("init service context handle success!\n\n");
  }
  if(swResult = OCIHandleAlloc(p_env,(dvoid *)&p_sql,OCI_HTYPE_STMT,0,NULL)) {      //SQL语句句柄
    printf("init statement handle error!\n\n");
    return -1;
  } else {
    printf("init statement handle success!\n\n");
  }
  return 0;
}

/*connect server*/
int conn_server()
{
  int swResult;
  if(swResult = OCILogon(p_env,p_err,&p_svc,(text *)username,strlen(username),(text *)password,strlen(password),(text *)oracle,strlen(oracle))) {
    printf("connect error!\n\n");

    OCIErrorGet(p_err, 1, NULL, &o_errorcode, o_errormsg, sizeof(o_errormsg), OCI_HTYPE_ERROR);
    printf("error: %s\n", o_errormsg);

    return -1;
  } else
    printf("connect success!\n\n");
  return 0;
}

int begin_session()
{
  int swResult;
  
  swResult = OCIServerAttach(p_ser, p_err, (text *)oracle, strlen(oracle), OCI_DEFAULT);
  if (swResult != OCI_SUCCESS )
  {
    printf("attach server failed!\n");
    OCIErrorGet(p_err, 1, NULL, &o_errorcode, o_errormsg, sizeof(o_errormsg), OCI_HTYPE_ERROR);
    printf("error: %s\n", o_errormsg);    
    return -1;  	
  }
  	
	swResult = OCIAttrSet((dvoid *)p_svc, (ub4)OCI_HTYPE_SVCCTX, (dvoid *)p_ser, (ub4)0, (ub4)OCI_ATTR_SERVER, (OCIError *)p_err);
  if (swResult != OCI_SUCCESS && swResult != OCI_SUCCESS_WITH_INFO) {
    printf("set service attr failed!\n");
    return -1;
  }
  	  
  swResult = OCIAttrSet((dvoid*)p_usr, (ub4)OCI_HTYPE_SESSION, (dvoid*)username, (ub4)strlen(username), OCI_ATTR_USERNAME, p_err);
  if (swResult != OCI_SUCCESS && swResult != OCI_SUCCESS_WITH_INFO) {
    printf("set username attr failed!\n");
    return -1;
  }
  
  swResult = OCIAttrSet((dvoid*)p_usr, (ub4)OCI_HTYPE_SESSION, (dvoid*)password, (ub4)strlen(password), OCI_ATTR_PASSWORD, p_err);
  if (swResult != OCI_SUCCESS && swResult != OCI_SUCCESS_WITH_INFO) {
    printf("set password attr failed!\n");
    return -1;
  }
  
  swResult = OCISessionBegin(p_svc, p_err, p_usr, OCI_CRED_RDBMS, OCI_SYSDBA);
  if (swResult != OCI_SUCCESS) {
    printf("begin_session failed!\n");
    OCIErrorGet(p_err, 1, NULL, &o_errorcode, o_errormsg, sizeof(o_errormsg), OCI_HTYPE_ERROR);
    printf("error: %s\n", o_errormsg);
    return -1;
  } else {
    printf("begin session success!\n\n");
  }
  
  return 0;
}


/*SQL statements*/
int oci_exec()
{
  int swResult;
  //准备SQL语句
  if(swResult = OCIStmtPrepare(p_sql,p_err,SQL,strlen(SQL),OCI_NTV_SYNTAX,OCI_DEFAULT)) {
    printf("prepare SQL statements error!\n\n");
  } else {
    printf("prepare SQL statements success!\n\n");
  }

  //设置绑定变量
  int getId ;
  char getName[10];

  OCIBind     *p_bndp1 = NULL;
  OCIBind     *p_bndp2 = NULL;

  printf("输入ID,NAME:\n");
  scanf("%d %s",&getId,getName);

  if(swResult = OCIBindByPos(p_sql,&p_bndp1,p_err,1,(dvoid *)&getId,(sb4)sizeof(getId),SQLT_INT,NULL,NULL,NULL,0,NULL,OCI_DEFAULT)) {
    printf("Bind p1 error!\n\n");
    return -1;
  } else {
    printf("bind success!\n\n");
  }

  if(swResult = OCIBindByPos(p_sql,&p_bndp2,p_err,2,&getName,(sb4)sizeof(getName),SQLT_STR, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT)) {
    printf("Bind p2 error!\n\n");
    return -1;
  } else {
    printf("bind success!\n\n");
  }


  //执行SQL statements
  if(swResult = OCIStmtExecute(p_svc,p_sql,p_err,1,0,NULL,NULL,OCI_DEFAULT)) {
    printf("execute SQL statement error!\n\n");
    return -1;
  } else {
    printf("execute SQL statement success!\n\n");
  }
  return 0;
}


/*quit server*/
void quit_server()
{
  OCILogoff(p_svc,p_err);
  printf("Quit success!\n");
}

/*free handle*/
void free_handle()
{
  OCIHandleFree(p_ser,OCI_HTYPE_SERVER);            //释放服务器句柄
  OCIHandleFree(p_err,OCI_HTYPE_ERROR);            //释放错误句柄
  OCIHandleFree(p_usr,OCI_HTYPE_SESSION);        //释放事务句柄
  OCIHandleFree(p_svc,OCI_HTYPE_SVCCTX);            //释放上下文句柄
  OCIHandleFree(p_sql,OCI_HTYPE_STMT);            //释放SQL语句句柄
}

int main()
{
  if(create_env() == -1)                //创建环境
    return -1;
  if(init_handle() == -1)                //初始化句柄
    return -1;
#if 0
  if(conn_server() == -1)                //连接数据库
    return -1;
#else
  if (begin_session() == -1)
    return -1;
#endif

#if 0
  if(oci_exec() == -1)
    return -1;
#endif
  quit_server();                            //退出数据库
  free_handle();                            //释放句柄
  return 0;
}

总结

本文使用的hydra版本是V8.5,对扫不出oracle中sysdba类用户密码的问题进行了分析,最后给出了解决方法。

猜你喜欢

转载自blog.csdn.net/qigaoqiang/article/details/83094410
今日推荐