쉘 코드를 제작하는 방법을 요약하면 대략 아래와 같다.
1. C를 기반으로 코딩 후 컴파일
2. 생성된 실행파일을 디어셈블러로 확인
3. 주요 부분 발췌 후 어셈블리 코드 작성
4. objdump 명령어를 통해서 기계어 확인
5. Null 바이트 제거
중요한 부분은 기계어에 포함된 널 바이트를 제거하는 것과 주어진 공간에 잘 맞추는 것이 아닐까 싶다.
주저리 주저리 상세히 작성해보려 했지만 워낙 동일한 내용에 잘 되어있는 사이트들이 많아서 이정도만 작성한다.
일단 어셈블리어에 익숙한 사람들은 바로 어셈을 작성해도 큰 문제가 없을 것 같다.
나도 이번 기회에 처음 쉘코드를 작성해봤는데 위 1번과 2번은 크게 신경써지지 않았다.
내가 진행한 순서는 아래와 같다.
1. 내가 쉘코드로 실행하고자 하는 바를 간단히 코딩 (의사코드 형식)
2. syscall 테이블을 확인 (64비트)
3. 필요한 파라미터 확인 및 준비
4. Null 바이트 확인 및 제거
처음엔 나도 C 기반으로 코딩하고 확인하는 순서대로 진행해보았으나 오히려 남들이 작성해놓은 쉘코드를 한 두개 확인하고 내가 작성한 쉘코드의 문제점을 개선하는 쪽이 훨씬 직관적이고 빨랐다.
내가 참고한 사이트와 syscall 테이블, 쉘코드를 볼 수 있는 사이트들을 아래에 기록해놓았다.
References
[1] Writing 64-Bit Shellcode - Part 1 (Beginner Assembly),
https://null-byte.wonderhowto.com/how-to/writing-64-bit-shellcode-part-1-beginner-assembly-0161593/
[2] Writing 64-Bit Shellcode - Part 2 (Removing Null-Bytes),
https://null-byte.wonderhowto.com/how-to/writing-64-bit-shellcode-part-2-removing-null-bytes-0161591/
[3] Searchable Linux Syscall Table for x86 and x86_64, https://filippo.io/linux-syscall-table/
[4] shell-storm, http://shell-storm.org/