Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
RIG#3-1
Search
RIG
October 09, 2019
Technology
0
69
RIG#3-1
2019/10/09に実施されたRIGの第3回勉強会で使用した発表資料「Shellcode Injectionの実践」です.
RIG
October 09, 2019
Tweet
Share
More Decks by RIG
See All by RIG
RIG#2-1
sfcrig
0
40
RIG#2-3
sfcrig
0
99
RIG#1-2
sfcrig
0
210
Other Decks in Technology
See All in Technology
JSON攻略法.pdf
miyakemito
8
5k
APIファーストなプロダクトマネジメントの実践 〜SaaSus Platformでの例〜 / "Practicing API-First Product Management - An Example with SaaSus Platform
oztick139
0
100
自己改善からチームを動かす! 「セルフエンジニアリングマネージャー」のすゝめ
shoota
6
550
ServiceNow Knowledge 24の歩き方 EYストラテジー・アンド・コンサルティング
manarobot
0
190
Cloud Native Java with Spring Boot (CNCF Aarhus, April 2024)
thomasvitale
1
170
ServiceNow Knowledge Learning Rise up
manarobot
0
210
プラットフォームってつくることより計測することが重要なんじゃないかという話 / Platform Engineering Meetup #8
taishin
1
350
DevOpsメトリクスとアウトカムの接続にトライ!開発プロセスを通して計測できるメトリクスの活用方法
ham0215
2
240
よく聞くけど使ったことないソフトウェアNo.1 KafkaとSnowflake
foursue
4
360
生産性向上チームの紹介
cybozuinsideout
PRO
1
870
20分で完全に理解するGrafanaダッシュボード
hamadakoji
3
560
Gitlab本から学んだこと - そーだいなるプレイバック / gitlab-book
soudai
4
370
Featured
See All Featured
How GitHub Uses GitHub to Build GitHub
holman
468
290k
Become a Pro
speakerdeck
PRO
11
4.5k
Debugging Ruby Performance
tmm1
70
11k
A better future with KSS
kneath
231
16k
Robots, Beer and Maslow
schacon
PRO
155
7.9k
Designing on Purpose - Digital PM Summit 2013
jponch
110
6.5k
GitHub's CSS Performance
jonrohan
1025
450k
Clear Off the Table
cherdarchuk
84
310k
Making Projects Easy
brettharned
108
5.5k
Fashionably flexible responsive web design (full day workshop)
malarkey
398
65k
The Power of CSS Pseudo Elements
geoffreycrofte
60
5k
Building Your Own Lightsaber
phodgson
99
5.7k
Transcript
Shellcode Injection RIG#3-1 (2019/10/09) Yuma Ueda (cyan)
Shellcode Injection • BOFを利用してコンピュータに任意コードを実行させる攻撃 • そもそも/bin/shなどシェルの実行を目的とした攻撃が大半であったためこの 種の攻撃を行うためのペイロードを総称してShellcodeと呼んでいる 2
How does it work? スタックオーバーフロー • スタックに乗っているリターンアドレスを書き換え,配置したshellcodeを実 行させる ヒープオーバーフロー •
ハンドラーなどのアドレスを書き換える 3
実践 • 何事も手を動かして実践,実証! • 簡単なpwnableの問題でshellcode Injectionを実践しよう! 4
start from pwnable.tw (https://pwnable.tw/challenge/#1) pwnable • 基本的にはサーバ上で動作するプログラ ムの脆弱性を突きflagを奪取する • バイナリはダウンロードさせてくれる
(当然) とりあえずディスアセンブル • objdump -D $path_to_binary • コマンドはLinux前提で書いてます • 右のような出力が得られる 5
start アセンブリを追う 8048060 push %esp 8048061 push $0x804809d <_exit> 8048066
xor %eax, %eax 8048068 xor %ebx, %ebx 804806a xor %ecx, %ecx old_esp esp 何をしている? • スタックにespの値を積む. • ここで注意すべきはpush %espが 実行され,espが4Byte下がる前の 値がスタックに積まれること. 6
start アセンブリを追う 8048060 push %esp 8048061 push $0x804809d <_exit> 8048066
xor %eax, %eax 8048068 xor %ebx, %ebx 804806a xor %ecx, %ecx old_esp 0x804809d <_exit> esp 何をしている? • _exitセクションのアドレスをス タックに積む(ここにRETしたい) 7
start アセンブリを追う 8048060 push %esp 8048061 push $0x804809d <_exit> 8048066
xor %eax, %eax 8048068 xor %ebx, %ebx 804806a xor %ecx, %ecx 804806c xor %edx, %edx old_esp 0x804809d <_exit> esp 何をしている? • レジスタのゼロクリアを行ってい る なんでmov %eax, $0じゃないの? • xor命令はバイナリサイズが小さい (2Byte) 8
start アセンブリを追う 804806c xor %edx, %edx 804806e push $0x3a465443 8048073
push $0x20656874 8048078 push $0x20747261 804807d push $0x74732073 8048082 push $0x2774654c old_esp 0x804809d <_exit> 0x3a465443 (:FTC) 0x20656874([ws]eht) 0x20747261 ([ws]tra) 0x74732073 (ts[ws]s) 0x2774654c(‘teL) esp 何をしている? • “Let’s start the CTF:”という文字列をスタックに積む(リトルエンディアン) 9
コラム: バイトオーダ リトルエンディアン • データの下位から1Byteずつメモリの 下位へ格納 10 ビッグエンディアン • データの上位から1Byteずつメモリの
下位へ格納 図は2つともhttp://www.ertl.jp/~takayuki/readings/info/no05.htmlより引用
start アセンブリを追う 8048082 push $0x2774654c 8048087 mov %esp, %ecx 8048089
mov $014, %dl 804808b mov $0x1, %bl 804808d mov $0x4, %al 804808f int $0x80 old_esp 0x804809d <_exit> 0x3a465443 (:FTC) 0x20656874([ws]eht) 0x20747261 ([ws]tra) 0x74732073 (ts[ws]s) 0x2774654c(‘teL) esp 11 int $0x80 • eaxに指定されたシステムコール番号に対応するシステムコールを発行 • システムコール番号→cat /usr/include/asm/unistd_32.h (今回は32bitなので) • 引数はどう渡すの?→この場合はbl, cl, dlと汎用レジスタに順に格納すればよい
start アセンブリを追う 8048082 push $0x2774654c 8048087 mov %esp, %ecx 8048089
mov $014, %dl 804808b mov $0x1, %bl 804808d mov $0x4, %al 804808f int $0x80 old_esp 0x804809d <_exit> 0x3a465443 (:FTC) 0x20656874([ws]eht) 0x20747261 ([ws]tra) 0x74732073 (ts[ws]s) 0x2774654c(‘teL) esp 12 何をしている? • 命令はwrite(1, esp, 20)と解釈できる • espから20Byte読み出す→”Let`s start the CTF:”と標準出力される 20Byte
start アセンブリを追う 804808f int $0x80 8048091 xor %ebx, %ebx 8048093
mov $0x3c, %dl 8048095 mov $0x3, %al 8048097 int $0x80 old_esp 0x804809d <_exit> 0x3a465443 (:FTC) 0x20656874([ws]eht) 0x20747261 ([ws]tra) 0x74732073 (ts[ws]s) 0x2774654c(‘teL) esp 13 60Byte 何をしている? • 命令はread(0, esp, 60)と解釈できる • 標準入力から受け取った文字列をespか ら60Byteまで書き込む
start アセンブリを追う 8048097 int $0x80 8048099 add $0x14, %esp 804809c
ret old_esp 0x804809d <_exit> 0x3a465443 (:FTC) 0x20656874([ws]eht) 0x20747261 ([ws]tra) 0x74732073 (ts[ws]s) 0x2774654c(‘teL) esp 14 何をしている? • スタックポインタを20Byte上げて ,ret命令を発行 • _exitセクションに処理が移る だがしかし • 先程のread命令が発行された際に 20Byte以上のデータが書き込まれてい れば,_exitセクションのアドレスが書 き換えられる. esp 60Byte
start アセンブリを追う 8048097 int $0x80 8048099 add $0x14, %esp 804809c
ret old_esp 0x804809d <_exit> 0x3a465443 (:FTC) 0x20656874([ws]eht) 0x20747261 ([ws]tra) 0x74732073 (ts[ws]s) 0x2774654c(‘teL) esp 15 何をしている? • スタックポインタを20Byte上げて ,ret命令を発行 • _exitセクションに処理が移る だがしかし • 先程のread命令が発行された際に 20Byte以上のデータが書き込まれてい れば,_exitセクションのアドレスが書 き換えられる. esp 60Byte esp
start ペイロードの作成 (1) readシステムコール発行 • |----適当な値20Byte----|----リターンしたいアドレス----| • 上記のようなデータを送信することで特定のアドレスに処理を移させられる ワンステップでShellcodeを実行させることはできない •
ASLR有効 &&スタックの上部の空間を使う→old_espの値をリークさせる必 要がある • 1回目のret実行後のesp→old_espを指している && このバイナリはespから 20Byteのデータをwriteシステムコールを発行し標準出力している→もう一 度この処理を呼び出せば出力の先頭4Byteにold_espが含まれる! • これを実現するために,0x8048087にリターンさせる 16
start ペイロードの作成 (2) 前ページの処理の実装 17 Pwntools • 有名なCTFチームがPwnableを解く際 に使ってるライブラリ •
pwntoolsのほうが好きなんだけど ,socketについてちゃんと知ってほ しい感じがあるので今回は使用しない
start ペイロードの作成 (3) Shellcodeの注入 • 処理が進んでいくと,再びreadシステ ムコールを発行する • | ----適当な値20Byte----
| ---- old_esp + 20 ---- | ---- Shellcode ---- | のようなデータを送信すること でShellcodeが実行される 18 old_esp 0x804809d <_exit> esp esp old_esp + 20 esp | old_esp + 20 Shellcode old_esp
start ペイロードの作成 (4) 前ページの処理の実装 • Shellが起動していることを確認できる • Shellcodeはragg2 -i exec
-b 32 で作成 • 19
start ペイロードの作成 (5) せっかくだしフラッグも取っていこう • 先程起動したShellでfind / -iname “*flag*”を実行 •
~/flagを確認できる 20
コラム: shellcodeとバリデーション対策 NULL文字排除 • Shellcode→文字列(char *)として与えられる→0x00を含むことができない • mov eax, 1
→ NULLバイトを含む • xor eax, eax inc eax→NULLバイトを含まない Unicode / 英数字のみShellcode • 上で示したような自己書き換えコードを用いて実現可能 21
参考文献 • https://blog.ohgaki.net/modern-shellcode-and-secure-defensive-progr amming (2019/10/08 参照) • http://www.ertl.jp/~takayuki/readings/info/no05.html (2019/10/08 参
照) • https://ja.wikipedia.org/wiki/%E3%82%B7%E3%82%A7%E3%83%AB% E3%82%B3%E3%83%BC%E3%83%89#%E7%AC%A6%E5%8F%B7%E5% 8C%96%E6%96%B9%E6%B3%95 (2019/10/08 参照) • http://web.archive.org/web/20150308214411/https://www.eecis.ude l.edu/~bmiller/cis459/2007s/readings/buff-overflow.html (2019/10/08 参照) 22