'보안 & 모의해킹/기타지식'에 해당되는 글 5건

  1. 2018.02.19 gdb를 사용한 실행파일 디버깅하기
  2. 2018.02.18 해커스쿨 강의만화 기록_4
  3. 2018.02.18 해커스쿨 강의만화 기록_3
  4. 2018.02.18 해커스쿨 강의만화 기록_2
  5. 2018.02.18 해커스쿨 강의만화 기록_1

* gdb를 사용한 실행파일 디버깅하기 *




보통 보안이나 해킹에서 보면 실행파일을 까 보는? 경우가 있습니다. 물론 제가 아직 거기까지 통달하지는 않았지만


역시나 오늘도 기록을 위해서 포스트를 작성해 보도록 하겠습니다.



일단 C언어를 사용한 코드를 하나 작성해 보겠습니다.



> touch shell.c


> nano shell.c



(source)

#include <stdio.h>


int main() {

int a = 10;

int b = 20;

int result = 0;


result = a + b;


return 0;

}



사실상 stdio.h 헤더는 사용하지 않았지만 버릇처럼 넣어버렸습니다...


아주 간단한 코드입니다.


a 에 10을 넣고 b 에 20을 넣고 그 값을 result 라는 4바이트짜리 변수에 넣고 종료


이것을 이제 gcc 를 통하여 실행파일로 컴파일 해보겠습니다.



> gcc -o shell shell.c


-o 옵션은 컴파일한 출력 파일의 이름을 지정해주는 옵션입니다.


단순히 gcc shell.c 로도 할 수 있지만, 이 결과는 a.out 리는 실행파일이 나오게 됩니다.


출력문 printf 를 쓰지 않았기 때문에 당연히 아무 반응도 없습니다.


==============================================================================


이것을 이제 gdb(GNU Debugger) 를 통해 디버깅을 해서, 어셈블리 코드로 바꿔서 결과를 보겠습니다.




> gdb shell


(gdb) > disass main


disass main 의 의미는 disassemble main 의미입니다.


즉 main 메소드를 역어셈블 한다는 뜻이죠.


한줄한줄 살펴볼까요?



==============================================================================



1. <+0>:    push   %rbp


이 1번줄과 2번줄은 어셈블리에서 항상 나오는 표현입니다.


레지스터 rbp를 스택에 넣어두고, rsp를 rbp에 넣어줍니다.


참고로 윈도우와는 다르게 리눅스에서는 source 와 destination 의 위치가 바뀝니다.



즉, add %r1, %r2 가 윈도우에서는


r1 = r1 + r2


이었다면, 리눅스에서는


r2 = r2 + r1


이 됩니다. 헷갈리실 수도 있으니 꼭 참고하세요.




2. <+1>:    mov    %rsp,%rbp


네, 아까 말씀드린 것처럼 어셈블리에서 항상 나오는 표현입니다.


1번줄과 2번줄은 외워두시는 것도 좋습니다. 저는 이미 외웠습니다.




3. <+4>:    movl   $0xa,-0xc(%rbp)


본격적인 main함수의 표현입니다.


movl $0xa, -0xc(%rbp)


언뜻 봐도 0xa(=dec. 10) 의 값을 %rbp 에 넣어주는 표현인 것 같습니다.


그런데 왜 -0xc 를 해줄까요? 분명히 int 는 4바이트(=0x4)인데?




어셈블리어 익숙하신 분들은 눈치채셨을 수도 있습니다.


저는 ARM M1 Cortex 시리즈를 학교에서 공부하면서 ARM 어셈블리 문법을 공부했었는데,


거기서 배운 것 하나가 여기서 도움이 되네요.



역어셈블 과정에서 디버거는 변수의 개수를 셉니다.


main 함수를 보시면 int 변수가


int a

int b

int result


이렇게 3개가 나옵니다.


즉, 4바이트 * 3 = 12바이트 (=hex. 0xc)


라는 공간을 "미리" 할당합니다.




아래 그림을 한번 봅시다. (byte address 로 하지말고 4byte 어드레스라고 가정합니다. 즉 1칸에 4바이트)


               [rbp]

4byte

4byte

4byte

 

 

 

 



이렇게 3칸(12byte)을 할당해 줍니다.


그리고 나서, 변수가 나오는 순서에 따라서 맨 아래서부터 메모리 위치를 배정해줍니다.


int a = 10;


즉, 10의 값(=hex. 0xa) 을 맨 아래인 rbp - 12byte 위치에 넣어줍니다.


이것을 어셈블리로 표현하면


movl    $0xa, -c(%rbp)


가 되는 것입니다.




4. <+11>:    movl   $0x14,-0x8(%rbp)


위의 3번줄에서 설명한 것 처럼, 다음 변수는 -12 바이트 위치가 아닌,


4바이트가 줄어든 -8 바이트 위치에 할당해줍니다.


다음 변수는


int b = 20;


입니다. 즉, 20의 값을 -0x8(%rbp) (=%rbp - 8byte) 에 넣어줍니다.


20은 hexa 값으로 0x14 입니다. (1 * 16 + 4 * 1)




5. <+18>:    movl   $0x0,-0x4(%rbp)


똑같습니다. 마지막 변수는 int result = 0; 이므로,


0의 값을 -4바이트 줄어든 위치에 넣어줍니다.




6. <+25>:    mov    -0xc(%rbp),%edx


이 것은 계산을 위해서 값을 옮기는 과정입니다.


계산 식은


result = a + b;


해당 인수들의 주소는


&a = -0xc(%rbp)


&b = -0x8(%rbp)




여기서는 %rbp - 0xc 위치에 있는 값(=10)을 edx 레지스터에 넣어주었습니다.




rbp 에서 직접적으로 계산을 하지 않고 edx 와 eax 같은 범용 레지스터에 임시적으로 옮겨놓고


계산을 한 후 그 결과 값을 다시 rbp에 가져오게 됩니다.


쉽게 생각해서, 값을 보존하기 위해서? 라고 생각하시면 되겠습니다.




ARM 어셈블리를 배울 때도, 메모리에서 직접적으로 계산을 할 수가 없기 때문에


값들은 메모리에 넣어 놓고 필요한 값만 r1, r2, r3 등의 범용 레지스터에 옮겨서 계산 후 다시 메모리에 넣었던 기억이 납니다.




7. <+28>:    mov    -0x8(%rbp),%eax


6번줄과 마찬가지로 rbp -8byte 의 위치에 있는 값(=20)을 eax 레지스터에 넣어줍니다.


8. <+31>:    add    %edx,%eax


계산입니다.


eax = eax + edx


eax 에는 20이 들어가 있었고, edx 에는 10이 들어가 있었죠.


최종적으로


eax = 20 + 10


과 동일합니다.


eax 에 결과 값 30이 들어가게 되겠군요.




9. <+33>:    mov    %eax,-0x4(%rbp)


계산이 끝났으니 값을 옮겨줘야겠죠?


eax 레지스터에 있는 값을 -0x4(%rbp), 즉 %rbp - 4byte 위치에 넣어줍니다.


저희는 이미 위의 과정들을 통하여 어떤 변수(값)가 어느 위치에 있는지 알고 있습니다.


rbp에서 4byte 줄어든 위치는 result 변수가 할당되어 있는 자리입니다. (5번줄 참고)


즉, result 변수에 eax 레지스터의 값, 30이 들어가게 됩니다.




10. <+36>:    mov    $0x0,%eax


사용한 도구는 닦아줘야죠.


eax 레지스터를 초기화 해줍시다. 다음에 있을 연산이나 작업을 위해서요.


항상 초기화는 습관을 들여줍시다.




11. <+41>:    pop    %rbp


모든 프로그램이 끝났습니다. 1번줄에서 stack memory 에 save 해 두었던 값을 rbp 에 다시 옮겨줍시다.


12. <+42>:    retq  


return 0; 의 의미입니다.





==============================================================================




굉장히 쉬운 어셈블리 였습니다. 실제로 보안업무를 진행하시는 분들은 몇 백 줄의 C언어 코드를 역어셈블 해서 보실텐데, 이런 코드는 정말 맛보기일 뿐입니다.


그래도 gdb 를 사용하고, 역어셈블과 어셈블리 언어를 관찰했다는 것에 의의를 두었습니다.



>>> gdb


>>> 리눅스 어셈블리


>>> 리눅스 역어셈블


>>> GNU Debugger

Posted by NDC :

* 해커스쿨 강의만화 기록_4(고등학교 단계) *


마지막으로 4편, 고등학교 단계입니다.


이번 편에는 cmd 상에서 ping 명령어를 통해 단말기 유무를 판별하는 것을 보여주었습니다.



==============================================================================================


지식의 출처는 해커스쿨입니다. 감사합니다. 문제 될 경우 필히 삭제하도록 하겠습니다.


==============================================================================================



[컴퓨터 알아내기]

동일 네트워크 상 = 끝자리 하나만 다름

ex. 192.168.0.13 and 192.168.0.16 이런식(1~255)

cf) 192.168.0.1 과 같이 끝자리가 1은 거의 대부분! GateWay 로 쓰인다.


*** route 명령어 ***

Link = https://m.blog.naver.com/PostView.nhn?blogId=ys9922&logNo=90069129492&proxyReferer=https%3A%2F%2Fwww.google.co.kr%2F

********************


[ping 반복 c코드]

#include <stdio.h>


int main() {

int i;

char cmd[40];


for(i = 1;i<=255;i++) {

sprintf(cmd, "ping 192.168.0.%d", i);

system(cmd);

}

}


+ 핑 한번때리는 옵션:-c 1

sprintf(cmd, "ping -c 1 192.168.0.%d", i);


+ grep 으로 걸러내기:|grep from -> 응답이 있는 것은 from 이라는 문자열이 들어가기 때문.

sprintf(cmd, "ping -c 1 192.168.0.%d|grep from", i);


[구체적인 조사]

운영체제, SSH와 같은 포트의 오픈여부?

TTL값도 알아야함.

TTL? Time To Live, 패킷의 유효시간.

TTL=3은 최대 3개의 라우터를 거쳐갈 수 있다.

TTL 값의 존재 이유? 영원히 돌아다니는 패킷을 방지하기 위해

윈도우의 TTL = 100~128

리눅스의 TTL = 50~64


SSH = 22 port

SSH를 사용한다? => 22번 포트가 열려있다.

X-windows  = 6000번 퐅,

X-windows를 사용하지 않는다? => 6000번 포트가 닫혀있다.


-> telnet (대상의 IP주소) (포트번호)

열려있다?->허가됨

닫혀있다?->거부됨(refused)

ex. 

> telnet 192.168.0.13 22

Posted by NDC :

* 해커스쿨 강의만화 기록_3(중학교 단계) *


이번에는 3편, 중학교 단계입니다.


이번 편에는 프로그램의 전반적인 모습, 가장 기본적인 개념에 대해서, 메모리란 무엇인가? 에 대해서 다룬 것 같습니다.



==============================================================================================


지식의 출처는 해커스쿨입니다. 감사합니다. 문제 될 경우 필히 삭제하도록 하겠습니다.


==============================================================================================



[언어]

기계어-어셈-포트란(이때 고급언어 첫등장)-코볼-베이직-비

-씨-씨플플-HTML(+PHP)-python,delphi,java 등

미국 표준협회(ANSI) 에서 C언어의 표준안 발표(1990) -> ANSI-C


사람-c언어 작성(*source code*)-컴파일러(C언어->기계어(*binary code*))-컴퓨터가 보고-동작(프로그램)


패키지가 있나없나?

> ls /usr/bin/(package name)

ex. ls /usr/bin/gimp

있으면 경로 출력, 없으면 No such file or directory(오류뜸)


*** /usr/bin/ 에 대해

ex. > touch a.sh 라는 쉘 스크립트 하나 만들었다.

> chmod 777 ./a.sh

이 쉘스크립트를 실행시키려면? 경로입력을 일일히 해야한다.

경로입력없이 그냥 

> a.sh

로만 실행시키려면?

> sudo mv ./a.sh /usr/bin/

=> /usr/bin/ 경로에 넣어라!

그러면 경로를 입력하지 않아도 바로 실행된다.


[소스코드 입력]

1. cat > main.c - 이후 소스코드 입력하고 완료 후엔 Ctrl+d

but, 입력한(엔터를 친) 부분이 수정불가한게 단점.

2. nano 혹은 gedit, vi 등 CUI 기반의 텍스트 에디터 사용


컴파일

> gcc -o main.out main.c -> 실행파일:main.out

> gcc main.c -> 실행파일:a.out


[vi editor]

1.명령모드 2.편집모드 3.라인모드

> touch main.c

> vi main.c

이후 보이는 화면은? 


3.라인모드

:w = 저장

:q = 나가기

:q! = 세이브 없이 강제종료

:wq = 세이브 하고 종료


[메모리]

Ram = Random Access Memory,임의 접근 기억장치

속도가 빠르다(전기 신호), 하지만 전기 신호로 정보를 기록하기 때문에

컴퓨터 종료 시 사라진다.

HDD 는 금속 판에 자성 물질을 입혀서 저장 = 속도가 느림. 하지만 대용량(물리적 공간)

Rom = Read Only Memory, 읽기 전용 기억장치


Ram은 빠르다, 하지만 빈 공간에 저장해야 한다(덮어씌워지면 이전 정보가 사라짐)

프로그램들은 메모리에 접근하기 전에 빈 공간을 요청해야 함.(메모리 할당)

1byte = 8bit(8개의 자릿수를 의미)

@@@@ @@@@ 에서 @는 1bit, @@@@ @@@@는 1byte

@에는 0 or 1이 올 수 있다.


예외)ARM Assembly 에서는 메모리에서 @@ 이 1byte, 이는 Hexa 값이기 때문에 2의 8승, 즉256개의 정보가 들어간다

(0x00 ~ 0xFF) = @를 풀어서 보면? xxxx 와 동일, x에는 0 or 1이 올 수 있다. 


즉, bit 는 자릿수다

n bit = 자릿수 n개

Posted by NDC :

* 해커스쿨 강의만화 기록_2(초등학교 단계) *


이전의 1편에 이어서 이번에는 초등학교 카테고리의 강의만화를 정리한 것들을 올리겠습니다.



==============================================================================================


지식의 출처는 해커스쿨입니다. 감사합니다. 문제 될 경우 필히 삭제하도록 하겠습니다.


==============================================================================================



[운영체제]

컴퓨터에서 어떤 작업이라도 하기 위한 가장 기초적인 프로그램

Bell 연구소의 UNIX 운영체제 개발(어셈블리어, 이후 UNIX는 C언어로 재개발된다)

-> 워크스테이션급의 고성능 컴퓨터를 위한 무거운 OS가 일파만파 생겨남

-> DOS(Disk Operating System) 개발됨(디스크 한장에 OS가 있다)

-> 빌 게이츠의 MS-DOS 개발됨(이후 MS-Windows 로 발전)

-> Linux 출시됨(리누스 토발즈)


[리눅스]

Unix 를 모태로 개발됨.

하지만 Kernel 을 포함한 모든 소스코드는 토발즈가 독자적으로 구현.

특징

- PC(Personal Computer)에서 사용가능.

- 멀티 유저 시스템을 지원(컴퓨터 한대에 한명이 아님, 자식 낳듯이 퍼질 수 있다->서버 시스템)

- 가볍고 안정적(저사양 컴퓨터에서도 사용가능)

- 무료, 오픈소스(내 마음대로 수정 가능)

- 글로벌하게 만들어가는 OS(오픈 소스 프로젝트, 지속적이고 빠른 업그레이드)


startx 명령어:x-windows 실행.(GUI 모드, Command 는 prompt 모드라고 한다.)


리눅스의 최고 관리자:root

- 사용자 관리(추가, 삭제, 패스워드 변경 등등)

- 서비스 관리(Web, FTP, Mail 등의 서비스 설치 및 삭제)

- 시스템 종료 및 리부팅

- 기타 중요한 설정 변경(날짜/시간, 네트워크 설정, 도메인 설정 등)


GUI->CUI(=TUI 진입:Ctrl+Alt+F1

CUI->GUI 진입:Ctrl+Alt+F7


CUI를 사용해야만 하는 경우

- 원격으로 나의 Linux 서버, 혹은 다른 사람의 서버에 접속할 때

- Linux의 설정을 세부적으로 변경하고 싶을 때

- 소스코드로 이루어진 새로운 프로그램을 설치할 때

- X-Windows 에 문제가 생겨 정상적으로 부팅이 되지 않을 때

- CUI 기반의 훌륭한 프로그램등을 사용해 보고 싶을 때(nmap, nc 등)


[데비안]

이안 머독으로부터 시작


[듀얼부팅]

- 두개의 하드에 각각 윈,눅 설치

- 하나의 하드를 두개의 파티션으로 나누어 각각 윈,눅 설치

- 윈 안에 눅 설치

- 눅 안에 윈 설치

Posted by NDC :

* 해커스쿨 강의만화 기록_1(유치원 단계) *




17회 해킹캠프에 당첨되었습니다!


해킹켐프를 준비하기 위해 해커스쿨에서 대충 만화정도만 살펴보았는데


상당히 도움이 되었던 것 같습니다.

(카테고리에서 유치원~고등학교 까지입니다.)


오늘은 제가 본 강의만화들을 텍스트로 한번 정리해 보았고, 그것들을 공유하려고 가져왔습니다.

(두서없이 적었습니다. 보기 힘드시겠지만 공유에 목적을 두고 하도록 하겠습니다.)


==============================================================================================


지식의 출처는 해커스쿨입니다. 감사합니다. 문제 될 경우 필히 삭제하도록 하겠습니다.


==============================================================================================


해커스쿨 URL

http://www.hackerschool.org/Sub_Html/HS_Community/index.html

해킹캠프 URL

http://hackingcamp.org/




1. 네트워크 - IP, port, protocol, 방화벽

2. 프로그래밍 - C언어/php,asp(웹해킹)/WinAPI(윈도우즈해킹)

/POSIX C,Shell script,perl(유닉스해킹)/Assembly(기계어)

3. 운영체제 - 윈도우즈,유닉스,리눅스(서버구축,메모리,라이브러리,백도어,스텔스)

4. 수학 - 메모리주소 계산,역공학,암호학


#########################################################################################


- 인터넷,TCP/IP등 네트워크 기초 이론에 대해 학습

- 운영체제(리눅스)의 설치, 운용, 서버 구축 방법

- C언어 학습, POSIX C언어도 학습, 이후 네트워크 프로그래밍

- 해킹 기법 학습, 버퍼 오버플로우, 포맷 스트링, 네트워크 해킹, 웹 해킹 등등

- 어셈블리어 학습 후 바이너리 파일 디버깅 실습, 운영체제의 커널에 대해 학습.


#########################################################################################


[네트워크]

인터넷과 사용자를 연결시켜주는 업체 = ISP(Internet Service Provider)

Ethernet = 데이터 통신 기술의 한 종류, 초당 10Mbps

인터넷 연결 순서:집-전봇대-맨홀(지하로가서)-전화국-ISP(인터넷서비스제공자)

라우터:집에서 나온 패킷이 도착해야 할 곳을 찾아줌.

패킷:데이터와 비슷함

내가 데이터(패킷)를 송출하면 그 데이터(패킷)는 ISP의 라우터에 도달함.(ex. Cisco Router)

내가 송출한 데이터가 수신될 위치를 찾는 것이 라우터의 역할.

라우터는 인터넷 곳곳에 설치되어 있다. 

목적지를 찾는 것 뿐만이 아니라, 목적지까지 가장 빠른 길을 찾는 것도 라우터의 역할.


그럼 패킷이란?

패킷은 실생활의 소포와 비슷한 의미.

소포처럼 받는사람의 주소(=받는이 IP)와 보내는사람의 주소(=보내는이 IP)가 자동으로 기록됨.

이처럼 실제 데이터 앞쪽에 자동으로 붙는 주소같은 정보들을 Header라고 한다.

헤더+실제 데이터 = 1개의 패킷


[기본 네트워크 명령어들]

net send = 상대방 컴퓨터에 메세지를 보내는 명령어

> net send (상대방 IP) ("보낼 메세지") 이었지만...XP sp2 이후로 막힘

> msg * Hi -> 로컬 상의 모든 세션(컴퓨터)에게 Hi 라는 메세지를 보냄.

/V -> 상태 보여줌 / /W -> 응답 보여줌

그래서 보통은 

> msg *(=모든 세션) /V /W Hello!

내 컴퓨터 IP = 127.0.0.1

(Link = http://neoray.org/495#.Wohkla5l9aQ)


ping = 상대방 컴퓨터와 내 컴퓨터가 서로 연결되어 있는지를 확인하는 명령어

ex1. ping (IP Address)

ex2. ping (Domain)


ipconfig(Linux:ifconfig) = 내 컴퓨터의 IP를 보는 명령어


NETSTAT = 내 컴퓨터에 열린 포트를 보는 명령어(ex. netstat -an)


TRACERT = 내 컴퓨터에서 상대방 컴퓨터까지 이어진 경로를 추적하는 명령어

ex. tracert (Domain or IP Address)///(ex. tracert google.com)

여기서 나오는 IP들은 라우터이다.

Posted by NDC :