一般的な背景:私は、次のようなstrcpy()関数呼び出しを利用するCでBoFの例を実装しようとするエコーサーバーを作成しました。
// .... including the corresponding libraries depending on Host environment
#include <stdio.h> // crossed platform headers
#include <string.h> // string header, for strcpy
#include <stdlib.h> // stardard lib, for exit()
void echo(void); // infinite loop echo serving client
char* vuln_func(char* recieved); // BoF vulnerable function that uses strcpy from string.h
int main(void)
{
... setting up echo server
echo();
return 0;
}
void echo(void)
{
char *send_str; // declaring the pointer to the string recieved from vulnFunc
char recv_str[1024]; // variable declaration to store input string from client
// infinite loop to echo serve clients
while(1)
{
... recieving string from client and storing it starting at location recv_str
// calling vuln_func and inputting the received string from client
send_str = vuln_func(recv_str);
...echoing the send_str back to the client
}
}
char* vuln_func( char* recieved)
{
char* sending_str = (char*)calloc(100, sizeof(char));
char buf[100];
int i; // declaring counter for loop
strcpy(buf, recieved);
for (i = 0; i < strlen(buf); i++) // for loop to populate return string with the send
{
sending_str[i] = buf[i];
}
return sending_str;
}
Problem:したがって、サーバーに十分な大きさの入力文字列を入力すると、サーバーはオフセット41414141(必要なもの)でアクセス違反を生成します。ただし、違反の時点で逆アセンブラ/デバッガ(イミュニティデバッガを使用した)でexeを逆アセンブルすると、ESPもEIPもAsの文字列で上書きされませんでした(たとえば))。 EBPレジスタは、Asのオーバーフローした大きな文字列で上書きされました。
Solution:だから私はグーグルして、同じ種類の同様のサンプルコード(BoF vulnを備えたEcho Server)を見て、次のようなvuln_funcで異なることを試しました:
void vuln_func( char* recieved)
{
char buf[100];
strcpy(buf, recieved);
}
または:
int vuln_func( char* recieved)
{
char buf[100];
strcpy(buf, recieved);
return 1;
}
エコー関数は次のようになります。
void echo(void)
{
char recv_str[1024]; // variable declaration to store input string from client
// infinite loop to echo serve clients
while(1)
{
... recieving string from client and storing it starting at location recv_str
// calling vuln_func with string received from client
vuln_func(recv_str);
...echoing the recv_str back to the client
}
}
したがって、ehoがsend_strの代わりにrecv_strをエコーバックして、vhon_func呼び出しの目的全体を無効にしますが、このBoFの脆弱性を実証するために、ここに残します。イミュニティデバッガーで確認した後、ESPとEIPレジスターの両方が文字列( "A * 128")で正常に上書きされます。問題が修正されました!!素晴らしい
質問:なぜ問題はそのように振る舞ったのですか?
ご覧のとおり、問題は解決されましたが、なぜ機能したのかわかりません。説明するか、書き込み方向を指定してください。多くの称賛と事前に感謝します。
私の推測では、他のローカル変数(iまたはending_str)を上書きしたため、時期尚早のクラッシュが発生しました。
何が起こっているかを確認するには、生成されたコードを調べる必要があります。設定に応じて、コンパイラーは、呼び出された関数をすべてインライン化するなど、コードに対して興味深いことを行うことができるため、戻りアドレスの上書きが大幅に遅くなります。
回答が研究の方向性とより多くのテストを提供したため、@ manducaがベストアンサーに投票しました。そして、いくつかのテストの後、私は尋ねられた私の質問に対する完全な答えを結論付けることができました: