본문 바로가기

3. Pwnable (포너블)/2) 개념 정리

[2023.04.08] '생활코딩 - Linux' 강의 수강 및 달고나 문서 ~p.27

'생활 코딩 - Linux' 강의를 섹션 7부터 섹션 9까지 수강하고 달고나 문서 목차 4번 학습하였다.4


<섹션 7. 권한 (permission)> 

 

권한 

권한의 지정 의미: 어떤 사용자(User)가 파일과 디렉토리에 대해 어떠한 일을 할 수 있게/없게 하는 것

1. 파일의 종류 (-: 일반 파일, d: 디렉토리)

2. 파일을 읽고 쓰고 실행할 수 있는 권한 표시 

r : read / w : write / x : excute

rw-: owner의 권한 (읽기, 쓰기 권한만 가짐)

rw-: group의 권한 (읽기, 쓰기 권한만 가짐)

r-- other의 권한 (읽기 권한만 가짐)

3. 하드링크의 개수

4. 파일 소유자

5. 파일 소유자의 그룹 

6. 파일의 크기

7,8. 파일의 마지막 수정 날짜

9. 파일 이름

 

권한을 변경하는 방법

chmod o+r perm.txt : 이 시스템에 있는 모든 사용자가 perm.txt라는 파일을 읽을 수 있게 모드를 바꾸는 명령

chmod o+w perm.txt : 시스템에 있는 모든 사용자가 perm.txt라는 파일을 수정할 수 있게 모드를 바꾸는 명령

chmod u-r perm.txt : perm.txt라는 파일을 소유자가 읽을 수 없게 모드를 바꾸는 명령

 

실행의 개념과 권한 설정 - execute

실행권한 : 어떤 파일에 대해서 해당 파일을 실행가능한 파일로 할 것인지 실행가능하지 않은 파일로 할 것인지를 지정하는 것

chmod u+x hi-machine.sh ; hi-machine.sh 이라는 파일에 대해 소유자에게 실행권한을 주는 명령

 

디렉토리 권한
perm이라는 디렉토리 만들었을 때
chmod or perm -> perm이라는 디렉토리는 제3자들이 못 읽어
chmod otr perm -> 제3자가 읽기 가능

 

chmod 사용법 

형식: chmod [option] [mode] file

octal: 8진수 모드 0: ---1: --x2: -w-3: -wx4: r--5: r-x6: rw-7: rwx

class의 종류

u : user

g : group

o : other

a : all

operator의 종류: +, -, =

 

<섹션 8. 그룹> 

group: 특정한 사용자 그룹, 특정 사용자들만 묶어 이름과 권한을 부여

 

그룹 만드는 법

groupadd 그룹이름 : 그룹 추가하는 명령어

그룹이 잘 추가되었는지 확인하는 법 : nano /etc/group 입력 후 그룹이름 있는 지 확인

usermod : 이미 존재하는 사용자를 수정하는 명령어

usermod -a -G 그룹이름 사용자이름 : 해당 그룹에 해당 사용자를 추가하는 명령어

chown [owner] [group] file: 파일의 오너와 그룹을 변경

 

<섹션 9. 인터넷, 네트워크 그리고 서버> 

 

인터넷
웹 브라우저 사용할 때
클라이언트: 서버에 요청함

서버: 요청을 받아 응답하며 서비스를 제공해줌

 
서버 접속 방법 -> domainname or IP 주소 이용

damainname: 전화번호부에 저장된이름
IP address: real 전화번호
DNS sever: IP주소를 저장하고 있는 데이터베이스
ip addr: 자신의 IP 주소 알아내는 명령어
ipinfo.io/ip: IP 주소 알려주는  서비스
curl ipinfo.io/ip: 리눅스에서 IP 주소 알 수 있음

apache1

apache: 리눅스에서 사용하는 웹 서버 프로그램
elinks: 쉘 환경에서 웹 브라우징을 할 수 있는 프로그램

웹 브라우저에서 자신이 설치된 컴퓨터에 설치된 웹 서버에 접속하는 방법: ip addr 사용 or localhost(127.0.0.1) 사용

 

apache2 - configuration

유닉스에서 여러가지 동작방법에 대한 설정들이 etc라는 곳에 저장됨.

웹 브라우저가 접속할 때 웹 서버는 /etc/apache2라는 디렉토리 밑에 있는 여러가지 설정파일들을 참고해서 사용자의 접속이 들어왔을 때 서버 컴퓨터의 어떤 스토리지의 어디에서 사용자가 요청한 파일을 뒤질 것인가를 설정파일을 참고해서 뒤진다.

어떤 서버를 쓰건 간 대부분의 서버들은 etc라는 디렉터리 밑에 자신의 이름으로 설정파일이 있고 그 파일을 수정하면 동작하는 방식이 달라진다.

 

어떤 서버를 쓰건 간 대부분의 서버들은 etc라는 디렉터리 밑에 자신의 이름으로 설정파일이 있고 그 파일을 수정하면 동작하는 방식이 달라진다.

 

apache3 - log

운영하고 있는 웹 서버에 사용자들이 여러가지 접속을 하는데, 그 접속의 현황을 보고싶을 때 log 파일을 본다.

/var/log/apache2: 로그파일 존재.

tail /var/log/apache2/access.log: 실시간으로 마지막 log 확인 가능

 

SSH 

ssh: 클라이언트 컴퓨터로 원격지에 있는 서버컴퓨터를 원격제어 해야할 때 SSH 사용
ssh 설치 과정

: sudo apt-get install openssh-server openssh-client → sudo service ssh start → sudo ps aux | grep ssh (잘 실행되는지 확인)

 

포트

모든 컴퓨터에는 포트가 있다.

SSH는 22번, WS은 80번 약속

~1024: 포트의 값 고정 / 유명한 인프라 같은 역할을 하는 프로그램들

 

포트포워딩

포트포워딩: 컴퓨터 서버에 외부 사용자가 접근할 수 있게 하는 방법, 사용자의 접속이 들어왔을 때 라우터 특정 포트에 접속이 들어오면 그 접속을 컴퓨터의 특정한 포트로 전달한다 

공유기의 안쪽에서만 통용되는 ip 를 default gateway 라고 함.

default gateway 알아내는 법 : ip route 입력

 


<STEP 1>

어셈블리어: 기계어와 일대일 대응이 되는 컴퓨터 프로그래밍의 저급 언어

예시 프로그램

 

예시 파일 어셈블리어로 변환

 

EIP 레지스터 : CPU가 수행할 명령이 있는 레지스터

프로그램이 시작되면 EIP 레지스터는 main()함수가 시작되는 코드를 가리킴

ESP : stack pointer

ESP는 스텍의 맨 꼭대기를 가리킴.

ESP가 스텍의 맨 꼭대기를 가리키고 있는 이유

: 프로그램이 수행되면서 수많은 PUSH와 POP 명령을 할 것이기 때문에 이 지점에 다 PUSH를 해라, 이 지점에 있는 데이터를 POP해 가라 라는 의미

EBP : base pointer

ebp를 저장하는 이유

: 이전에 수행하던 함수의 데이터를 보존하기 위함.

함수 프롤로그 과정

: 함수가 시작될 때 stack pointer와 base pointer를 새로 지정하는 과정

 

<STEP 2>

push %ebp : 이전 함수의 base pointer를 저장하면 stack pointer는 4바이트 아래를 가리키게 될 것

mov %esp, %ebp : ESP 값을 EBP에 복사. 함수의 base pointer와 stack pointer가 같 은 지점을 가리키게 됨.

sub $0x8, %esp : ESP에서 8을 빼는 명령

and $0xfffffff0, %esp : ESP와 11111111 11111111 11111111 11110000 과 AND 연산. ESP의 주소 값의 맨 뒤 4bit를 0으로 만들기 위함.

mov $0x0, %eax : EAX 레지스터에 0을 넣음

sub %eax, %esp : ESP에 들어 있는 값에서 EAX에 들어 있는 값만큼 뺌.

sub $0x4, %esp : 스텍을 4바이트 확장

 

<STEP 3>

push $0x03 push $0x02 push $0x01

: function(1, 2, 3)을 수행하기 위해 인자값 1, 2, 3을 차례로 넣음.

call 0x80482f4 : 명령은 0x80482f4에 있는 명령을 수행하라는 것. (0x80482f4에는 function 함수가 자리잡은 곳임.)

call 명령은 함수를 호출할 때 사용되는 명령으로 함수 실행이 끝난 다음 다시 이 후 명령을 계속 수행할 수 있도록 이 후 명령이 있는 주소를 스텍에 넣은 다음 EIP에 함수의 시작 지점의 주소를 넣음 → 함수 수행이 끝나고 나면 이제 어디에 있는 명령을 수행해야 하는가 하는 것을 스텍에서 POP하여 알 수 있게 됨 …return address

 

<STEP 4>

push %ebp mov %esp, %ebp

: function()함수에서도 마찬가지로 함수 프롤로그가 수행됨. main()함수에서 사용하던 base pointer가 저장되고 stack pointer를 function()함수의 base pointer로 삼는다.

 

<STEP 5>

sub $0x28, %esp : 스텍을 40바이트 확장함

⇒ 40바이트가 된 이유 : simple.c의 function()함수에서 지역 변수로 buffer1[15] 와 buffer2[10]을 선언했기 때문

buffer1[15]를 위해서 16바이트, buffer2[10]을 위해서 16바이트가 할당된다. 그리고 추가로 8바이트의 dummy가 들어가 총 40바이트의 스텍이 확장 된 것.

 

<STEP 6>

만들어진 버퍼에는 이제 필요한 데이터를 쓸 수 있게 됨.

mov $0x41, [$esp -4] mov $0x42, [$esp-8] 보통 위와 같은 형식으로 ESP를 기준으로 스텍의 특정 지점에 데이터를 복사해 넣는 방식으로 동작함.

 

<STEP 7>

leave instruction은 함수 프롤로그 작업을 되돌리는 일을 함.

이전에서 본 대로 함수 프롤로그는 push %ebp mov %esp, %ebp 임.

이것을 되돌리는 작업 은 mov %ebp, %esp

pop %ebp 이다.

stack pointer를 이전의 base pointer로 잡아서 function() 함수에서 확장했던 스텍 공간을 없애버리고 PUSH해서 저장해 두었던 이전 함수 즉, main()함수의 base pointer를 복원시킨다.

 

<STEP 8>

ret를 수행하고 나면 return address는 POP되어 EIP에 저장되고 stack pointer는 1 word 위로 올라간다. add $0x10, %esp : 스텍을 16바이트 줄임. stack pointer는 0x804830c에 있는 명령을 수행하기 이전의 위치로 돌아가게 됨. leave ret 를 수행하게 되면 각 레지스터들의 값은 main()함수 프롤로그 작업을 되돌리고 main()함수 이전으로 돌아가게 된다.