본문 바로가기

시스템

시스템 2주

x64 어셈블리 언어는 동사에 해당하는 명령어(Operation Code, Opcode)와 목적어에 해당하는 피연산자(Operand)로 구성됩니다.

명령어들을 크게 분류하면 이렇습니다. 

 

피연산자에는 3가지 종류가 올 수 있습니다. 상수, 레지스터, 메모리입니다. 

메모리 피연산자는 []으로 둘러싸인 것으로 표현됩니다. 앞에 크기 지정자인 TYPE PTR이 추가될 수 있습니다. 타입에는 BYTE, WORD, DWORD, QWORD가 올 수 있으며 각각 1, 2, 4, 8바이트의 크기를 지정합니다. 

 

데이터 이동 명령어는 어떤 값을 레지스터나 메모리에 옮기도록 지시한다.

 

mov dst, src에 들어있는 값을 dst에 대입

mov rdi, rsi rsi의 값을 rdi에 대입
mov QWORD PTR[rdi], rsi rsi의 값을 rdi가 가리키는 주소에 대입
mov QWORD PTR[rdi+8*rcx], rsi rsi의 값을 rdi+8*rcx가 가리키는 주소에 대입

 

lea dst, src : src의 유효 주소(Effective Address, EA)를 dst에 저장

lea rsi,[rbx+8*rcx] rbx+8*rcx를 rsi에 대

 

산술 연산

산술 연산 명령어는 덧셉,뺄샘,곱셈,나눗셈 연산을 지시한다. 

 

add dst, src: dst에 src의 값을 더한다.

add eax, 3 eax += 3
add ax, WORD PTR[rdi] ax += *(WORD*) rdi

 

sub dst, src : dst에서 src의 값을 뺀다

sub eax, 3 eax -= 3
sub ax, WORD PTR[rdi] ax -= *(WORD *)rdi

 

inc op:op의 값을 1 증가시킴

inc eax eax += 1

 

dec op:op의 값을 1 감소시킨다

dec eax eax -= 1

 

논리 연산 명령어는 and, or, xor, neg등의 비트 연산을 지시한다.

and dst, src dst와 src의 비트가 모두 1이면 1, 아니면 0
or dst, src dst와 src의 비트 중 하나라도 1이면 1, 아니면 0
xor dst, srcd dst와 src의 비트가 서로 다르면 1,같으면 0
not op op의 비트 전부 반

 

비교 명령어는 두 피연산자의 값을 비교하고, 플래그를 설정한다.  

cmp op1, op2:op1과 op2를 비교한다. cmp는 두 피연산자를 빼서 대소비교를 하며 연산 결과는 op1에 대입하지 않는다. 

 

test op: op2:op1과 op2를 비교한다. test는 두 피연산자에서 AND비트연산을 취한다. 연산의 결과는 op1에 대입하지 않는다. 

 

분기 명령어는 rip를 이동시켜 실행 흐름을 바꾼다. 

jmp addr addr로 rip를 이동시킨다
je addr 직전에 비교한 두 피연산자가 같으면 점프한다
jd addr 직전에 비교한 두 연산자 중 전자가 더 크면 점프

 

push val: val을 스택 최상단에 쌓는다. 

pop reg:스택 최상단의 값을 꺼내서 reg에 대입한다.

 

Opcode:프로시저

 

특정 기능을 수행하는 코드 조각을 말합니다. 프로시저를 사용하면 반복되는 연산을 프로시저 호출로 대체할 수 있어서 전체 코드의 크기를 줄일 수 있으며, 기능별로 코드 조각에 이름을 붙일 수 있게 되어 코드의 가독성을 크게 높일 수 있습니다

 

프로시저를 부르는 행위:호출(call)

"                  돌아오는 것:반환(return)

프로시저를 호출할 때는 프로시저를 실행하고 나서 원래의 실행 흐름으로 돌아와야 한다. call 다음 명령어의 주소(return address, 반환 주소)를 스택에 저장하고 프로시저로 rip를 이동시킨다.

 

call addr:addr에 위치한 프로시져 호출한다.

 

Opcode: 시스템 콜

해킹으로부터 막강한 권한을 보호하기 위해 커널 모드와 유저 모드로 권한을 나눈다.

 

커널 모드: 운영체제가 전체 시스템을 제어하기 위해 시스템 소프트웨어에 부여하는 권한이다.

유저 모드:  운영체제가 사용자에게 부여하는 권한이다. 유튜브를 시청하는 것, 게임을 하고 프로그래밍을 하는 것 등은 모두 유저 모드에서 이루어진다.

시스템 콜: 유저 모드에서 커널 모드의 시스템 소프트웨어에게 어떤 동작을 요청하기 위해 사용된다. 소프트웨어 대부분은 커널의 도움이 필요하다. 

 


 

Q1. 레지스터, 메모리 및 코드가 다음과 같다. Code를 1까지 실행했을 때, rax에 저장된 값은?

 

A. 0x4oaa40+8을 한 0xC0FFEE이다.(로드)

 

Q2. Code를 2까지 실행했을 때, rax에 들어있는 값은?

 

A. 0x4oaa40+8(저장)

 

 

Q3. 레지스터, 메모리 및 코드가 다음과 같다. Code를 1까지 실행했을 때, rax에 저장된 값은?

 

rbx + rcx*8 = 0x555555554000 + 0x2*8 = 0x555555554000 + 0x10 = 0x555555554010

0x555555554010의 메모리값은 0x0000000000000003

rax에 더할 시:ax3133A

 

Q4.  Code를 3까지 실행했을 때, rax에 저장된 값은?

rbx + rcx*8와 rax가 같으므로 0이 된다. 

 

Q5. Code를 4까지 실행했을 때, rax에 저장된 값은?

 

0에서 1을 증가시켰으므로 1이 된다.

 

 

Q6. 레지스터, 메모리 및 코드가 다음과 같다. Code를 1까지 실행했을 때, rax에 저장된 값은?

 

rax와 rcx를 각각 이진수로 바꿔서 계산합니다. 0x1234567800000000가 나옴을 알 수 있습니다.

 

Q7. Code를 2까지 실행했을 때, rbx에 저장된 값은?

 

각각 이진수로 바꿔서 계산합니다. 0x000000009ABCDEF0가 나옴을 알 수 있습니다.

 

Q8. Code를 3까지 실행했을 때, rax에 저장된 값은?

 
각각 이진수로 바꿔서 계산합니다. 0x120056789abcdef0가 나옴을 알 수 있습니다.  
 

 

Q9. 레지스터, 메모리 및 코드가 다음과 같다. Code를 1까지 실행했을 때, rax에 저장된 값은?

 

각각 이진수로 변환하여 계산해줍니다. 0xEBACFBAE 가 나옴을 알 수 있습니다.

 

Q10. Code를 2까지 실행했을 때, rax에 저장된 값은?

 

각각 이진수로 변환하여 계산해줍니다. 0x35014541가 나옴을 알 수 있습니다.

 

Q11. Code를 3까지 실행했을 때, rax에 저장된 값은?

 

이진수로 변환합니다. 0xCAFEBABE가 나옴을 알 수  있습니다.

 

답:Welcome to assembly world!

 


gdb

설치가 된 것을 확인합니다. 

 

entry

 실행파일의 형식으로 ELF (Executable and Linkable Format)를 규정한다. ELF는 크게 헤더 와 여러 섹션 들로 구성되어 있다. 

 

Context

실행 상황을 이와 같이 부른다. 크게 REGISTERS, DISASM, STACK, BACKTRACE으로 나뉜다.

 

REGISTERS: 레지스터의 상태를 보여줍니다

DISASM: rip부터 여러 줄에 걸쳐 디스어셈블된 결과를 보여줍니다

STACK: rsp부터 여러 줄에 걸쳐 스택의 값들을 보여줍니다

BACKTRACE: 현재 rip에 도달할 때까지 어떤 함수들이 중첩되어 호출됐는지 보여줍니다.

 

break & continue

 

break는 특정 주소에 중단점(breakpoint)을 설정하는 기능이고, continue는 중단된 프로그램을 계속 실행시키는 기능입니다. 

 

run

 

단순히 실행만 시킵니다.

 

navigate

관찰하고자 하는 함수의 중단점에 도달했으면, 그 지점부터는 명령어를 한 줄씩 자세히 분석해야 한다. 이때 사용하는 명령어로 ni si가 있다

 

step into

필요한 부분으로 들어가 분석할 때 사용합니다.

 

finish

함수의 규모가 커서 ni로는 원래 실행 흐름으로 돌아가기 어려울 수 있습니다. 이럴 때는 finish라는 명령어를 사용하여 함수의 끝까지 한 번에 실행할 수 있습니다.

 

pwntools

설치를 완료합니다

process 익스플로잇을 로컬 바이너를 대상으로 함
remote 원격 서버를 대상으로 함
send 데이터를 프로세스에 전
recv 프로세스에서 데이터를 받
packing & unpacking 어떤 값을 리틀 엔디언의 바이트 배열로 변경하거나 역의 과정
interactive 셸을 획득했거나 익스플로잇의 특정 상황에 입력을 주며 출력 확
ELF 익스플로잇에서 사용될 수 있는 각종 정보 기
context.log 익스플로잇에 버그가 발생하면 익스플로잇도 디버깅한다
context.arch 셸코드를 생성하거나, 코드를 어셈블, 디스어셈블하는 기능 등을 가지며, 이들은 공격 대상의 아키텍처에 영향을 받습니다
shellcraft  공격에 필요한 셸 코드를 쉽게 꺼내 쓸 수 있게 해준다.
asm 어셈블 기능을 제공한다.

'시스템' 카테고리의 다른 글

7주차 시스템  (0) 2024.08.19
5주차_시스템  (0) 2024.08.07
4주차_시스템  (0) 2024.07.29
3주차_시스템  (1) 2024.07.22
시스템 1주  (0) 2024.07.07