소프트웨어 버그 헌팅 - 2 (어셈블리 기초 및 실습)
할때마다 까먹는 어셈블리
Remind
힙영역은 메모리 내에서 아래서 위로 쌓인다.
스택영역은 메모리 내에서 위에서 아래로 쌓인다.
(툴따라 스택을 아래에서 위로 표현하기도 하기때문에 헷갈리지 말 것)
함수 호출하고 돌아하는 프로세스는 중요하니까 한번 더 생각해볼 것
(프롤로그, 에필로그)
함수 호출 규약으로는 cdecl, stdcall, fastcall 3가지가 존재하며,
cdecl은 x86 환경에서 대부분 C 컴파일러가 쓰는 규약
stdcall은 MS가 자체적으로 만든 호출 규약, 작고 빠른 프로그램에 용이
fastcall은 함수에 전달하는 파라미터 일부를 스택 메모리가 아닌 레지스터로 전달
PUSH: 스택에 데이터 삽입, 자동으로 ESP를 4바이트 감소
POP : 스택에서 4바이트를 꺼내와 지정한 레지스터에 삽입, 자동으로 ESP 4바이트 증가
MOV : 복사, 레지스터 -> 레지스터, 메모리 <-> 레지스터, Immediate 값 -> 레지스터 or 메모리
LEA : 복사(Load Effective Address), 레지스터 연산 결과를 레지스터에 저장(not 포인터)
- MOV는 값을 로드하고(mov eax, [ebp+esp+4])
- LEA는 유효 주소를 로드한다 - lea eax, [ebp+esp+4]
CMP : 두 값을 비교하고 플래그 값만 바꾼다.
TEST : 논리 비교, test eax, eax(eax 값이 0 인경우 ZF=1), 보통 jcc랑 같이 쓰임
JNE : Jump not equal(ZF=0)
JE : Jump Equal(ZF=1)
JLE : Jump Less Equal(ZF=1 or SF<>OF)
CALL : 우선 다음 실행할 명령어 주소를 스택에 삽입한 뒤, EIP에 해당 주소를 옮긴 뒤 이동하는 방식
외부함수를 사용할 때 반드시 해당 함수가 포함된 라이브러리를 liner에 함께 전달해야 함
칼리 리눅스에서 gdb를 이용하여 간단하게 어셈블리를 만들고, 실습 진행
소프트웨어 버그 헌팅 - 1에 쓴 칼리사용할 예정이며, 실행시키고 네트워크 설정을 NAT로 변경
GDB가 가벼워서 범용적으로 사용가능하나 가독성이 썩 좋지 않음. 그래서 페다를 사용할 것
[gdb 설치]
sudo apt-get update
sudo apt-get install gdb
[peda로 바꾸기]
git clone https://github.com/longld/peda.git ~/peda
echo "source ~/peda/peda.py" >> ~/.gdbinit
[nasm 설치]
sudo apt-get install nasm
[컴파일]
nasm -f elf [코드작성파일명] && ld -m elf_i386 -o [결과파일명] [파일명.o] --entry main
nasm -f elf push && ld -m elf_i386 -o push.b push.o --entry main
GDB 명령어
disas main : 메인 코드 보기
b* main : main에 BP(브레이크 포인트)
r : 실행
disas : 현재 코드 보기
ni : 다음 명령어 실행하기
c : 실행된 상태에서 지행
ex) b* main으로 BP1 잡고 B*main+20으로 Bp2 잡고 r 누르면 BP1가는데 거기서 C 누르면 C2까지감
mov 코드
global main
section .text
main:
push 10h
push 0x1234
mov ebx, esp
mov eax, dword [ebx]
mov dword [esp], 0x5678
위 코드대로 저장하고, 컴파일 이후 GDB [결과파일명] 으로 불러온다.
이후 b* main으로 BP를 잡아주고 r 한다.
main+2 - 현재 ESP에서 0x10를 넣고 ESP-4 바이트한다.
main+7 - 현재 ESP에서 0x1234를 넣고 ESP-4 바이트한다.
main+9 - EBX에 있는 값을 eax에 넣는다.
main+11 - 5678을 ESP에 넣는다.
add 코드
global main
section .text
main:
mov eax, esp
sub esp, 8
mov [eax], dword 5
mov [eax+4], dword 3
sub [eax+4], dword 1
add [eax+4], dword 2
add esp, 8
main - ESP의 값을 EAX에 넣는다.
main+2 - ESP에서 8을 뺸다( 지역함수 크기 할당)
main+5 - 5를 eax에 넣는다.
main+11 - 3을 eax+4로 간다
main+18 -1을 뺀다
main+22 - EAX에 있는 값에 2를 더한다
main+26 - ESP에 +8 하여 다시 할당한 것을 회수한다(데이터는 남아있을걸?)
JMP 코드
global main
section .text
main:
mov ecx, 0
mov eax, ecx
inc ecx
cmp ecx, 255
jne 0x8049007
ret
main - ecx의 값을 0으로 만듬
main+5 - ecx의 값을 eax 넣음
main+7 - ecx의 값을 1 증가
main+8 - ecx와 0xff를 비교(같으면 ZF=1)
main+14 - ZF의 값이 1이면 넘어가고 0이면 main+7로 점프
'Reversing' 카테고리의 다른 글
소프트웨어 버그 헌팅 - 3 (IDA 스크립트 활용한 findkey 문제 풀이) (0) | 2019.12.07 |
---|---|
소프트웨어 버그 헌팅 - 2.1 (OllyDBG, IDA) (0) | 2019.12.07 |
소프트웨어 버그 헌팅 - 1 (취약점 개요 및 메타스플로잇) (0) | 2019.12.07 |
시스템 내에서 일어나는 여러 행위들을 기록하는 툴 Sysmon (1) | 2017.08.23 |
운영보안할 때 도와주는 툴 PC Hunter, SystemExplorer (0) | 2017.08.23 |
최근댓글