hydra掃描不出oracle中sys使用者的弱密碼
阿新 • • 發佈:2019-01-10
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類使用者密碼的問題進行了分析,最後給出瞭解決方法。