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
74
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
55
RIG#2-3
sfcrig
0
100
RIG#1-2
sfcrig
0
230
Other Decks in Technology
See All in Technology
Enhancing SaaS Product Reliability and Release Velocity through Optimized Testing Approach
ropqa
1
250
SREのためのeBPF活用ステップアップガイド
egmc
2
900
[ JAWS-UG千葉支部 x 彩の国埼玉支部 ]ムダ遣い卒業!FinOpsで始めるAWSコスト最適化の第一歩
sh_fk2
2
150
敢えて生成AIを使わないマネジメント業務
kzkmaeda
2
510
CDK Vibe Coding Fes
tomoki10
1
530
インフラ寄りSREの生存戦略
sansantech
PRO
9
3.4k
60以上のプロダクトを持つ組織における開発者体験向上への取り組み - チームAPIとBackstageで構築する組織の可視化基盤 - / sre next 2025 Efforts to Improve Developer Experience in an Organization with Over 60 Products
vtryo
3
980
CDKコード品質UP!ナイスな自作コンストラクタを作るための便利インターフェース
harukasakihara
2
200
助けて! XからWaylandに移行しないと新しいGNOMEが使えなくなっちゃう 2025-07-12
nobutomurata
2
140
スタックチャン家庭用アシスタントへの道
kanekoh
0
110
Operating Operator
shhnjk
1
650
サイバーエージェントグループのSRE10年の歩みとAI時代の生存戦略
shotatsuge
4
830
Featured
See All Featured
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
8
830
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
281
13k
Making the Leap to Tech Lead
cromwellryan
134
9.4k
The World Runs on Bad Software
bkeepers
PRO
69
11k
Practical Orchestrator
shlominoach
189
11k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
30
2.1k
Fireside Chat
paigeccino
37
3.5k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
34
3.1k
Raft: Consensus for Rubyists
vanstee
140
7k
Optimising Largest Contentful Paint
csswizardry
37
3.3k
Designing for Performance
lara
610
69k
Art, The Web, and Tiny UX
lynnandtonic
299
21k
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