Presentation is loading. Please wait.

Presentation is loading. Please wait.

어셈블리.

Similar presentations


Presentation on theme: "어셈블리."— Presentation transcript:

1 어셈블리

2 어셈블리 구조 어셈블리는 다음과 같이 다섯 영역으로 구성된다.
레이블(Label), 명령(OP-code), 인수 1(Operand 1), 인수 2(Operand 2), 주석(comment) 레이블 직접적인 수행과는 관계가 없으며 jmp, call 을 통해서 참조할때 사용된다. C 언어의 goto 문장에서 사용하는 레이블(레이블명:)과 같이 사용된다. 명령 기종에 따라 약간의 차이가 있다. 인수 인수에 따라 명령어 구사가 달라진다. movb $0x1, %eax  1바이트 데이터를 eax 레지스터에 저장한다. movw $0x1, %eax  2바이트(word) 데이터를 eax 레지스터에 저장한다. movl $0x1, %eax  4바이트(long) 데이터를 eax 레지스터에 저장한다. 실습 포인트 어셈블리 기초 명령어

3 어셈블리 구조(실습 포인트) eax 에 4 바이트 형의 1 을 저장하라. eax 에 들어있는 값에 1을 더하라.
label_123 위치로 분기하라. 서브루틴(sub1) 을 호출하라. 서브루틴에서 원래의 위치로 복귀하라. 시스템콜을 위한 인터럽트를 발생시켜라. eax 에 ‘esi+8’ 의 주소를 저장하라. ebp 값을 스택에 저장하라. 스택에 저장된 값을 꺼내어 esi 에 저장하라.

4 어셈블리 구조(문제 풀이) eax 에 4 바이트 형의 1 을 저장하라. mov1 $0x1, %eax
addl $0x1, %eax eax 에 들어있는 값에서 1을 빼라. subl $0x1, %eax eax 의 값에서 1을 증가시켜라. incl %eax eax 의 값에서 1을 감소시켜라. decl %eax label_123 위치로 분기하라. jump label_123 서브루틴(sub1) 을 호출하라. call sub1 서브루틴에서 원래의 위치로 복귀하라. ret 시스템콜을 위한 인터럽트를 발생시켜라. int $0x80 eax 에 ‘esi+8’ 의 주소를 저장하라. leal 0x8(%esi), %eax ebp 값을 스택에 저장하라. push %ebp 스택에 저장된 값을 꺼내어 esi 에 저장하라. pop %esi

5 어셈블리 - 인텔계열과 AT&T 계열 비교 Register naming
인텔 : ecx AT&T : %ecx Source, Destination Ordering 인텔 계열은 오른쪽에서 왼쪽으로 대입되고 AT&T 계열을 반대로 왼쪽에서 오른쪽으로 대입된다. 인텔 : mov ecx, ebx AT&T : movl %ebx, %ecx Operation size specification 레지스터의 크기는 정해주는 것이 좋다(b, w, l). 인텔 : mov cx, bx AT&T : movw %bx, %cx Constant value/immediate vale format AT&T 계열은 value 앞에 ‘$’ 가 붙는다. 인텔 : mov ebx, _hack AT&T : movl $_hack, %ebx

6 어셈블리 - 인텔계열과 AT&T 계열 비교 Referencing memory 32 비트 주소를 어드레싱
인텔 : [base + index * scale + immediate32] AT&T : immediate_value(32){base, index, scale} 특정 포인터를 어드레싱 인텔 : [ebx] AT&T : (%eax) C 언어 변수를 어드레싱 인텔 : [_hack] AT&T : _hack 오프셋 어드레싱 인텔 : [ebx +1] AT&T : 1(%ebx) 실습 포인트 해킹개념 상시 유지용 문제

7 해킹개념 상시 유지용 문제 - Brutus Attack(실습 포인트)
(추후 변동가능 있음) 를 대상으로 FTP 서버공격으로 ID/PW 를 획득하라. 아이디/비밀번호를 획득한 후에 숨겨져 있던 쉐도우 파일을 크랙하라. 힌트 크랙용 사전이 생성되는 시간 관계상 여기서 제공되는 DIC 생성기의 범위는 부터 으로 제한한다.

8 해킹개념 상시 유지용 문제 - Brutus Attack(문제 풀이)
(추후 변동가능 있음) 를 대상으로 FTP 서버공격으로 ID/PW 를 획득하기. FTP 크랙 프로그램 다운로드 위치 Dic Generator(사전 생성기) 다운로드 위치 샘플용으로 생성된 사전 다운로드 위치 위의 결과로 나온 아이디와 비밀번호를 이용하여 FTP 클라이언트을 이용하여 쉐도우을 빼낸다. 아이디/비밀번호를 획득한 후에 숨겨져 있던 쉐도우 파일을 크랙하기. 쉐도우(shadow) 파일 크랙용 크래커 다운로드 위치

9 어셈블리 - 메모리 1바이트(byte)가 메모리의 기본단위이다.
2바이트(word), 4바이트(double word), 8바이트(quad word), 16바이트(paragraph) 메모리의 데이터는 숫자로 구성되어 있음. ASCII 는 하나의 문자를 코딩하기 위해 1바이트를 사용. Unicode 는 하나의 문자를 코딩하기 위해 2바이트를 사용.

10 어셈블리 – segment:offset 16비트 BUS 의 한계를 극복하기 위해 20 비트 BUS를 사용하기 위해 고안.
physical address = segment x 10h + offset 31337:12345 의 물리적 주소 = 31337 x 10h 325715

11 어셈블리 - 기초 명령어 Jump if Above Ascii Adjust for Addition
어셈블리 - 기초 명령어 Jump if Above JA : 비교 결과가 크면 점프 JAE : 크거나 같으면 점프 Jump if Below JB : 비교 결과가 작으면 점프 JGE : 크거나 같으면 점프 JMP : 조건없이 점프 JLE : 작거나 같으면 점프 Jump if Not Greater or Equal JNGE : 결과가 작으면 점프 MOV : 오퍼랜드에 값을 이동시킴 MUL : 곱하기 NOP : 3 사이클 동안 작동안함 POP : 스택에서 꺼냄 PUSH : 스택에 넣음 SUB : 나누기 XCHG : 두 오퍼랜드의 값을 서로 바꿈 Ascii Adjust for Addition AAA : 덧셈후 10진 보정 AAD : 나누기전에 10진 보정 AAM : 곱한후 10진 보정 AAS : 뺄셈후 10진 보정 ADC : 더할때 carry 도 포함 ADD : 오른쪽에 왼쪽으로 더하기 CALL : 서브루틴을 호출 CBW : 바이트를 워드로 저장 CLD : 방향 플래그를 클리어 CLI : 인터럽트 플래그를 클리어 CMP : 오퍼랜드 비교하기 Decimal Adjust for Addition DAA : 덧셈후 AL 레지스터에 보정 DEC : 오퍼랜드 값에서 1을 뺌 DIVIDE : 나눗셈을 수행 IMUL : 곱셈을 수행 INC : 오퍼랜드 값을 1 증가시킴 INT : 인터럽트를 호출 실습 포인트 기초 명령어 사용법

12 어셈블리 - 기초 명령어(실습 포인트) EAX 레지스터에서 00ch 에 해당하는 값을 빼라.
어셈블리 - 기초 명령어(실습 포인트) EAX 레지스터에서 00ch 에 해당하는 값을 빼라. EBX 레지스터의 값이 h 일때 h 주소로 점프하라. 서브루틴 h 를 호출하라.

13 어셈블리 - 기초 명령어(문제 풀이) EAX 레지스터에서 00ch 에 해당하는 값을 빼는 법. SUB EAX, 00ch
어셈블리 - 기초 명령어(문제 풀이) EAX 레지스터에서 00ch 에 해당하는 값을 빼는 법. SUB EAX, 00ch EBX 레지스터의 값이 h 일때 h 주소로 점프하라. CMP EBX, h JZ h 서브루틴 h 를 호출하라. CALL h 실습 포인트 기초 명령어 사용법 AT&T 방식

14 어셈블리 - 기초 명령어(실습 포인트) EAX 레지스터에서 00ch 에 해당하는 값을 AT&T 어셈블리 방식을 이용하여 빼라.

15 어셈블리 - 기초 명령어(문제 풀이) EAX 레지스터에서 00ch 에 해당하는 값을 AT&T 어셈블리 방식을 이용하여 빼는 법. SUB $0x00ch, %EAX

16 어셈블리 - 레지스터 레지스터란 무엇인가 ? 레지스터는 수학적인 연산이 가능하다. 레지스터는 CPU 내에 내장되어 있다.
어셈블리 - 레지스터 레지스터란 무엇인가 ? 레지스터는 수학적인 연산이 가능하다. 레지스터는 CPU 내에 내장되어 있다. 메모리는 읽고 쓰기는 가능하지만 연산은 불가능하다. 메모리의 느린 처리능력을 레지스터가 보강해 준다. 레지스터의 종류 일반 레지스터(General Purpose Register) 포인터 레지스터(Pointer Register) 스택 레지스터(Stack Register) 플래그 레지스터(Flag Register) 세그먼트 레지스터(Segment Register)

17 어셈블리 - 일반 레지스터 1 eax 32비트중 오른쪽 16비트 = AX[왼쪽 상위 AH(8비트)+오른쪽 하위 AL(8비트)]
어셈블리 - 일반 레지스터 1 eax 32비트중 오른쪽 16비트 = AX[왼쪽 상위 AH(8비트)+오른쪽 하위 AL(8비트)] 입출력과 산술연산에 사용 곱셈, 나눗셈, 변환 명령어 ebx 32비트중 오른쪽 16비트 = BX[왼쪽 상위 BH(8비트)+오른쪽 하위 BL(8비트)] 베이스 레지스터 주소지정용 인덱스로 사용 계산에 사용 특정주소 지정때 DI 나 SI 와 함께 사용 ecx 32비트중 오른쪽 16비트 = CX[왼쪽 상위 CH(8비트)+오른쪽 하위 CL(8비트)] 카운터 레지스터 루프횟수를 제어 32 비트 16 비트

18 어셈블리 - 일반 레지스터 2 edx 32비트중 오른쪽 16비트 = DX[왼쪽 상위 DH(8비트)+오른쪽 하위 DL(8비트)]
어셈블리 - 일반 레지스터 2 edx 32비트중 오른쪽 16비트 = DX[왼쪽 상위 DH(8비트)+오른쪽 하위 DL(8비트)] 데이터 레지스터 일부 연산에서 반드시 edx 를 사용해야 한다. 큰수의 곱셈과 나눗셈 연산 si 16비트 원시 인덱스 레지스터 (source index register) 문자 연산에 사용 DS 와 함께 사용 ESI(80386 의 32비트 확장 레지스터) di 16비트 목적지 인덱스 레지스터 (destination index register) ES 와 함께 사용 EDI(80386 의 32비트 확장 레지스터) 32 비트 16 비트

19 어셈블리 - 세그먼트 레지스터 CS(Code Segment) 코드를 저장 DS(Data Segment) 테이터를 저장
어셈블리 - 세그먼트 레지스터 CS(Code Segment) 코드를 저장 DS(Data Segment) 테이터를 저장 EX(Extra Segment) 스트리밍을 저장 SS(Stack Segment) 리턴어드레스를 저장

20 어셈블리 - 인덱스 레지스터 SI(Source Index) 문자열, 배열의 소스 인덱스를 저장.
어셈블리 - 인덱스 레지스터 SI(Source Index) 문자열, 배열의 소스 인덱스를 저장. DI(Destination Index) 문자열, 배열의 목적지 인덱스를 저장. IP(Instruction Pointer) 차후 실행될 명령어의 주소를 저장.

21 어셈블리 - 스택 레지스터 BP(Base Pointer) 상위주소를 가리킴. SP(Stack Pointer)
어셈블리 - 스택 레지스터 BP(Base Pointer) 상위주소를 가리킴. SP(Stack Pointer) 하위 주소를 가리킴. 실습 포인트 스택 관련 명령어 사용법

22 어셈블리 - 스택 레지스터 (실습 포인트) 다음의 문제는 AT&T 어셈블리 방식을 적용하여 푼다.
어셈블리 - 스택 레지스터 (실습 포인트) 다음의 문제는 AT&T 어셈블리 방식을 적용하여 푼다. 베이스 포인터(Base Pointer) 의 값을 스택에 저장하라. 스택 포인터(Stack Pointer) BP 에 넣어 스택을 초기화 시켜라.

23 어셈블리 - 스택 레지스터 (문제 풀이) 다음의 문제는 AT&T 어셈블리 방식을 적용하여 푼다.
어셈블리 - 스택 레지스터 (문제 풀이) 다음의 문제는 AT&T 어셈블리 방식을 적용하여 푼다. 베이스 포인터(Base Pointer) 의 값을 스택에 저장하기. push %ebp 스택 포인터(Stack Pointer) BP 에 넣어 스택을 초기화 시켜라. movl %esp, %ebp

24 어셈블리 - 기초 명령어 사용법 Jump if Above Ascii Adjust for Addition
어셈블리 - 기초 명령어 사용법 실습 포인트 어셈블리 명령어 사용법 응용편 Jump if Above JA : 비교 결과가 크면 점프 JAE : 크거나 같으면 점프 Jump if Below JB : 비교 결과가 작으면 점프 JGE : 크거나 같으면 점프 JMP : 조건없이 점프 JLE : 작거나 같으면 점프 Jump if Not Greater or Equal JNGE : 결과가 작으면 점프 MOV : 오퍼랜드에 값을 이동시킴 MUL : 곱하기 NOP : 3 사이클 동안 작동안함 POP : 스택에서 꺼냄 PUSH : 스택에 넣음 SUB : 나누기 XCHG : 두 오퍼랜드의 값을 서로 바꿈 Ascii Adjust for Addition AAA : 덧셈후 10진 보정 AAD : 나누기전에 10진 보정 AAM : 곱한후 10진 보정 AAS : 뺄셈후 10진 보정 ADC : 더할때 carry 도 포함 ADD : 오른쪽에 왼쪽으로 더하기 CALL : 서브루틴을 호출 CBW : 바이트를 워드로 저장 CLD : 방향 플래그를 클리어 CLI : 인터럽트 플래그를 클리어 CMP : 오퍼랜드 비교하기 Decimal Adjust for Addition DAA : 덧셈후 AL 레지스터에 보정 DEC : 오퍼랜드 값에서 1을 뺌 DIVIDE : 나눗셈을 수행 IMUL : 곱셈을 수행 INC : 오퍼랜드 값을 1 증가시킴 INT : 인터럽트를 호출

25 어셈블리 - 기초 명령어 사용법 1(실습 포인트)
어셈블리 - 기초 명령어 사용법 1(실습 포인트) ax 의값을 36h 으로 설정하여라. ax 의 값은 bx 주소값으로 대체하여라. dx 의 값을 36h 으로 설정하여라. dx 의 값을 증가 시켜라. dx 의 값을 감소 시켜라.

26 어셈블리 - 기초 명령어 사용법 2(문제 풀이) ax 의값을 36h 으로 설정하기. mov ax, 36h
어셈블리 - 기초 명령어 사용법 2(문제 풀이) ax 의값을 36h 으로 설정하기. mov ax, 36h ax 의 값은 bx 주소값으로 대체하기. mov ax, bx dx 의 값을 36h 으로 설정하기. mov dx, 50h dx 의 값을 증가 시키기. inc dx <--- 37h(dx++) dx 의 값을 감소 시키기. dec dx <--- 35h(dx--)

27 어셈블리 - 기초 명령어 사용법 2(실습 포인트)
어셈블리 - 기초 명령어 사용법 2(실습 포인트) ax 의값을 36h 으로 설정하여라. ax 의 값은 bx 주소값으로 대체하여라. dx 의 값을 36h 으로 설정하여라. dx 의 값을 증가 시켜라. dx 의 값을 감소 시켜라.

28 어셈블리 - 기초 명령어 사용법 2(문제 풀이) ax 의값을 36h 으로 설정하기. mov ax, 36h
어셈블리 - 기초 명령어 사용법 2(문제 풀이) ax 의값을 36h 으로 설정하기. mov ax, 36h ax 의 값은 bx 주소값으로 대체하기. mov ax, bx dx 의 값을 36h 으로 설정하기. mov dx, 50h dx 의 값을 증가 시키기. inc dx <--- 37h(dx++) dx 의 값을 감소 시키기. dec dx <--- 35h(dx--)

29 어셈블리 - 기초 명령어 사용법 3 나중에 사용하기 위한 용도로 ax 에 임시로 값을 저장하라.
어셈블리 - 기초 명령어 사용법 3 나중에 사용하기 위한 용도로 ax 에 임시로 값을 저장하라. push ax <-- 16비트 레지스터만 가능함. 다음의 예제에서 최종 ax 와 bx 의 값을 구하라. mov ax, 36h <-- ax = 36h mov bx, 2fh <-- bx = 2fh xchg ax, bx <-- ax = 2fh, bx = 36h push ax <-- ax 의 값을 저장. mov ax, 21h <-- ax 의 값에 21h 를 대신 저장. pop bx <-- bx 의 원래값인 2fh 를 회복시킴. push bx <-- bx 의 값(2fh)를 저장. pop ax <-- ax 의 새로운 값인 21h 에서 원래값인 2fn 을 회복시킴. 실습 포인트 어셈블리 명령어 사용법 응용편

30 어셈블리 - 기초 명령어 사용법 3(실습 포인트)
어셈블리 - 기초 명령어 사용법 3(실습 포인트) 다음의 dx 의 값과 ax 의 값을 교환하라. mov dx, 36h mov ax, 2fh 참고 xchg 사용시 8비트(h/l) 레지스터와 16비트(x) 레지스터는 절대 교환해서는 안된다. xchg ah, bx <--- 8비트, 16비트가 같이 혼용 되어서는 안된다.

31 쉘코드 만들기(문제 풀이) 문자열을 넣고 주소를 계산한다. 계산된 문자열의 주소를 가리키는 주소를 레지스터에 넣는다.

32 쉘코드 만들기 쉘 실행코드란 무엇인가 ? 쉘을 실행하는 기능을 가진 짧은 코드를 의미한다. 쉘코드로 변환되어 사용된다.
실습 포인트 쉘실행 코드 만들기 쉘 실행코드란 무엇인가 ? 쉘을 실행하는 기능을 가진 짧은 코드를 의미한다. 쉘코드로 변환되어 사용된다. execve(시스템 콜 번호 11) 와 setreuid(시스템 콜 번호 70) 의 함수가 필수적이다. execve() 콜은 /bin/sh 를 실행시킬때 사용된다. setreuid()콜은 suid root 프로그램에 보안상 설정된 일반사용자 권한을 루트권한으로 바꾸어 준다. 쉘코드에서 이 권한을 복구하지 않으면 루트쉘이 아닌 일반쉘이 뜨기 때문에 반드시 복구해야 한다. 쉘코드의 모습

33 쉘코드 만들기(실습 포인트) 쉘 실행코드를 제작한 후 어셈블과 링크과정을 거친 후 실행여부를 테스트 하라.

34 쉘코드 만들기(문제 풀이) 문자열을 넣고 주소를 계산한다. 계산된 문자열의 주소를 가리키는 주소를 레지스터에 넣는다.

35 쉘코드 만들기(문제 풀이) mov [ebx + 7], al 분석하기
al 에 들어있는 내용을 ebx +7 레지스터 주소에 저장하라는 명령이다. 32 비트 eax 레지스터 대신에 8비트 al 레지스터를 사용하여 eax 의 처음 1바이트 만을 사용하고 있다. eax 의 처음 1 바이트를 문자열의 7번째 주소로 복사한다. ebx 에는 문자열 “/bin/shXAAAABBBB”에 대한 주소가 들어있다. 7번째 위치

36 쉘코드 만들기(문제 풀이) mov [ebx + 8], ebx 분석 mov [ebx + 12], eax 분석
32 비트(4바이트) 레지스터 하나를 통째로 사용하여 “AAAA” “BBBB” 부분에 값을 복사한다. “AAAA” 부분인 ebx + 8 에는 문자열의 주소(ebx)가 저장된다. “BBBB” 부분인 ebx + 12 에는 널주소인 0(eax) 이 저장된다.

37 쉘코드 만들기(문제 풀이) lea ecx, [ebx + 8]
문자열의 “AAAA” 부분에 해당되는 주소를 ecx 에 넣는다. lea edx, [ebx + 12] 문자열의 “BBBB” 부분에 해당되는 주소를 edx 에 넣는다. 참고 : 주소값을 담고 있는 메모리의 주소값을 저장하는 이중법을 쓰는 이유는 execve() 함수가 마지막 2개의 인자를 받아들일때 포인터의 포인터 값으로 받아들이기 때문이다. 다시 말하면 인자의 값은 주소값을 담고 있느 메모리의 주소값이 되어야 한다.

38 쉘코드 만들기(문제 풀이) 어셈블과 링크과정을 거친 후 실행하기. $ nasm -f elf shell.asm
$ ld shell.o $ ./a.out 실습 포인트 루트 장악용 쉘실행 코드 만들기

39 쉘코드 만들기(실습 포인트) shell.asm 으로 생성된 a.out 를 루트 장악용 쉘실행코드로 변환하라.

40 쉘코드 만들기(문제 풀이) shell.asm 으로 생성된 a.out 를 루트 장악용 쉘실행코드로 변환하기.
# chown root a.out # chmod +s a.out # exit $ ./a.out

41 쉘코드 만들기 - 단일 세그먼트에서 처리하기 shell.asm 은 아직은 미완성된 쉘코드라고 볼 수 있다.
쉘코드는 단독으로 작동할 수 없으며 공격대상 프로그램내에 삽입되어야 그 기능이 작동된다. 데이터 세그먼트에 들어있는 문자열을 명령코드 쪽에 저장하고 그 주소를 찾아내는 것이 관건이다. 문자열 주소는 명령어가 들어있는 주소와 같은 곳에 존재한다. 쉘코드 실행시의 정확한 메모리주소를 알 수 없기 때문에 EIP 를 참조하여 찾아내야 한다. jmp 와 call 은 EIP 와 특정한 규칙관계를 가지고 있는 점을 이용한다. jmp 와 call 은 EIP 를 메모리의 특정한 곳으로 이동하도록 지시하는 기능을 가지고 있다. 프로그램 시작 > call 명령과 문자열이 있는 코드의 끝으로 jump > call 명령 실행 > 문자열 주소가 스택에 삽입 > call 명령은 맨처음의 jump 명령 바로 다음위치로 제어를 이동 > 프로그램은 문자열 주소를 스택에서 꺼낸뒤 쉘코드를 실행

42 쉘코드 만들기 - 단일 세그먼트에서 처리하기 프로그램 실행후 two 로 jump > 리턴주소(문자열 주소)를 스택에 삽입 > one 으로 이동 > 스택에서 문자열 주소를 꺼냄 > EBX 에 저장 > 쉘코드 실행 jmp two one : pop ebx [프로그램 코드부분] two : call one db ‘예제에 사용되는 문자열’ 다음 페이지에서 위의 알고리즘을 처리하는 코드를 제공하니 참고하시기 바란다.

43 쉘코드 만들기 - 단일 세그먼트에서 처리하기 shellcode_1.asm

44 쉘코드 만들기 - 널바이트 없애기 개선된 코드 ‘shellcode_1.asm’을 헥사 편집기를 이용하여 분석한다.
$ nasm shellcode_1.asm $ hexedit shellcode1 ’00’ 으로 되어 있는 부분이 널바이트 이다. 문자열의 끝으로 인식하기 때문에 첫 2바이트만 버퍼에 복사한다. 쉘코드 모두를 버퍼로 복사하기 위해서는 모든 널바이트를 제거해야 한다.

45 쉘코드 만들기 - 널바이트 없애기 ‘0’ 이라는 값을 사용하지 않고 레지스터에 ‘0’을 저장하기 위해서는 임의의 32 비트 값을 레지스터로 불러온 다음에 다시 그 값을 레지스터에 빼는 방법을 사용한다. 이 방법은 용량이 늘어나기 때문에 쉘코드가 커진다는 단점을 가지고 있다. 쉘코드는 실행의 특성상 되도록이면 용량을 작게 만드는 것이 좋은 방법이다. mov ebx, 0x sub ebx, 0x

46 쉘코드 만들기 - 널바이트 없애기 레지스터와 그 레지스터 본인을 XOR 연산하게 되면 값이 ‘0’ 이 되기 때문에 널바이트 제거의 한 방법이 된다. OR 연산 0 OR 0 = 0 0 OR 1 = 1 1 OR 0 = 1 1 OR 1 = 1 XOR 연산 0 XOR 0 = 0 0 XOR 1 = 1 1 XOR 0 = 1 1 XOR 1 = 0 OR 연산과 XOR 연산의 차이점

47 쉘코드 만들기 - 단일 세그먼트에서 처리하기 shellcode_2.asm

48 쉘코드 만들기 - 널바이트 없애기 개선된 코드 ‘shellcode_2.asm’을 헥사 편집기를 이용하여 분석한다.
$ nasm shellcode_2.asm $ hexedit shellcode2 shellcode.1.asm 보다 널바이트가 줄어든 것을 확인할 수 있다.

49 쉘코드 만들기 - 널바이트 없애기 어셈블된 기계어를 비교해 보면 다음과 같이 분석된다.
mov eax, 70 = B 복사될 ’70’ 은 1바이트인데 32비트(4바이트) 레지스터의 특성상 3개의 널바이트가 생성된다. EAX 의 8비트 레지스터인 AL 을 사용하여 널바이트를 제거할 수 있다. 0xB8 0x shellcode.1.asm 보다 널바이트가 줄어든 것을 확인할 수 있다.

50 쉘코드 만들기 - 널바이트 없애기 다음과 같이 EAX 대신 AL 을 사용하여 널바이트를 제거한다.
mov al, 70 ; = B0 46 위 같은 방식에서는 처음 1바이트만이 ‘0’으로 바뀌고 나머지는 바뀌지 않기 때문에 다음과 같이 레지스터 전체를 ‘0’으로 바꾸고 난후 다음 1바이트를 AL 로 복사하면 된다. xor eax, eax ; 반드시 다음 명령을 위해 eax 를 0 으로 설정해야만 한다. mov al, 70 ;

51 쉘코드 만들기 - 널바이트 없애기 Shellcode.asm

52 쉘코드 만들기 - 널바이트 없애기 다시 개선된 코드 ‘shellcode.asm’을 헥사 편집기를 이용하여 분석한다.
$ nasm shellcode.asm $ hexedit shellcode 널바이트 모두 제거된 것을 확인할 수 있다. 쉘코드의 크기도 줄어든 것을 확인할 수 있다.

53 쉘코드 만들기 - 널바이트 없애기 XAAAABBBB 의 목적은 널바이트와 2개의 주소에 대한 메모리 할당을 위해서 입력되었다.
쉘코드를 단독 개별 프로그램으로 제작했을 때는 위의 인자가 필요하다. 쉘코드가 다른 프로그램이 만든 메모리에 삽입될때는 위의 인자가 필요없다. 그렇기 때문에 ‘XAAAABBBB ‘ 를 제거하여 쉘코드의 크기를 줄일 수 있다.

54 쉘코드 만들기 - 널바이트 없애기 최종적인 코드 ‘shellcode.최종.asm’을 헥사 편집기를 이용하여 분석한다.
$ nasm shellcode.최종.asm $ hexedit shellcode.최종 코드의 크기가 더욱 줄어든 것을 확인할 수 있다.

55 쉘코드 만들기 - 바이트 코드 만들기 바이트 코드란 다음과 같은 형태를 가진 코드를 의미한다.
쉘코드란 다음과 같은 형태를 가진 코드를 의미한다.

56 쉘코드 만들기 - 바이트 코드 만들기 바이트 코드를 제작하기 위한 도구로써 다음과 같은 것들이 사용된다. gcc nasm ld
objdump ndisasm

57 쉘코드 만들기 - 바이트 코드 만들기 완성된 쉘코드용 asm 소스를 이용하여 바이트 코드와 쉘코드 제작하기
바이트 코드란 무엇인가 ? 널바이트와 문자열을 제거하여 크기가 축소된 산뜻한 asm 코드를 만든 후에는 최종적으로 바이트 코드를 제작하는 단계로 들어간다. 즉 여러분들이 자주 보던 공격코드(exploits) 에 들어 있는 다음과 같이 생긴 것들을 일컬어 바이트 코드라고 부르는 것이다. 바이트 코드의 모습

58 쉘코드 만들기 - 바이트 코드 만들기 그렇다면 쉘코드는 또 무엇인가 ?
쉘코드는 바이트 코드를 프로그램 내에 삽입하여 실행 가능하게 만든 완전한 형태의 코드를 뜻한다. 즉, 바이트 코드를 실행하려면 조금 더 마무리 작업을 해주어야 하겠지요 ? 그렇지 않고 저기 보이는 저런 발가벗은 형태의 바이트 코드가 혼자서는 제 역할을 해낼 수가 없지요 ? 이것을 다음과 같이 완전한 형태로 만들어 준 것을 쉘코드라고 합니다. 즉 프로그램내에 삽입되어 제 구실을 하게끔 프로그래밍 문법을 적용시킨 것이라고 보시면 됩니다. 그림을 보시면 ‘\x69\x6e……” 되어 있는 바이트 코드 앞에 ‘char hellc0de….어쩌구..저쩌구’ 와 같은 코드를 추가해준 것입니다. 쉘코드의 모습

59 쉘코드 만들기 - 바이트 코드 만들기 바이트 코드를 만들기 위한 준비물 gcc nasm ld objdump ndisasm

60 쉘코드 만들기 - 바이트 코드 만들기 바이트 코드 삽입 후 실행 유무 테스트용 본체

61 쉘코드 만들기 - 바이트 코드 만들기 exit.asm 코드를 바이트 코드로 만들기 소스코드 ;exit.asm
[SECTION .text] global _start _start: xor eax, eax ;exit is syscall 1 mov al, ;exit is syscall 1 xor ebx,ebx ;zero out ebx int 0x80

62 쉘코드 만들기 - 바이트 코드 만들기 명령어 사용법 nasm -f elf exit.asm ld -o exiter exit.o
objdump -d exiter 결과물

63 쉘코드 만들기 - 바이트 코드 만들기 결과물에서 산출한 바이트 코드 b0 01 31 db cd 80
산출된 바이트 코드를 쉘코드 형태로 변환하기 char shellcode[] = "\xb0\x01\x31\xdb\xcd\x80"; 프로그램 본체에 삽입된 쉘코드의 완전한 모습

64 쉘코드 만들기 - 바이트 코드 만들기 hello.asm 을 바이트 코드로 만들고 출력하기 소스코드 ;hello.asm
[SECTION .text] global _start _start: jmp short ender starter: xor eax, eax ;clean up the registers xor ebx, ebx xor edx, edx xor ecx, ecx mov al, ;syscall write mov bl, ;stdout is 1 pop ecx ;get the address of the string from the stack mov dl, ;length of the string int 0x80 xor eax, eax mov al, ;exit the shellcode xor ebx,ebx ender: call starter ;put the address of the string on the stack db 'hello'

65 어셈블리 - 기초 명령어 사용법 3(문제 풀이) 다음의 dx 의 값과 ax 의 값을 교환하는 법. mov dx, 36h
어셈블리 - 기초 명령어 사용법 3(문제 풀이) 다음의 dx 의 값과 ax 의 값을 교환하는 법. mov dx, 36h mov ax, 2fh xchg dx, ax


Download ppt "어셈블리."

Similar presentations


Ads by Google