해커스쿨 F.T.Z에서도 해봤던 Shell Code 실습이지만 조금 다른 실습을 한다.
지금까지 사용해오던 셸 코드가 있다.
\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80
위 셸 코드에서 "0x2f"를 없애려고 한다. 해커스쿨 L.O.B level 7에서 배운 argv[0] 즉, 파일 이름에 셸 코드를 넣어야 할 때가 있다.
파일 이름에 "0x2f" 즉, "/"이 문자가 들어있으면 경로로 인식되어 셸 코드가 제대로 작동되지 않으므로 보통의 셸 코드를 사용할 수 없다.
기존 사용하던 셸 코드의 어셈블리 언어다.
컴파일하고 실행하면 셸이 실행되는 것을 볼 수 있다.
objdump로 기계어를 보면 항상 사용하던 셸 코드가 있는 것을 알 수 있다.
위 셸 코드에서 "/"인 "0x2f"를 없애는 것도 맞지만 정확하게 말해선 "0x2f"를 다른 방법으로써 불러온다고 하는 게 맞는 것 같다.
"0x68732f2f"에서 "0x68732e2e"로 바꾸어 사용한다. 이때 두 수의 차이는 101이 차이가 난다. 이 차를 더해 줌으로써 "0x68732f2f"를 불러온다.
밑에 있는 "0x6e69622f"도 마찬가지로 "0x6e69622e"로 바꾸어 준다. 이때 두 수의 차이는 1이다. 이 차를 더해 준다.
기본 방식을 알았으니 어셈블리 코드로 구현한다.
위 설명과 같이 "0x2f"를 "0x2e"로 대체하고 차이를 더해서 "0x2f"를 불러오는 어셈블리 코드가 작성되었다.
컴파일 후 실행하면 셸이 실행되는 것을 볼 수 있다.
셸이 실행됐으니 셸 코드를 알아내기 위해 objdump로 열어봐야 한다.
방금 만든 어셈블리 코드를 열면 기계어 중간에 NULL byte인 "0x00"이 보인다.
알다시피 NULL byte 문자열의 끝을 의미하기 때문에 이 NULL byte를 없애주어야 한다.
여기서 NULL byte가 생성되는 것은 esi에 add 할 때 "0x101"을 더해 주어서 생기는 것인데 그 이유는 "0x101" 같은 작은 값을 더하기 때문에 명령어의 길이를 맞추기 위해 NULL byte가 추가되는 것이다.
그러므로 자릿값에 맞추어 "0x68732f2f"의 상위 비트들도 빼주어 명령어의 길이를 맞춰야 한다.
"0x68732f2f"에서 "0x67722e2e"를 빼면 "0x1010101"이고 "0x101"의 명령어 길이를 맞추기 위해 "0x1010101"로 바꿔서 작성한다.
"0x68732f2f"에서 "0x67722e2e" 바꾸고 "0x1010101"을 더해줬다.
실행하면 셸이 잘 나온다.
셸이 잘 나오니 objdump로 기계어를 살펴본다.
기계어 코드를 보면 NULL byte가 있던 자리에 "0x01"로 채워지면서 NULL byte가 사라진 것을 볼 수 있다.
셸 코드를 작성한다.
\x31\xc0\x50\xbe\x2e\x2e\x72\x67\x81\xc6\x01\x01\x01\x01\x56\xbf\x2e\x62\x69\x6e\x47\x57\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80
"0x2f"가 없는 셸 코드가 완성되었다.
특수한 상황에서도 사용할 수 있는 커스텀 셸 코드 제작을 할 수 있도록 어셈블리 언어의 능력을 키워야 한다.
'System Hacking > 해커스쿨 L.O.B' 카테고리의 다른 글
해커스쿨 L.O.B 로컬서버 구축 (0) | 2020.05.15 |
---|
댓글