일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- vinetto
- CTF-D
- Multimedia
- 2022시작
- slack space
- 네트워크관리사2급
- 는 하지마...
- Multimeida
- Window process
- 24시간의 전사
- blkls
- 디지털포렌식
- ftz
- 윈도우 프로세스 종류
- N0Named
- 디지털포렌식 with CTF
- 생활코딩 html
- memory
- 포렌식
- 정보처리기사 필기 합격
- pythonchallenge
- 네트워크 보안
- disk
- 생활코딩
- 슬퍼유
- 윈도우 프로세스
- network
- html
- ZIP 파일구조
- 실기
- Today
- Total
ssoL2 TISTORY
[FTZ] LEVEL 18 풀이 본문
attackme가 존재하고 hint로 코드를 살펴봅시다.
굉장히 긴 코드 등장. 역대급 코드 인정? (그래서 원래 가운데 정렬하는데 이번에는 왼쪽 정렬한다..쓸게 많아,,)
코드를 읽어보면서 중요한 것들만 골라내면 다음과 같다.
1. count >=100이면 "뭐하는거냐?" 문구 출력
2. check == 0xdeadbeef이면 shellout() 실행 => shell권한 획득 !! **중요
3. read 함수로 stdin 입력 받은 것을 1 byte씩 x에 저장
3-1. x가 '\r', '\n'이면 "\a" 출력
3-2. x가 0x08이면 count 1 빼고, "\b \b" 출력
3-3. 위 두 경우가 아니라면 string[count]에 변수 x값을 넣고, count 1 더한다.
결론적으로 다음 쉘을 얻기 위해서는 check을 0xdeadbeef로 덮어줘야한다.
-> 덮어주려면? 현재 string 배열로 bof 일으켜서 덮을 수도 없는 상황(check이 string 이후에 선언돼서 더 낮은 주소에 있을 것)
-> bof를 할 수 없다.
-> 그러면 위에 적어 놓은 3번을 이용해서 check을 0xdeadbeef로 덮어야한다.
-> 직접적으로 변화를 일으키는건 3-3인데, string[count]에 stdin 입력한 것을 1바이트씩 옮기고 count++
-> 그러면 3-2로 int count=0으로 되어있는 count를 1씩 빼고, 3-3으로 string[음수]를 통해 string 보다 낮은 주소에 있는(뒤에 선언된) check에 접근을 하고 0xdeadbeef로 덮어주면 된다.
높은 주소(high) string->check->x->count 낮은주소(low)이렇게 되어있기 때문에 보통 bof하면 low->high 덮는건데, 이 문제에서는 string이 그럴수가 없으므로 string의 인덱스를 음수로 해서 check에 접근하겠다는 소리임
이제 string과 check이 실제로 얼마만큼 떨어져있는지 확인을 하고, count를 얼만큼 빼야하는지 계산해야한다.
gdb로 분석해볼때 ebp-104에 담겨있는 값이 0xdeadbeef랑 비교하는 것을 보면 [ebp-104]가 check 변수이다.
이제 string만 알아내면 된다.
string을 직접적으로 쓰는 곳은 3-3(switch default)인데, 인덱스로 count를 사용하니까 count 먼저 알아보자.
count는 100과 비교해서 print하는 부분이 있었는데, 어셈블리에서도 [ebp-112]가 0x63과 비교하는 것을 알 수 있다.
밑으로 내려가면 cmp랑 jump가 여러번 사용되는 것을 볼 수 있는데 이 부분이 switch 부분이다.
switch 뒷부분에 je 안되면 jmp로 main+499로 점프하는 것을 봐서 이부분이 default임을 알 수있다.
default 부분인 main+499에 오면 ebp-100을 언급하고, 이후 count인 ebp-112를 사용하는 것을 보면 string[count]에 대한 어셈블리임을 알 수 있다. 따라서 [ebp-100]이 string임을 알 수 있다.
결론적으로 check은 ebp-104에, string은 ebp-100에 위치함을 발견했다. check은 4 byte int형이므로 두 사이에 dummy가 없이 딱 붙어 있음을 알 수 있다. 이제, 두 사이에 아무것도 없음을 알아냈으므로 "0x08"을 4번 입력해서 count를 -4로 만들어 놓고, string[-4]부터 string[-1]까지 즉, check 4 byte(check[0]부터 check[4]까지)에 0xdeadbeef를 넣어서 권한을 획득하면 된다.
그것을 페이로드로 짜면 아래와 같다. 0xdeadbeef는 리틀 인디안으로 넣어줘야 한다. 또한, 인자 입력이 아닌 stdin 입력이므로 stdin payload를 작성한다. 그러면 쉘 권한 획득하여 pw를 얻을 수 있다.
'challenge > pwn' 카테고리의 다른 글
pwnable.kr [random] (0) | 2021.06.30 |
---|---|
pwnable.kr [passcode] (0) | 2021.06.29 |
[FTZ] LEVEL 17 풀이 (0) | 2021.02.23 |
[FTZ] LEVEL 16 풀이 (0) | 2021.02.01 |
[FTZ] LEVEL15 풀이 (0) | 2021.02.01 |