當前位置:首頁 » 編程語言 » c語言安全漏洞
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

c語言安全漏洞

發布時間: 2022-09-18 06:39:04

c語言未經處理的異常,求大佬指點

您好,很高興回答您的問題。

您的這個題目,系統已經很明顯告訴您了錯誤的原因。因為您定義的x為字元型數據,那麼它對應的輸入輸出格式符為%c,但是您在輸入語句中寫的是%s,是字元串格式,不符合字元型單個變數的輸入輸出。根據題目意思,應該是要輸入字元串,那麼定義的時候就要寫成charx[2],因為存放的是性別中文字,所以數組長度定義為2就可以了。您再試試哦。

② 下列C程序存在安全漏洞,請給出攻擊方法。如何修復或防範

下列C程序存在安全漏洞,請給出攻擊方法。

③ 一門編程語言會有漏洞嗎,比如C,C++,java之類的

1、語言是不會有漏洞的。就象我們說漢語、英語、法語,是不會有「漏洞」的,如果表達不清,可以多說兩句,說清楚。
2、實際用一門計算機語言編程,生成的應用,是可以存在「漏洞」的,存在的原因多種多樣,比如:編程者考慮不周,編程環境存在隱性問題,應用依附的環境存在問題,外界環境變化(比如技術的提高或支持平台的變更)導致的問題,等等。
3、當然,不是說每一門編程語言都是完美的,實際上,語言針對的側重不同,各人的習慣不同,當前的對應的編程支持環境的不同,都會使得編程人員對某門編程語言的感受不同,也會使得編程人員工作的結果的漏洞發生率有所不同。

4、舉例,有人說了「C語言就存在著內存溢出的風險」,那一般是因為以下幾種原因:
a、設計時,使用了指定為全局有效的變數卻沒有合理的在應該的位置下達釋放指令。
b、編譯器存在問題,雖然編寫者下達了釋放指令,但編譯器生成的應用在實際工作中就是不釋放應釋放的內存。
c、總之,這不是語言的錯,是使用者或環境的錯。

5、當然,也不能說所有的編程語言都是優秀的,也有不好的,但我們能說它是有缺陷的,一般不能說它是有漏洞的。每門語言都有它的缺陷,只是缺陷的多少而已。
6、C和JAVA在編程人員中,用的人群是非常多的,應該說,是很優秀的語種,當然,對多數人來說學習難度不小。

④ 計算機二級C語言最後一道編程題漏洞技巧有哪些

網上碰到有二級c的作弊方法,提到了通過更改out.dat文件的內容,達到作弊的目的,自己也在二級c語言的模擬考試環境下測試過,可用,滿分,24分就來了,至於真正的二級c考試,有人說能用,也有人說,不能用,只有試試就知道了,第一次考二級,也沒試過,所以不知道是不是能用。

具體如下:

電腦常見問題解決

1、無法自動識別硬碟控制器

使用非正版的個別操作系統光碟,在安裝系統時,容易出現此錯誤。原因是非正版光碟自動載入的硬碟控制器驅動不符合電腦自身需要的驅動。這種情況就建議換正版光碟安裝操作系統。

2、手動更新錯誤的驅動程序

windows操作系統正常使用,但手動更新驅動程序把硬碟控制器的驅動程序更新錯誤,導致此故障。解決方法是進入windows系統高級菜單,選擇最後一次的正常配置,即可正常進入系統。

3、bios設置變化後所導致

windows操作系統正常,但是由於某些原因,用戶修改了bios設置,導致0x0000007b故障。

⑤ 什麼是C語言緩沖區溢出漏洞怎麼利用誰可以提供詳細的資料

緩沖區溢出漏洞入門介紹
文/hokersome
一、引言
不管你是否相信,幾十年來,緩沖區溢出一直引起許多嚴重的安全性問題。甚至毫不誇張的說,當前網路種種安全問題至少有50%源自緩沖區溢出的問題。遠的不說,一個沖擊波病毒已經令人談溢出色變了。而作為一名黑客,了解緩沖區溢出漏洞則是一門必修課。網上關於溢出的漏洞的文章有很多,但是大多太深或者集中在一個主題,不適合初學者做一般性了解。為此,我寫了這篇文章,主要是針對初學者,對緩沖區溢出漏洞進行一般性的介紹。
緩沖區溢出漏洞是之所以這么多,是在於它的產生是如此的簡單。只要C/C++程序員稍微放鬆警惕,他的代碼裡面可能就出現了一個緩沖區溢出漏洞,甚至即使經過仔細檢查的代碼,也會存在緩沖區溢出漏洞。
二、溢出
聽我說了這些廢話,你一定很想知道究竟什麼緩沖區溢出漏洞,溢出究竟是怎麼發生的。好,現在我們來先弄清楚什麼是溢出。以下的我將假設你對C語言編程有一點了解,一點點就夠了,當然,越多越好。
盡管緩沖區溢出也會發生在非C/C++語言上,但考慮到各種語言的運用程度,我們可以在某種程度上說,緩沖區溢出是C/C++的專利。相信我,如果你在一個用VB寫的程序裡面找溢出漏洞,你將會很出名。回到說C/C++,在這兩種使用非常廣泛的語言裡面,並沒有邊界來檢查數組和指針的引用,這樣做的目的是為了提高效率,而不幸的是,這也留下了嚴重的安全問題。先看下面一段簡單的代碼:
#include<stdio.h>
void main()
{
char buf[8];
gets(buf);
}
程序運行的時候,如果你輸入「Hello」,或者「Kitty」,那麼一切正常,但是如果輸入「Today is a good day」,那麼我得通知你,程序發生溢出了。很顯然,buf這個數組只申請到8個位元組的內存空間,而輸入的字元卻超過了這個數目,於是,多餘的字元將會佔領程序中不屬於自己的內存。因為C/C++語言並不檢查邊界,於是,程序將看似正常繼續運行。如果被溢出部分佔領的內存並不重要,或者是一塊沒有使用的內存,那麼,程序將會繼續看似正常的運行到結束。但是,如果溢出部分佔領的正好的是存放了程序重要數據的內存,那麼一切將會不堪設想。
實際上,緩沖區溢出通常有兩種,堆溢出和堆棧溢出。盡管兩者實質都是一樣,但由於利用的方式不同,我將在下面分開介紹。不過在介紹之前,還是來做一些必要的知識預備。
三、知識預備
要理解大多數緩沖區溢出的本質,首先需要理解當程序運行時機器中的內存是如何分配的。在許多系統上,每個進程都有其自己的虛擬地址空間,它們以某種方式映射到實際內存。我們不必關心描述用來將虛擬地址空間映射成基本體系結構的確切機制,而只關心理論上允許定址大塊連續內存的進程。
程序運行時,其內存裡面一般都包含這些部分:1)程序參數和程序環境;2)程序堆棧,它通常在程序執行時增長,一般情況下,它向下朝堆增長。3)堆,它也在程序執行時增長,相反,它向上朝堆棧增長;4)BSS 段,它包含未初始化的全局可用的數據(例如,全局變數); 5)數據段,它包含初始化的全局可用的數據(通常是全局變數);6)文本段,它包含只讀程序代碼。BSS、數據和文本段組成靜態內存:在程序運行之前這些段的大小已經固定。程序運行時雖然可以更改個別變數,但不能將數據分配到這些段中。下面以一個簡單的例子來說明以上的看起來讓人頭暈的東西:
#include<stdio.h>
char buf[3]="abc";
int i;
void main()
{
i=1
return;
}
其中,i屬於BBS段,而buf屬於數據段。兩者都屬於靜態內存,因為他們在程序中雖然可以改變值,但是其分配的內存大小是固定的,如buf的數據大於三個字元,將會覆蓋其他數據。
與靜態內存形成對比,堆和堆棧是動態的,可以在程序運行的時候改變大小。堆的程序員介面因語言而異。在C語言中,堆是經由 malloc() 和其它相關函數來訪問的,而C++中的new運算符則是堆的程序員介面。堆棧則比較特殊,主要是在調用函數時來保存現場,以便函數返回之後能繼續運行。
四、堆溢出
堆溢出的思路很簡單,覆蓋重要的變數以達到自己的目的。而在實際操作的時候,這顯得比較困難,尤其是源代碼不可見的時候。第一,你必須確定哪個變數是重要的變數;第二,你必須找到一個內存地址比目標變數低的溢出點;第三,在特定目的下,你還必須讓在為了覆蓋目標變數而在中途覆蓋了其他變數之後,程序依然能運行下去。下面以一個源代碼看見的程序來舉例演示一次簡單的堆溢出是如何發生的:
#include "malloc.h"
#include "string.h"
#include "stdio.h"
void main()
{

char *large_str = (char *)malloc(sizeof(char)*1024);
char *important = (char *)malloc(sizeof(char)*6);
char *str = (char *)malloc(sizeof(char)*4);
strcpy(important,"abcdef");//給important賦初值

//下面兩行代碼是為了看str和important的地址
printf("%d/n",str);
printf("%d/n",important);
gets(large_str);//輸入一個字元串
strcpy(str, large_str);//代碼本意是將輸入的字元串拷貝到str
printf("%s/n",important);
}
在實際應用中,這樣的代碼當然是不存在的,這只是一個最簡單的實驗程序。現在我們的目標是important這個字元串變成"hacker"。str和important的地址在不同的環境中並不是一定的,我這里是7868032和7868080。很好,important的地址比str大,這就為溢出創造了可能。計算一下可以知道,兩者中間隔了48個位元組,因此在輸入溢出字元串時候,可以先輸入48個任意字元,然後再輸入hakcer回車,哈哈,出來了,important成了"hacker"。

五、堆棧溢出
堆溢出的一個關鍵問題是很難找到所謂的重要變數,而堆棧溢出則不存在這個問題,因為它將覆蓋一個非常重要的東西----函數的返回地址。在進行函數調用的時候,斷點或者說返回地址將保存到堆棧裡面,以便函數結束之後繼續運行。而堆棧溢出的思路就是在函數裡面找到一個溢出點,把堆棧裡面的返回地址覆蓋,替換成一個自己指定的地方,而在那個地方,我們將把一些精心設計了的攻擊代碼。由於攻擊代碼的編寫需要一些匯編知識,這里我將不打算涉及。我們這里的目標是寫出一個通過覆蓋堆棧返回地址而讓程序執行到另一個函數的堆棧溢出演示程序。
因為堆棧是往下增加的,因此,先進入堆棧的地址反而要大,這為在函數中找到溢出點提供了可能。試想,而堆棧是往上增加的,我們將永遠無法在函數裡面找到一個溢出點去覆蓋返回地址。還是先從一個最簡單的例子開始:
void test(int i)
{
char buf[12];
}
void main()
{
test(1);
}
test 函數具有一個局部參數和一個靜態分配的緩沖區。為了查看這兩個變數所在的內存地址(彼此相對的地址),我們將對代碼略作修改:
void test(int i)
{
char buf[12];
printf("&i = %d/n", &i);
printf("&buf[0] = %d/n", buf);
}
void main()
{
test(1);
}
需要說明的是,由於個人習慣的原因,我把地址結果輸出成10進制形式,但願這並不影響文章的敘述。在我這里,產生下列輸出:&i = 6684072 &buf[0] = 6684052。這里我補充一下,當調用一個函數的時候,首先是參數入棧,然後是返回地址。並且,這些數據都是倒著表示的,因為返回地址是4個位元組,所以可以知道,返回地址應該是保存在從6684068到6684071。因為數據是倒著表示的,所以實際上返回地址就是:buf[19]*256*256*256+buf[18]*256*256+buf[17]*256+buf[16]。
我們的目標還沒有達到,下面我們繼續。在上面程序的基礎,修改成:
#include <stdio.h>
void main()
{
void test(int i);
test(1);
}
void test(int i)
{
void come();
char buf[12];//用於發生溢出的數組
int addr[4];
int k=(int)&i-(int)buf;//計算參數到溢出數組之間的距離
int go=(int)&come;
//由於EIP地址是倒著表示的,所以首先把come()函數的地址分離成位元組
addr[0]=(go << 24)>>24;
addr[1]=(go << 16)>>24;
addr[2]=(go << 8)>>24;
addr[3]=go>>24;
//用come()函數的地址覆蓋EIP
for(int j=0;j<4;j++)
{
buf[k-j-1]=addr[3-j];
}
}
void come()
{
printf("Success!");
}
一切搞定!運行之後,"Success!"成功列印出來!不過,由於這個程序破壞了堆棧,所以系統會提示程序遇到問題需要關閉。但這並不要緊,因為至少我們已經邁出了萬里長征的第一步。

⑥ 安全漏洞的發掘方法

首先必須清楚安全漏洞是軟體BUG的一個子集,一切軟體測試的手段都對安全漏洞發掘實用。現在」黑客「用的各種漏洞發掘手段里有模式可循的有:
fuzz測試(黑盒測試),通過構造可能導致程序出現問題的方式構造輸入數據進行自動測試。
源碼審計(白盒測試),現在有了一系列的工具都能協助發現程序中的安全BUG,最簡單的就是你手上最新版本的C語言編譯器。
IDA反匯編審計(灰盒測試),這和上面的源碼審計非常類似,唯一不同的是很多時候你能獲得軟體,但你無法拿到源碼來審計,但IDA是一個非常強大的反匯編平台,能讓你基於匯編碼(其實也是源碼的等價物)進行安全審計。
動態跟蹤分析,就是記錄程序在不同條件下執行的全部和安全問題相關的操作(如文件操作),然後分析這些操作序列是否存在問題,這是競爭條件類漏洞發現的主要途徑之一,其他的污點傳播跟蹤也屬於這類。
補丁比較,廠商的軟體出了問題通常都會在補丁中解決,通過對比補丁前後文件的源碼(或反匯編碼)就能了解到漏洞的具體細節。
以上手段中無論是用哪種都涉及到一個關鍵點:需要通過人工分析來找到全面的流程覆蓋路徑。分析手法多種多樣,有分析設計文檔、分析源碼、分析反匯編代碼、動態調試程序等。

⑦ 如何檢測C語言中的內存漏洞(leak)

在動態分配的內存單元(即由函數malloc()或ealloc()分配的內存單元)不再使用卻沒有被釋放的情況下,會出現內存漏洞。未釋放內存單元本身並不是一種錯誤,編譯程序不會因此報告出錯,程序也不會因此而立即崩潰。但是,如果不再使用而又沒有被釋放的內存單元越來越多,程序所能使用的內存空間就越來越小。最終,當程序試圖要求分配內存時,就會發現已經沒有可用的內存空間。這時,尤其是當程序員沒有考慮到內存分配失敗的可能性時,程序的運行就會出現異常現象。
內存漏洞是最難檢測的錯誤之一,同時也是最危險的錯誤。導致這個問題的編程錯誤很可能出現在程序的開始部分,但只有當程序奠名其妙地使用完內存後,這個問題才會暴露出來。
此時去檢查當前那條導致內存分配失敗的語句是無濟於事的,因為那些分配了內存卻未能按時釋放內存的代碼可能在程序的其它地方。
遺憾的是C語言並沒有為檢測或修復內存漏洞提供現成的方法。除非使用提供這種功能的商業軟體包,否則,程序員就需要以很大的耐心和精力去檢測和修復內存漏洞。最好的辦法是在編寫程序時就充分考慮到內存漏洞的可能性,並小心謹慎地處理這種可能性。
導致內存漏洞的最簡單的也是最常見的原因是忘記釋放分配給臨時緩沖區的內存空間,請看下述程序段:
# include
# include /** Say hello to the user's and put the user's name in UPPERCASE.*/void SayHi( char *name ){char * UpName;int a;UpName = malloc( strlen( name ) +1);
/ * Allocate space for the name * /
for( a =0; a

⑧ 關於C語言的:一個程序的漏洞修補

我覺得這題最好用switch分支,而且既然在「printf("請選擇運算符號(1為加,2為減,3為乘,4為除,5為關閉程序),程序會自動生成一個運算數不超過2位數的算術式:"); 」輸入字母時判斷為錯誤,我覺得後面就沒有再輸入答案的必要了,所以我改為在「printf("請選擇運算符號(1為加,2為減,3為乘,4為除,5為關閉程序),程序會自動生成一個運算數不超過2位數的算術式:"); 」前加一個" Loop:",把continue改為goto Loop;雖然在C中goto語句最好不使用,但我覺得這題足取!

⑨ 關於c語言printf 與scanf問題 漏洞

這個是可以實現的,這樣就行。#include#include#include#includeintmain(){intn;printf("請輸入數字:【】\b\b");scanf("%d",&n);}\b是退格符號。因為「【】」是中文符號,所以佔得位元組數與英文字元不一樣。你自己可以調一下格式。而且這兒還有一個關鍵的問題,就是當「【】」內的內容夠長時,就會把後面的括弧「】」覆蓋掉。你可以自己試一下