2017-09-06 4 views
0

셸 코드를 배우고 있습니다.셸 코드에서 문자열을 올바르게 디 어셈블리하십시오.

나는 튜토리얼이 쉘 코드를 발견 : 내가 원하는 무엇

python -c 'print "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80 "' > shellcode 

어떻게 작동하는지 이해하기 위해이 매우 기본적인 쉘 코드를 분해하는 것입니다. 여기

내가 무슨 짓입니다 :

$ objdump -D -b binary -m i8086 shellcode 

shellcode:  file format binary 


Disassembly of section .data: 

00000000 <.data>: 
    0: 90      nop 
    1: 90      nop 
    2: 90      nop 
    3: 90      nop 
    4: 90      nop 
    5: 90      nop 
    6: 90      nop 
    7: 90      nop 
    8: 90      nop 
    9: 31 c0     xor %ax,%ax 
    b: 50      push %ax 
    c: 68 2f 2f    push $0x2f2f 
    f: 73 68     jae 0x79 
    11: 68 2f 62    push $0x622f 
    14: 69 6e 89 e3 50   imul $0x50e3,-0x77(%bp),%bp 
    19: 53      push %bx 
    1a: 89 e1     mov %sp,%cx 
    1c: b0 0b     mov $0xb,%al 
    1e: cd 80     int $0x80 

또는 :

$ ndisasm shellcode 
00000000 90    nop 
00000001 90    nop 
00000002 90    nop 
00000003 90    nop 
00000004 90    nop 
00000005 90    nop 
00000006 90    nop 
00000007 90    nop 
00000008 90    nop 
00000009 31C0    xor ax,ax 
0000000B 50    push ax 
0000000C 682F2F   push word 0x2f2f 
0000000F 7368    jnc 0x79 
00000011 682F62   push word 0x622f 
00000014 696E89E350  imul bp,[bp-0x77],word 0x50e3 
00000019 53    push bx 
0000001A 89E1    mov cx,sp 
0000001C B00B    mov al,0xb 
0000001E CD80    int 0x80 

이 쉘 코드는 86 지침으로 해석 된 문자열이 포함되어 있습니다. 점프에 적절한 라벨을 부착 할 수있는 방법이 있습니까?

문자열에 x86 명령어를 디코딩하는 대신 문자열을 표시하는 방법이 있습니다. 섹션과 헤더가있는 엘프가 없기 때문에 이것이 쉬운 일이 아니라는 것을 알고 있습니다 ...

+0

음, 이것은 실제로 다른 모드를 언급하는 https://stackoverflow.com/questions/1737095/how-do-i-disassemble-raw-x86-code의 복제입니다 (예 : [이 답변에서 ] (https://stackoverflow.com/questions/1737095/how-do-i-disassemble-raw-x86-code/34424146#34424146).)하지만 우리는이 질문을 당신이 언제 잘못된 모드로 분해 중입니다 ... (아마도 그 중복이있을지라도 /) –

답변

0

, 당신은 @DavidJ이 제안, 지시로 데이터를 처리하는 동안 디스어셈블러가 동기화 가지고있는 경우 NOP를 가진 문자열을 교체해야 할 것입니다.

이 경우 그냥 잘못된 모드으로 분해 중입니다. jnc은 분명히 가짜입니다 (제 생각에 당신은 깨달았습니다). 즉 16 비트 모드가 작동하는 방법이기 때문에

디스어셈블러는 push imm16의 시작과 pushopcode합니다 (0x68 바이트)을 치료한다. 그러나 32 및 64 비트 모드에서 동일한 op 코드는 push imm32의 시작입니다. 따라서 push 명령은 실제로 3 대신 5 바이트이고 다음 명령은 실제로 다음 push입니다.

가짜 짧은 jnc이 아니고 16 비트 코드라는 큰 힌트입니다.


사용 ndisasm -b32 또는 -b64. Ndisasm은 stdin에서 입력을 읽을 수 있으므로 python2 -c 'print "... "' | ndisasm - -b32을 사용했습니다.

objdump을 사용하는 경우 Intel 구문을 선호하는 경우 objdump -d -Mintel을 사용하십시오.따라서 objdump -Mintel -bbinary -D -mi386 /tmp/shellcode은 32 비트 (-mi386은 ARM 또는 MIPS 등이 아닌 아키텍처로 x86을 선택하고, -Mi386 32 비트 모드도 포함 함)를 의미합니다.

또는 64 비트의 경우 objdump -D -b binary -mi386 -Mx86-64 /tmp/shellcode 작품. (objdump은 stdin에서 이진을 읽지 않습니다 : /) 옵션에 대한 자세한 내용은 objdump 매뉴얼 페이지를 확인하십시오.

일반적으로 ELF 실행 파일/개체를 분해하여 쉘 코드가 아닌 컴파일러가 무엇인지 확인하기 때문에이 별칭을 ~/.bashrc : alias disas='objdump -drwC -Mintel'에 사용합니다. 별칭에 -D이 필요할 수 있습니다.


64 비트 모드에서는 두 번의 누를 때마다 간격이 남기 때문에 32 비트 코드라고 확신합니다. 이 코드는 push imm64이 아니지만 push imm32은 64 비트 푸시이며 직접 부호 확장은 64 비트로 확장됩니다. 64 비트 모드에서는

push 'abcd' 
mov [rsp+4], 'efgh' 

"abcdefgh"에 RSP을 가리키는 결국 사용할 수 있습니다.

또한 스택 주소로 int 0x80을 사용하는 것이 64 비트 코드가 아닌 큰 단서입니다. int 0x80는 64 비트 모드로 리눅스에서 작동하지만 32 비트 모든 입력을 절단 : NDISASM에서 What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code?


32 비트 분해는 다음과 같습니다 제정신 보이는

00000000 90    nop 
00000001 90    nop 
00000002 90    nop 
00000003 90    nop 
00000004 90    nop 
00000005 90    nop 
00000006 90    nop 
00000007 90    nop 
00000008 90    nop 
00000009 31C0    xor eax,eax 
0000000B 50    push eax 
0000000C 682F2F7368  push dword 0x68732f2f 
00000011 682F62696E  push dword 0x6e69622f 
00000016 89E3    mov ebx,esp 
00000018 50    push eax 
00000019 53    push ebx 
0000001A 89E1    mov ecx,esp 
0000001C B00B    mov al,0xb 
0000001E CD80    int 0x80 
00000020 200A    and [edx],cl 

. 어떤 가지도 포함하고 있지 않지만,

점프에 적절한 라벨을 붙일 방법이 있습니까?

예, Agner Fog의 objconv 디스 어셈 블러는 분기 대상에 레이블을 붙여 어떤 분기가 어디로 갈지를 파악할 수 있습니다. 참조 How do I disassemble raw x86 code?

0

이것은 폰 노이만 아키텍처의 결과입니다. 코드와 데이터는 컴퓨터의 메모리에있는 숫자 일뿐입니다. 따라서 디스어셈블러는 (바이트 시퀀스에 대한 정보를 미리 알지 못하며) 코드 란 무엇이며 데이터는 무엇인지 알 수 없습니다. 의미는 수동으로해야합니다.

다행히도 쉽게 할 수 있습니다. 문자열 데이터를 nop (\ x90)으로 바꾸고 다시 해체하십시오. 그런 다음 nop 영역을 교체하여 문자열 데이터를 소스 코드에 다시 넣을 수 있습니다.

또한 분해 할 올바른 대상 CPU를 사용하고 있는지 확인하십시오. 나는이 쉘 코드가 16 비트 8086 CPU에서 작동하도록 의도 된 것은 아니라고 생각합니다. 일부 데이터를 통해 이동 call 또는 jmp을 사용하는 쉘 코드를 가지고 있다면

관련 문제