본문 바로가기
정보보안

정보보안3 2차시

by 뭔가해보겠습니다 2024. 6. 2.

64dbg 프로그램에서 main() 함수 찾기
=> 프로그램 내 문자열로 찾기

 

A 버튼 누르면 이런 창이 뜬다

해당 문자열을 더블클릭하면 그 위치로 이동할 수 있다

 

컴파일러에 따라 main의 위치는 달라진다

 

short jmp 
- 8비트 부호 있는 오프셋을 사용하여 현재 위치에서 상대적 이동시 사용
- 앞으로, 뒤로 이동 가능

 

EB 08을 04 02 이런식으로 수정하면 jmp 주소값이 바뀐다

 

한 칸 아래로 가서 mov eax~ 에 걸림
뒤로 가도록 변경하면 FA 가 되는데 F는 음수를 의미한다

 

계산기에서 FD는 -3을 의미

NOP 명령어만 있는 주소는 1바이트
명령어가 있는 00401501 주소는 89E5로 두 바이트를 차지하고 있다
때문에 NOP 명령어만 있을때는 FD FC FB 이렇게 한바이트씩 올리면 올라가지만
명령어가 있는 주소는 F6 F7 둘 다 00401501 주소를 가리키고 있다

 

test는 and 연산

jne같은 조건부 점프 명령어를 무조건 점프 jmp로 변경하면 인증을 우회할 수 있다

 

strcmp 함수

NAME
       strcmp, strncmp - compare two strings
SYNOPSIS
       #include <string.h>
       int strcmp(const char *s1, const char *s2);
       int strncmp(const char *s1, const char *s2, size_t n);

RETURN VALUE
       The strcmp() and strncmp() functions return an integer less than, equal
       to, or greater than zero if s1 (or the first n bytes thereof) is found,
       respectively, to be less than, to match, or be greater than s2.

=> 두 개의 값을 비교하는 함수. 리턴값의 경우 같으면 0을 반환한다 (s1이 더 크면 양수, 작으면 음수)

 

리눅스에서도 strcmp 결과를 if문으로 비교시 test 명령어가 사용된다

 

0x080484e3 <+6>:     movl   $0x6c6c6548,-0x6(%ebp)
0x080484ea <+13>:    movw   $0x6f,-0x2(%ebp)
=> l l e H

=> o

4바이트로 Hello 라는 문자열을 다 담을 수 없어 끊어서 저장된 것

(gdb) x/4xw $esp

0xffffd43c:     0xf7fbc000      0x65480000      0x006f6c6c      0x00000000

( 6f 의 경우 나머지 자리는 0 으로 채워진다 006f )

 

lea    -0xc(%ebp),%eax

=> lea : 주소를 저장하는 명령어

 

(gdb) ni

1: $esp = (void *) 0xffffd43c

(gdb) i r eax
eax            0xffffd43c 

=> %ebp -12 위치의 주소(esp)를 eax에 저장했다.

 

(gdb) x/4xw $esp
0xffffd43c:     0x6c6c6548      0x6548006f      0x006f6c6c      0x00000000

=> Hello 문자열을 한 번 더 저장할 때, 이렇게 나누어져 저장되고 있다

 

$ebp = (void *) 0xffffd448

                                       443 442 441 440                                            448

0xffffd43c:     0x6c6c6548      0x6548006f      0x006f6c6c      0x00000000

               43f 43e 43d 43c                      447 446 445 444

=> 계산해보면 딱 맞아 떨어진다

 

 

코드 : if(strcmp(s1, s2) == 0) {

(gdb) ni

x/4xw $esp
0xffffd434:     0xffffd442      0xffffd43c      0x6c6c6548      0x6548006f

(gdb)  i r eax
eax            0xffffd442

=> s2, s1 두 인수의 주소( 0xffffd442 0xffffd43c )가 스택에 들어갔다

 

(gdb) p &s2
$4 = (char (*)[6]) 0xffffd43c
(gdb) p &s1
$5 = (char (*)[6]) 0xffffd442

=> 확인

 

call   0x8048370 <strcmp@plt>

(gdb) i r eax
eax            0x0                 0

=> strcmp의 결과값이 eax 레지스터에 전달되었음 (0)

 

test   %eax,%eax

=> test는 bit and(&)연산을 하고 결과를 저장하지 않으며 플래그 레지스터만 설정한다

and 연산 결과가 0값이라면 ZF 플래그에 1이 설정된다 그 외에는 clear (초기화) 됨

 

(gdb) i r eflags
eflags         0x246               [ PF ZF IF ]

 

왜 test로 %eax, %eax를 하는가 궁금했는데 %eax에는 strcmp의 결과값이 저장된다.

and 연산이므로 값이 그대로 나온다

strcmp는 결과값이 다르면 1 또는 -1이 나오므로

and 연산을 했을 때도 1 또는 -1이 나와 ZF 플래그가 설정되지 않는 것

굳이 이런식으로 우회하여 비교하는 이유는 나중에 알게 되겠지 ...

 

bit or (|)연산 : 두 비트 중 하나라도 1일 때 결과 비트가 1이 된다

 

 

int i = 7;

int *p = &i;

p는 주소값, *를 붙이면 주소에 들어있는 값을 출력한다

 

gdb로 어셈블리어 목록을 보면, lea 명령어가 사용되고 있다

 

Load Effective Address. LEA 명령어는 주로 포인터(메모리 주소)에서 사용한다

 

소스코드 : p = &i;

명령어 : lea    -0x8(%ebp),%eax

=> ebp 레지스터로부터 -8 위치의 주소값을 eax 레지스터에 복사한다

 

(gdb) x/4xw $ebp -8
0xffffd440:     0x00000007      0x08048370      0x00000000      0xf7e34f36

(gdb) i r eax
eax            0xffffd440          -11200

=> $ebp -8위치는 0xffffd440 이고 eax에 저장되었다

(gdb) p /x &i
$1 = 0xffffd440

=> p 프린트를 통해서도 위치를 확인해볼 수 있다

 

mov는 해당 위치의 을 집어넣고

lea는 해당 위치의 메모리 주소값을 집어넣는다

 

 

소스코드 : printf("i: %d, &i: %p\n", i, &i);

이 중 &i에 해당하는 명령어 : lea    -0x8(%ebp),%edx

 

소스코드 : printf("p: %p, *p: %d\n", p, *p);

이 때도 포인터 변수를 출력하니 lea를 사용할 것 같지만,

이미 포인터 변수에 메모리 주소값이 들어 있기 때문에 주소를 또 저장할 필요가 없다

mov로 변수값을 복사하면 된다

 

어셈블리어

mov    -0x4(%ebp),%eax               => eax 값은 0xffffd440
mov    (%eax),%eax                      => eax 값은 0x7

=> ebp-4 위치는 포인터변수 p의 위치이다. p의 위치에는 i의 주소값이 들어있다.

이를 eax에 복사한 후, eax의 값을 다시 eax에 복사하면 i의 주소값에 들어있는 value 값을 복사하게 된다

 

+

(gdb) x/b 0xffffd440
0xffffd440:     0x07

=> 440에는 i의 값인 7이 들어있다

 

 

'정보보안' 카테고리의 다른 글

정보보안3 4차시  (0) 2024.06.09
정보보안3 3차시  (0) 2024.06.08
정보보안3 1차시  (0) 2024.06.01
정보보안2 8차시  (0) 2024.05.26
정보보안2 7차시  (0) 2024.05.25