: buffer overflow: buffer overrun



[1][2]

バッファオーバーフローの具体例

編集

簡単な例

編集

28 A2 BA  0 B  1,979 1
変数名 A B
NUL NUL NUL NUL NUL NUL NUL NUL 1979
16進数値 00 00 00 00 00 00 00 00 07 BB

ここで、プログラムがバッファ Aヌル終端文字列「excessive」を書きこもうとした場合を考える。文字列の長さチェックが行われていないと、この処理で B の値が上書きされてしまう。

変数名 A B
「e」 「x」 「c」 「e」 「s」 「s」 「i」 「v」 25856
16進数値 65 78 63 65 73 73 69 76 65 00

 BB ASCIIe 25,856  A B B

電子メールアドレスを題材にした例

編集

使

200

(一)200

(二)200

(三)

(四)




C言語特有の例

編集

Cgets使使Cscanf[3]

getsgets使Linux Programmer's Manualgets()使200gets200EOF
#include <stdio.h>
int main(int argc, char *argv[])
{
  char buf[200];
  gets(buf);
  ....
}

gets関数の代わりにfgets関数を用いることで、この問題を回避できる(fgets#getsを置き換える例等を参照)。fgets関数にはバッファのサイズを渡すことができ、このバイト数を超えてバッファに書き込みを行わない。したがってバッファサイズが正しく設定されていれば、fgets関数においてバッファオーバーフローは起こり得ない。

これ以外のC言語の標準文字列処理関数の多くにも同様の問題(脆弱性)がある。

バッファオーバーフロー攻撃

編集

Use-After-Free[1]

CWE
番号 名称
CWE-120 入力サイズをチェックしないバッファのコピー(古典的バッファオーバーフロー)[4]
CWE-121 スタックベースのバッファオーバーフロー[5]
CWE-122 ヒープベースのバッファオーバーフロー[6]

3CWE-119: [7][7][8]

3CC++[4][5][6][4]

3[4][5][6][4][5][6]3[4][5][6][4][5][6]

CWECWE-193: Off-by-one[9][10][11]

古典的バッファオーバーフロー攻撃

編集

ABBA[4][4][4]

CC++strcpyscanf[4]strcpyscanfgets[4]

AAxx

スタックベースのバッファオーバーフロー攻撃

編集

スタックベースのバッファオーバーフローは「上書きされるバッファがスタック(すなわち、局所変数や、まれに関数のパラメータ)にアロケートされる」[5]事が可能な場合に生じる脆弱性である。このような脆弱性はファジングを使用して発見されることが多い[12]

C言語・C++におけるメモリ領域

編集

 (OS) WindowsLinuxOS使[1]

CC++bss[2][3]malloc[13]

[13]
最低位 最高位
コード領域 静的領域 ヒープ領域

(高位に向かって成長→)

スタック領域

(←低位に向かって成長)

データ領域 bss領域

スタック領域はプロセス中で呼ばれる関数のコールスタックを格納する領域で、コールスタック中の各関数のデータ(スタックフレームという)を並べて格納している[14]。プロセス中で関数fが関数gを呼び出した場合、コールスタックは以下のようになる[14][15]

低位アドレス 高位アドレス
gのスタックフレーム fのスタックフレーム
gの処理に必要な一時的な情報 gの局所変数 gのSFP gのリターンアドレス gの引数の値 fの処理に必要な一時的な情報

[4]ggSFPSFPfgfSFPgSFPSFPSaved Frame Pointer退[14]

gf[5][14]

攻撃の基本的アイデア

編集

gASCIIchar A[10]A10gA10g

g



[15]

AA[i]ig[15]
低位アドレス 高位アドレス
gのスタックフレーム fのスタックフレーム
gの処理に必要な一時的な情報 gの局所変数 gのSFP gのリターンアドレス gの引数の値 fの処理に必要な一時的な情報
(シェルコード)… (シェルコードの仮想アドレス)

gg[15]

NOPスレッド

編集

g[16]NOP

NOP[16]CPU[16]NOP(sled)[16]NOP

g

NOP  NOP ()()()

NOP  NOPNOPNOPg
gのスタックフレーム fのスタックフレーム
gの局所変数 gのSFP gのリターンアドレス
NOP… NOP NOPNOP (シェルコード)…(戻りアドレス)…(戻りアドレス) (戻りアドレス) (戻りアドレス)…

gNOPgNOPNOP[16][17]NOPNOP

NOP使使NOP[18]

戻りアドレスの値の予想

編集

hhg

hxhgghgvar_add

var_add = &x - ()

[16]&xxNOP使var_add

g(使)NOPh[16]

埋め込めるコード量が小さい場合の対処

編集

gNOP++ggg

NOP+NOP+ggNOP[19]

hgetenv()[20]

ヒープスプレー

編集

NOPgNOPNOP[21]

NOPNOPNOPNOPNOP[21]

JavaScript使[21]

トランポリング

編集

(trampolining)Rjump Rcall R使DLL使MetasploitWindows使[22]

ヒープベースのバッファオーバーフロー

編集

malloc[6]2[23]malloc2malloc2

mallocのメモリ管理

編集

mallocmalloc

malloc使chunk[24]mallocchunk[24]chunkchunk[24]mallocchunk[25][24]chunkchunkfreefreechunk[24]

chunkchunkchunkWindowsflink[26]linuxfd[24]chunkWindowsblink[26]linuxbk[24]

使chunk使chunk (coalesce) 1chunk[26]

mallocのメタデータの書き換え

編集

malloc使Windows XP SP1Windowsmalloc使chunkflinkblink[27]flinkblinkcoalescemalloc[27]

バッファオーバーフローの結果

編集

write-what-where状態

編集

write-what-where"write-what-where condition"[28]CWE-123[28][29][28]

write-what-where[28][28][28]

プログラムのフリーズ・クラッシュ

編集

攻撃者は意図的にバッファオーバーフローを起こすによりプログラムをクラッシュさせたり[4][5][6]、処理を書き換えて無限ループに追い込むことでプログラムをフリーズさせてたり[4][5][6]する事でプログラムの可用性を侵害できる。

関数ポインタの書き換え

編集

古典的バッファオーバーフロー[30]やヒープオーバーフロー[6]などの結果として、関数ポインタの書き換えが可能になるケースがある。攻撃者はnmコマンドを用いる事でプログラム中で用いられている様々な関数のアドレスを知る事ができるので[30]、nmの結果を参照して攻撃に利用可能な関数に関数ポインタの値を書き換えられる。

技術的対策

編集

コンパイラやライブラリによる対策

編集

カナリア

編集

SFPcanary[31][32][33]

安全なライブラリへの置き換え

編集

標準Cライブラリ等にはバッファオーバーフロー検知機能が施されていない関数が収録されているので、これを検知機能を持った関数に置き換えたライブラリを標準Cライブラリの代わりに使う事で攻撃を検知できる。例えばLibsafe[36]は標準Cライブラリのstrcpy(*dest,*src)をより安全な関数に置き換えており、入力srcのサイズがコピー先のdestのサイズが大きいか否かを検知できる[37]

実行環境での対策

編集

Write XOR eXecute

編集

NOPWrite XOR eXecute[37]W X[37]W^X[37]W XWindowsDEP: data execution prevention[37][38]DEPSEH[39] UNIXOpenBSDmacOSW X

PaX[40]

Exec Shield[41]

Openwall[42]



BufferShield[43]

StackDefender[44]

2018使x64W XNX[45]NXXD[45]

ASLRAddress Space Layout RandomizationDLLOS

ASLRReturn-to-libcReturn-oriented programming

ASLRKASLRkernel address space layout randomizationlinux(3.14)[46]iOS(6)[47]KASLRKernel page-table isolation

gccg++ASLRASLR-pie使[48]ASLR-fPIC[48]

開発時の対策

編集

プログラミング言語・プログラミング環境の選択

編集

CC++AdaEiffelLISPModula-2SmalltalkOCamlCCycloneD

Java.NET Framework[6]

ソースコード記述時の対策

編集

バッファオーバーフロー攻撃は主にC言語やC++を対象としたものなので、以下ではプログラミング言語としてC言語かC++を選んだ場合に対しての対策を述べる。

人手による対策

編集

バッファオーバーフロー攻撃を防ぐには、領域長とデータ長を意識したプログラミングを行う事が重要である[51]

  • データをバッファに挿入する際には、データ長がバッファ長を超えない事を調べる検査ロジックをプログラムに書き加えておく[51]
  • データが文字列の場合は文字列長を数え間違えないよう、文字列の終端にあるナル文字も数える[51]
  • データ長に依存したループを書くときに間違ってループを回しすぎる(Off-by-oneエラー)事が無いようにする[51]
  • 事前にデータ長の上限がわからない場合は、バッファをmalloc等で動的に確保し、不要になったら確実にfreeする[51]

安全なライブラリの使用

編集

C使使

Managed StringLinux[51]

ISO/IEC 9899:2011 Annex KWindows[51]

SafeStrLinuxWindows[51]

"The Better String Library"[52]

Vstr[53]

Erwin[54]

BSD libcCstrlcpystrlcat

静的コード解析時における対策

編集

人手による静的コード解析

編集

静的コード解析の際、前述した領域長とデータ長を意識したプログラミングが行われているか再確認し、strcpy, sprintf 等のデータ領域長を意識しないライブラリ関数が使用されていないか、使用されているならその入力長の計算が間違っていないかを確認する[55]。またヒープオーバーフロー対策としてmalloc/freeやnew/deleteの多用に注意し、関数ポインタの書き換えを防ぐために関数ポインタが多用に注意し[55]、攻撃パターンを見逃す事がないようデータの一部を切り捨てている関数に注意する[55]

自動化された静的コード解析

編集

strcpy使[55][55]使[55]


発展的な攻撃

編集

Return-to-libc攻撃

編集

NOPW X

W XReturn-to-libcC(libc)DLLW X

ASLRlibc

Return-to-Register攻撃

編集

Return-to-Register攻撃とは「ret命令実行後にレジスタが指しているアドレスに不正な命令コードを挿入し、その上で”そのレジスタ値に実行を移す命令群が格納されているアドレス”でリターンアドレスを書き換える攻撃」[56]のことである。

例えばレジスタAがバッファの先頭へのポインタを格納しているとすると、そのときレジスタAをオペランドにとる任意のjumpまたはcall命令が実行フローの支配権を得るのに使用できる[57]

ret2esp攻撃

編集

ret2espReturn to esp2017ASLR.textASLR[58]espx86.textjmp esp[58]espjmp espjmp espjmp espesp[58]

歴史

編集

1972[?]Anderson 1972 


Anderson 1972, p. 61: The code performing this function does not check the source and destination addresses properly, permitting portions of the monitor to be overlaid by the user. This can be used to inject code into the monitor that will permit the user to seize control of the machine.








1988Morris wormUNIXfinger[59] 1995Thomas LopaticBugtraq稿[60] 1996Aleph onePhrack"Smashing the Stack for Fun and Profit"[61] 使

22001Code RedInternet Information Services (IIS) 5.0[62] 2003SQL SlammerMicrosoft SQL Server 2000[63]

2003XboxHomebrewMod[64] PlayStation 2PS2 Independence Exploit使WiiHomebrew 

参考文献

編集

; ;  (2015-03-17). . . ISBN 978-4339024951 

Erickson, Jon  (2011-10-22). Hacking:  2 . . ISBN 978-4873115146 

 C/C++. . 20181214

CTF1. NTT. 20181214


Markus Gaasedelen. Heap Exploitation Modern Binary Exploitation CSCI 4968 - Spring 2015 (pdf). CyberSecurity group, Department of Computer Science, Rensselaer Polytechnic Institute (RPI). 20181218

2013-12-27 Monthly Research Heap Exploit. FFRI. 20181226
Monthly Research Heap Exploit (pdf). FFRI (20131227). 20181218

, , , , , 調201420142201410767-774NAID 1700000873422021122 

"Discovering and exploiting a remote buffer overflow vulnerability in an FTP server" by Raykoid666

"Smashing the Stack for Fun and Profit" by Aleph One

An Overview and Example of the Buffer-Overflow Exploit. pps. 16-21.

CERT Secure Coding Standards

CERT Secure Coding Initiative

Secure Coding in C and C++

SANS: inside the buffer overflow attack

"Advances in adjacent memory overflows" by Nomenumbra

A Comparison of Buffer Overflow Prevention Implementations and Weaknesses

More Security Whitepapers about Buffer Overflows

Chapter 12: Writing Exploits III from Sockets, Shellcode, Porting & Coding: Reverse Engineering Exploits and Tool Coding for Security Professionals by James C. Foster (ISBN 1-59749-005-9). Detailed explanation of how to use Metasploit to develop a buffer overflow exploit from scratch.

Anderson, James P. (1972). Computer Security Technology Planning Study (PDF). 2023124

関連項目

編集

脚注

編集

注釈

編集


(一)^ i386Windows2 GBLinux1 GB (ASLR) 

(二)^ Block Started by Symbol

(三)^ bss

(四)^ x86ebp (Stack Base Pointer Register)

(五)^ x86eip (Extended Instruction Pointer)

(六)^ Delphi$RangeChecks[49][50]

出典

編集


(一)^ ab,  &  2015, p. 59.

(二)^ 10 : #1 .  C/C++ 2007. . 20181214

(三)^  [] scanf . C/C++. . 20201122010228 scanf 

(四)^ abcdefghijklmnCWE-120: Buffer Copy without Checking Size of Input ('Classic Buffer Overflow'). Mitre. 20181218

(五)^ abcdefghiCWE-121: Stack-based Buffer Overflow. Mitre. 20181218

(六)^ abcdefghijCWE-122: Heap-based Buffer Overflow. Mitre. 20181218

(七)^ abCWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer. Mitre. 20181218

(八)^ CWE-787: Out-of-bounds Write. Mitre. 20181218

(九)^ CWE-193: Off-by-one Error. Mitre. 20181218

(十)^ CWE-131: Incorrect Calculation of Buffer Size. Mitre. 20181218

(11)^ CWE-680: Integer Overflow to Buffer Overflow. Mitre. 20181218

(12)^ The Exploitant - Security info and tutorials. 20091129

(13)^ abErickson 2011, pp. 8788.

(14)^ abcdErickson 2011, p. 84.

(15)^ abcd,  &  2015, pp. 6061.

(16)^ abcdefgErickson 2011, pp. 161164.

(17)^ ,  &  2015, p. 64.

(18)^ Akritidis, P.; Markatos, Evangelos P.; Polychronakis, M.; Anagnostakis, Kostas D. (2005). "STRIDE: Polymorphic Sled Detection through Instruction Sequence Analysis." (PDF). Proceedings of the 20th IFIP International Information Security Conference (IFIP/SEC 2005). IFIP International Information Security Conference.

(19)^ Erickson 2011, pp. 164168.

(20)^ Erickson 2011, pp. 168173.

(21)^ abc,  &  2015, pp. 6567.

(22)^ The Metasploit Opcode Database. 20075122007515

(23)^ Erickson 2011, pp. 173179.

(24)^ abcdefg   (20071130). malloc(3). VA Linux Systems Japan. 20181226

(25)^ Doug Lea. A Memory Allocator. 20181226

(26)^ abcFFRI 2013, p. 7.

(27)^ abFFRI 2013, p. 8.

(28)^ abcdefCWE-123: Write-what-where Condition. Mitre. 20181226

(29)^ JVNDB-2015-004721 Silicon Integrated Systems WindowsXP Display Manager . JVN iPedia. 20181226

(30)^ abErickson 2011, pp. 179192.

(31)^  (200695). 14: . ThinkIT. . p. 2. 201911

(32)^ David Wheeler (2004127).   . IBM. 201911

(33)^ abc,  &  2015, pp. 6970.

(34)^ StackGuard: Automatic Adaptive Detection and Prevention of Buffer-Overflow Attacks by Cowan et al. (PDF). 201229

(35)^ /GS ( ) (2016114). 201229

(36)^ Libsafe - Free Software Directory. 201229

(37)^ abcde,  &  2015, pp. 7173.

(38)^ Windows XP Service Pack 2Windows XP Tablet PC Edition 2005 Windows Server 2003  (DEP) . 2012217

(39)^ Bypassing Windows Hardware-enforced Data Execution Prevention. 2007520

(40)^ PaX: Homepage of the PaX team. 2012217

(41)^ KernelTrap.Org. 20125292012217

(42)^ Openwall Linux kernel patch 2.4.34-ow1. 2012217

(43)^ BufferShield: Prevention of Buffer Overflow Exploitation for Windows. 2012217

(44)^ NGSec Stack Defender. 20075132012217

(45)^ abNX. ITe-Words. 201911

(46)^ Linux kernel 3.14, Section 1.7. Kernel address space randomization. kernelnewbies.org (2014330). 201442

(47)^ Stefan Esser. iOS 6 Exploitation 280 Days Later. 201911

(48)^ abHardening. Devian. 201911

(49)^ Neil Moffatt. Delphi Basics : $RangeChecks command. 201223

(50)^  - RAD Studio

(51)^ abcdefgh10  : #2 . (2007). . 20181227

(52)^ The Better String Library. 201228

(53)^ The Vstr Homepage. 201228

(54)^ The Erwin Homepage. 201228

(55)^ abcdef10  : #3 . (2007). . 20181227

(56)^ 調 2014, p. 769.

(57)^ Shah, Saumil (2006). 1 - Saumil Shah - Writing Metasploit Plugins.pdf "Writing Metasploit Plugins: from vulnerability to exploit" (PDF). Hack In The Box. Kuala Lumpur. {{cite conference}}: |url= ()

(58)^ abcCTF1. NTT. 201911

(59)^ "A Tour of The Worm" by Donn Seeley, University of Utah. 2007520200763

(60)^ Bugtraq security mailing list archive. 200791200763

(61)^ Smashing the Stack for Fun and Profit. 200763

(62)^ eEye Digital Security. 200763

(63)^ Microsoft Technet Security Bulletin MS02-039. 200763

(64)^ Hacker breaks Xbox protection without mod-chip. 2007927200763