1. 程式人生 > 實用技巧 >逆向 - Strcpy緩衝區溢位漏洞

逆向 - Strcpy緩衝區溢位漏洞

緩衝區漏洞千千種,這次遇到實驗才來講一講我想明白的題目。

利用棧溢位漏洞破解口令

原始碼:

#include<stdio.h>
#include<string.h>
#define PASSWORD "1234567"
int verify_password(char* password)
{
int authenticated=0xEEEEEEEE;
char buffer[8];
printf("My stack looks like:\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n\n");
authenticated=strcmp(password,PASSWORD);
printf(
"My stack looks like:\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n\n"); //printf("flag的值為:%d\n",authenticated); strcpy(buffer,password); printf("%s\n",buffer); printf("My stack looks like:\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n\n"); //printf("覆蓋以後flag的值為:%d\n",authenticated); return authenticated; } int main() {
int valid_flag=0x0; char password[8]; printf("please input password:"); scanf("%s",password); //printf("傳的值為:%d\n",verify_password(password)); valid_flag=verify_password(password); //printf("傳完之後flag的值為:%d\n",valid_flag); if (valid_flag) { printf("incorrect password!\n\n"); } else { printf(
"Congratulation! You have passed the verification!\n"); } }

1.首先,觀察一下程式,能判斷造成棧溢位的程式碼是

strcpy(buffer,password);

把執行到呼叫verify_password函式的堆疊來畫一下

2.來分析一下程式碼的作用

(注:strcpy比較的是ASCII值,數字輸入時雖然是“數字”,但是它是字串)

我們能夠使用strcpy覆蓋並修改return給main函式的值,讓main函式誤以為我們輸入了正確的密碼。

看下面程式碼知判斷密碼正確的flag值為0,否則為不正確(包括大於0和小於0),因此我們就要return給valid_flag一個0。

3.首先執行

輸入12個2,因為buffer最多存8個位元組,會溢位4位元組到緊接著的堆疊,字串結尾還有00('\0')也要儲存

flag值被結束符00覆蓋了,因此被誤認為輸入正確

4.特殊情況

如果輸入12個1為什麼會認為輸入錯誤呢?

首先strcpy是逐位比較,遇到不同位相減返回值的,輸入12個1,遇到第二位2時,1-2=-1,因此返回-1(16進位制存的是補碼為FFFFFFFF)

因為return的值即flag位的數為負數,儲存時補碼佔4位元組,雖然字串有結束符00,但是還遠遠不能覆蓋,返回的值不為0,因此被判斷為輸入錯誤

實際上只要輸入的字元為12位,且第一個不同位的ASCII值比預設密碼的那位ASCII值大就能繞過密碼的判斷了。