[ LOB wolfman ]
id : wolfman
pw : love eyuna
- 코드분석 -
인자는 main 함수를 통해 전달받는다.
크기 40의 버퍼가 char형식으로 선언되었고, 변수 i가 int형식으로 선언되었다. 따라서 선언된 변수의 총 바이트 수는 44 바이트이다.
main함수의 인자전달에서
argc[A] = 인자 개수가 A 개 임을 의미
argv[0] = 실행파일의 이름
argv[1] = 첫번째 인자 ( 공백으로 구분 )
argv[2] = 두번째 인자 ( 공백으로 구분 ) 으로 나누어진다.
첫번째 if문에서는 인자가 두개 미만일때 ( 인자 전달이 아예 없을때 ) 프로그램을 종료시킨다. ( argc는 인자갯수를 의미 )
첫번째 for문은 모든 환경변수의 내용을 0으로 바꾸는 코드이다. 이 코드로 인헤 EGG SHELL이나 EXPORT를 이용하여 쉘코드를 환경변수에 올려놓고 공격하는 방법이 막힌 셈이다.
두번째 if문에서는 첫번째인자의 48번째 원소가 "\xbf" 인지 확인한다. 리틀엔디안방식으로 페이로드를 작성한다면, ret주소의 마지막 바이트인 48byte 째에는 무조건 "\xbf"것이므로 별 상관 없을듯 하다.
세번째 if문은 첫번째인자의 길이가 48이하인지 확인한다. 이건 argv 뒷부분에 쉘코드를 집어넣는 방식을 차단한것으로 보이는데, argv[1] 뒷부분에 쉘코드를 삽입하는 방식은 전레벨인 orc 에 포스팅하겠다.
신경써야할 부분은 마지막 에 새로추가된 buffer hunter다. 버퍼의 내용을 0으로 초기화시키는데, 우리는 지금까지 버퍼에 shell code를 넣어서 페이로드를 작성했으므로 지금까지 공격한 방법을 사용할 수 없다.
strcpy함수가 진행된 후에 브레이크포인트를 걸어서 esp레지스터의 내용을 확인해보았다. 버퍼 40만큼을 0으로 만들어 0xbffffacc 뒤쪽 소수의 부분에만 내용이 남아있다. ( A 7개, 조건을 만족시키기위해 넣어둔 \xbf 한개 )
- 공격 방법 -
자, 그렇다면 우리는 어떤 공격방법을 사용해야할까?
지금까지 우리는 argv[1] 영역만 공격에 이용했다. 하지만, 이번 공격에는 argv[2] 영역을 이용해보려고 한다. argv에 대한 설명은 위에있으니 다시 확인해보길 바란다.
일단 스택의 구조를 생각해보자
- 가장높은주소 -
:
:
:
argv 2 -- 공격에 이용할 부분
argv 1
argv 0
:
:
:
ret 4byte
sfp 4byte
int i 4byte
char buffer 40byte
- 가장낮은주소 -
지금까지 우리는 buffer에 nop+쉘코드를 입력하고 ret에 버퍼의 주소를 입력하여 쉘코드가 실행되도록 했다.
하지만 이번에는 ret에 argv의 시작주소를 입력하고, argv에 nop+쉘코드를 입력하여 쉘코드가 실행되도록 해볼것이다.
일단 스택이 구성된 후에 브레이크 포인트를 걸어서 A가 20개 들어간 argv[2]를 찾아보자.
하얀색 41부터가 두번째 인자이다.
공격 코드를 짜서 공격해보자.
coredump가 일어났다. core파일을 확인해보자.
core 파일을 보니 nop이 들어가는 메모리주소가 공격코드와는 달랐다. 이를 참고로 다시 페이로드를 작성해보자.
쉘이 성공적으로 뜬걸 볼수있다.
참고로 이건 tmp 디렉토리에 있는 darkelf 파일이다. 따라서 setuid가 제대로 걸려있는 wolfman 디렉토리에 가서 공격을 동일한 방법으로 실행하면, 다음레벨로 가는 패스워드를 알수있을것이다.
'System Hacking ( pwnable ) > hackerschool LOB Write-up' 카테고리의 다른 글
[LOB] level7 - darkelf( write - up ) (0) | 2019.03.24 |
---|---|
[LOB] level1 - gate ( write - up ) (0) | 2019.03.22 |