Inject ME!!!

Description 드림이가 수상한 DLL 파일을 획득하였습니다. DLL 파일과 함께 있던 TXT 파일에는 조건을 맞춰서 DLL을 로드시키면 플래그를 얻을 수 있다고만 쓰여 있었습니다. 어떻게 해야 DLL 파일을 로

dreamhack.io

 

문제 파일로 dll 파일 하나만 달랑 주어진다.

문제 설명을 읽어보면 DLL 파일을 조건에 맞춰서 로드시켜야한다고 하는데… 조건이 무엇인지는 안알려준다.

조건을 어떻게 찾아야할지 감을 못잡고 있다가 무작정 hex editor를 켜서 flag 문자열에 대해 검색해보았다.

그랬더니 아래와 같이 flag 문자열 주변에 dreamhack.exe라는 문자열이 있는 것을 발견하였다.

 

DLL은 자체적으로 로드되기보단 실행 파일에 기생(?)하여 실행되어야 할 것인데, Windows에서 사용되는 대표적인 실행 파일은 exe 확장자를 가진 파일이다.

그런데 마침 dreamhack.exe 라는 .exe 확장자를 가진 문자열을 발견하였고, dreamhack.exe 파일이 뭔지는 모르겠지만 일단 주어진 DLL을 로드하는 코드를 다음과 같이 만들었다.

#include "stdio.h"
#include "windows.h"
#include "conio.h"

void main() {
	HMODULE			hDll = NULL;

	hDll = LoadLibraryA("prob_rev.dll");
	if (hDll == NULL) {
		printf("Failed to load dll");
		return;
	}

	printf("Success to load library");
	while (_getch() != 'q');

	FreeLibrary(hDll);
}

 

여기서 dreamhack.exe 라는 문자열을 활용할 수 있는 방안은 실행할 exe 파일의 이름을 동일하게 맞춰주는 것이라고 생각되었기에, 이 코드를 빌드한 결과로 얻은 exe 파일의 이름을 dreamhack으로 변경한 후 실행하였다.

이걸 운이 좋았다고 표현하는게 맞는건지… 바로 flag를 얻을 수 있었다.

 


이렇게 풀어놓고 안찝찝할 수가 없다. 그래서 다른 풀이자분들의 풀이를 보았고, x64dbg를 이용해서 직접 dll의 행위를 리버싱할 수 있는 것을 알았다. 그렇기에 나도 직접 디버깅을 해보았다.

먼저 확인 가능한 문자열을 확인해보았고 다음과 같은 결과를 얻었다.

여기서도 dreamhack.exe는 매우 수상한 문자열로 느껴지므로 이것이 사용되는 위치로 이동해서 분석을 시작하였다.

 

이 부근을 디버깅해보면 dreamhack.exe 문자열이 strncmp 함수에 의해 rcx에 저장된 어떤 문자열과 비교되는 것을 알 수 있다.
그리고 문자열 비교 전 File명을 가져오는 함수가 사용되는데, 이 때 사용되는 파일의 경로가...

주어진 dll을 로드하고 있는 파일의 경로이다.

 

이를 계속 실행시켜보면 결국 현재 dll을 로드하고 있는 파일의 이름과 dreamhack.exe 문자열을 비교하고 있다.

 

따라서 실제로 파일명을 가져오는 함수의 결과를 담는 rax의 값을 dreamhack.exe로 바꿔주면 이 부분을 정상적으로 통과해 flag를 얻을 수 있다.

 

 

rev-basic-8

Reversing Basic Challenge #8 이 문제는 사용자에게 문자열 입력을 받아 정해진 방법으로 입력값을 검증하여 correct 또는 wrong을 출력하는 프로그램이 주어집니다. 해당 바이너리를 분석하여 correct를 출

dreamhack.io

 

이 문제도 여타 다른 문제와 마찬가지로 입력값을 넣고 일련의 연산을 취한다음 이것이 특정한 값과 일치하는지를 비교하여 Correct / Wrong을 출력하는 문제이다. 역시나 Correct가 나올 수 있는 입력값을 찾아야 한다.

아래는 프로그램의 main 코드이다. 이중 일부 부분의 직접 변수명이나 타입을 바꾸어준 상태이다.

보면 uVar1의 값을 가지고 Correct / Wrong 결과를 가르는데 이 값을 결정짓는게 FUN_140001000 함수이다. 이 함수의 인자로 입력값이 들어가는걸 보면 이 함수가 핵심인게 분명하다.

 

아래 코드는 FUN_140001000 함수의 decompile 결과이며, 미리 각 변수의 이름을 해석하기 편리하도록 고쳐둔 상태이다.

코드를 보면 20개의 문자를 하나씩 비교하는데, 이 때 입력값에 대해 일련의 연산을 취한 후 이 값이 문제 속 데이터와 일치하는지 검사한다.

 

DAT_140003000 위치를 가보면 정확히 20개의 16진수 데이터가 위치해있음을 알 수 있다.

그러나 위 코드에서 입력값에 -5가 곱해지는 것도 그렇고 좀 더 자세한 분석이 필요할 것으로 보여 어셈 코드로 다시 살펴보았다.

 

입력값에 대한 연산은 140001031과 140001037 이렇게 두 부분이 핵심이다.

  • 14000102d: 입력값에 대해 byte 단위로 가져온 후
  • 140001031: 이에 대해 FB를 곱하고
  • 140001037: 그 결과에서 하위 1바이트만 남기고 지운다.

여기서 연산 결과에 대해 하위 1바이트만 남기고 지우기 때문에, 곱셈 결과가 어떻게 나오든 문제 속 하드코딩되어 있는 각각의 바이트와 하나씩 비교가 가능한 것으로 보인다.

 

이 문제를 풀기 위해 처음에는 곱셈의 반대인 나눗셈으로 시도해보려고 했지만, 아무래도 AND 연산으로 하위 바이트를 자르고 비교하는 형태이기 때문에 역연산으로 정답인 입력값을 찾기 어려울 것 같았다. 그래서 결국 가능한 입력 범위 안에서 브루트포스 코드를 작성하였다.

answer = [0xAC, 0xF3, 0x0C, 0x25, 0xA3, 0x10, 0xB7, 0x25, 0x16, 0xC6, 0xB7, 0xBC, 0x07, 0x25, 0x02, 0xD5, 0xC6, 0x11, 0x07, 0xC5]
input_data = []

for i in range(20):
	for num in range(0x20, 0x7E):
		if (num * -5) & 0xFF == answer[i]:
			print(chr(num), end='')
			break

 

이를 실행하면 플래그를 얻을 수 있으며, 뜨끔하는 문장을 얻을 수 있다.ㅋㅋ

 

 

patch

flag를 그리는 루틴을 분석하고 가려진 flag를 보이게 해주세요. Reference GDI+ - Win32 apps | Microsoft Docs Graphics Functions - Win32 apps | Microsoft Docs File — x64dbg documentation

dreamhack.io

 

이 문제는 실행하면 아래와 같이 딱 중요한 부분만을 가려놓은 윈도우 GUI 프로그램을 제공한다.

 

문제 설명을 토대로 유추하면.. Graphic 함수를 이용하여 flag를 그리는데, 이 루틴 중 flag를 가리는 부분을 패치하여 플래그를 얻어내는 문제인 것으로 추정된다.

IDA를 통해 문제 파일을 열어보면 Windows GUI 프로그램 국룰 시작 지점인 WinMain 함수를 확인할 수 있다. 그런데 내 IDA는 서버와의 오류 때문에 hex-ray가 되지 않으니 IDA가 찾아준 WinMain의 위치를 이용하여 Ghidra에서 WinMain의 hex-ray 결과를 볼 것이다.

 

아래는 Ghidra에서 분석해준 WinMain 함수의 hex-ray 결과이다.

 

MSDN의 API 문서에서 검색하면 알 수 있겠지만..

32줄의 CreateWindowExW 함수를 이용하여 윈도우 창을 실행하고,

이에 앞서 30줄의 RegisterClassExW 함수를 이용하여 CreateWindowEx 함수에서 사용할 창 클래스를 등록한다. 그렇기에 RegisterClassExW의 매개인자로 들어가는 WNDCLASSEXW 타입의 local_a8 변수의 속성을 18~29줄에서 정의하고 있는 것을 알 수 있다.

처음에는 이렇게 창 클래스 정의하는 부분은 단순 속성이라 생각하고 CreateWindowExW 함수를 이용하여 창을 생성하고 난 이후 if 문 안에서 이루어지는 작업이 그래픽 작업을 하는 부분인줄 알고 헤맸던 것 같다. 그런데 원하는 그래픽 작업 흔적이 명확하게 발견되지 않아 찾는 방식을 바꿨다.

Ghidra의 Symbol Tree 부분을 보면 GDIPLUS.DLL 이라고 그래픽 작업 관련 함수를 포함하는 DLL를 발견할 수 있다. 본 프로그램에서 사용되는 dll과 함수라고 생각하고 이 부분이 참조되고 있는 부분을 찾아나갔다.

 

다 사용되는 것 같긴 했지만, 이 중 GdipDrawLineI 함수에 대한 Reference 내역을 먼저 조회했다.

많은 결과가 나오지만 이 중 가장 첫 번째 항목을 따라갔다.

 

추적 결과 FUN_140001240 함수에서 사용되고 있었으며,

 

이 부분의 Call Tree를 따라가보면

 

다음과 같이 윈도우 창 클래스를 정의하던 부분의 lpfnWndProc 속성에 정의되는 FUN_1400032f0 함수를 통해 Pen 작업이 이루어지고 있음을 알 수 있다.

WNDCLASSEXW클래스의 lpfnWndProc 속성의 경우 창 클래스에 대한 프로시저 포인터를 가진다. 여기에 들어가는 함수는 콜백 함수 형태를 가지며, 윈도우 창에서 사용자에 의한 상호작용이 발생할 경우 이를 어떻게 처리할 것인지를 정의한다. 그렇기 때문에 이 부분에서 창에 보여질 행위 중 하나인 draw 작업이 이루어진 것으로 생각한다.

 

FUN_1400032f0 함수 내부를 살펴보면

BeginPaint 함수와 EndPaint 함수가 있으며, 이 사이에서 GdipAlloc 후 어떤 작업을 수행하고 GdipFree까지 하고 있다. 그 과정에서 FUN_140002c40 함수가 호출되는데, 이 함수의 내부를 살펴보면

 

다음과 같이 반복적으로 특정 함수가 호출하는 작업이 이루어짐을 확인할 수 있다.

아래 코드를 보면 초반에는 FUN_140002b80 함수가 반복적으로 사용되고 있고, 그 이후에 서로 다른 함수가 호출되고 있다.

 

우선 FUN_140002b80 함수의 역할에 대해 보기 위해 내부를 분석했다.

이 함수에서는 GdipCreatePen1 함수 호출 이후 GdipDrawLineI 함수를 이용하여 한번의 직선을 그리고 GdipDeletePen 함수를 이용하여 Pen 작업을 끝낸다.

즉, FUN_140002b80 함수가 한번 실행될 때마다 이 param으로 들어온 값에 따라 한 개의 직선을 그리고 있는 것으로 생각된다.

 

FUN_140002b80 함수 이후에 차례로 나타나는 여러 함수들의 경우는 조금 다른 코드 패턴을 가진다.

그 중 FUN_140002b80 함수 이후로 가장 처음 나타나는 FUN_1400017a0 함수는 다음과 같이 여러 차례의 GdipCreatePen1 - GdipDrawLineI - GdipDeletePen 과정을 가지며, 여러 선을 그리고 있는 것으로 추정된다.

FUN_1400017a0 함수 이후에 나타나는 여러 함수들도 FUN_1400017a0 함수와 같이 여러 개의 선을 그리는 코드를 가진다.

 

따라서 FUN_140002b80 함수와 그 이후에 위치하는 FUN_1400017a0 함수와 같은 함수들이 각각 어떤 선을 그리는지 보기 위해 다시 IDA를 이용하여 해당 위치를 동적 분석하였다.

FUN_140002b80 함수와 FUN_1400017a0 함수에 각각 bp를 걸고 실행시켰다.

 

먼저 처음 호출된 FUN_140002b80 함수의 경우 아래와 같은 선을 그린다.

그리고 그 다음에 호출된 FUN_140002b80 함수 역시 다음과 같은 선을 그린다.

여러 차례 진행되는 FUN_140002b80 함수를 모두 호출하고 나면 다음과 같은 선들이 그려진다.

이 선들이 그려진 곳은 분명 플래그를 가리는 위치이다. 따라서 FUN_140002b80 함수는 플래그를 가릴 때 사용하는 함수로 여길 수 있다.

그리고 그 이후에 bp를 걸었던 FUN_1400017a0 함수를 실행하면 다음과 같이 플래그의 첫글자가 그려진 것을 확인할 수 있다.

이후의 함수들을 모두 호출하면 다음과 같이 모든 플래그가 그려지게 되는 것을 알 수 있다. (비록 가려져 있긴 하지만…)

이를 통해 플래그를 가리는 함수인 FUN_140002b80 함수가 실행되지 않도록 막으면 정상적으로 플래그를 확인할 수 있을 것임을 알았다.

 

패치를 하기 위해 다음과 같은 방안을 생각해보았다.

  1. FUN_140002b80 함수 시작 위치 어셈을 ret로 패치
  2. FUN_140002b80 함수를 call 하는 위치 어셈을 nop으로 패치

IDA로 패치하려니 계속 권한 오류가 떠서 x64dbg로 패치했다.
x64dbg에서 패치하려고 하는 주소로 이동한 후 고안한 방법대로 패치를 진행한다.

 

1. FUN_140002b80 함수 시작 위치 어셈을 ret로 패치

→ 잘 된다.

 

2. FUN_140002b80 함수를 call 하는 위치 어셈을 nop으로 패치

→ 잘된다.

 

사실 두 방법 모두 FUN_140002b80 함수의 실행을 방해한다는 측면에서 같은 방식이긴 하다.

그러나 두번째 방법을 사용할 경우 FUN_140002b80 함수가 실행되는 모든 곳에 대해 패치를 해야하니 더 번거롭기 때문에 굳이 이렇게 할거면 첫 번째 방법이 좀 더 나은 선택지인 것 같다는 생각을 했다.

이렇게 패치를 해도 괜찮은 이유는 다음과 같다.

  1. 본 프로그램이 레지스터를 이용하여 인자를 전달하는 x64 프로그램이고, FUN_140002b80 함수 역시 함수 내에서 스택을 정리하는 fastcall 호출 규약을 사용한다. 그렇기 때문에 함수 실행과 관련하여 스택을 직접 손봐줘야할 필요가 없다.
    다만 함수 내에서 ret를 이용하여 함수를 종료할 경우 함수 내에서 스택을 사용하기 전에 ret를 넣어줘야 가장 최근에 스택에 넣었던 ret 값을 그대로 다시 가져와 원래 위치로 돌아갈 수 있을 것이다.
  2. FUN_140002b80 함수의 리턴값이 코드의 다른 부분에 사용되지 않기 때문에, 별도로 리턴값을 관리해줄 필요 없이 함수 실행만 막으면 된다.

 

1번과 관련하여 잘못 패치를 하는 상황을 재현해보았다.

여기에서는 FUN_140002b80 함수의 프롤로그 이후 사용할 스택 메모리를 확보한 상황에서 스택 정리 없이 곧바로 ret를 넣은 경우이다.

FUN_140002b80 함수의 프롤로그 실행 시 ret 값에 의하면 본 함수 종료 후 rip는 7FF63BC22C71 값을 가지며 함수를 call 했던 코드의 다음 코드로 돌아가야 한다.

그러나 지금과 같이 스택 프레임 확보를 위해 rsp값을 조정해주고 난 상황에서 ret를 이용하여 곧바로 pop rip를 수행하게 될 경우 dummy 값이 rip로 들어가 이후 정상적인 프로그램 실행에 문제를 일으키게 된다.

문제를 클릭하면 Easy_CrackMe.exe 라는 exe 파일 하나를 받을 수 있다.

다운로드 받은 파일을 실행해보면 아래와 같은 GUI 프로그램이 실행되는 것을 볼 수 있다. 문자열을 입력 후 확인 버튼을 누르면 Incorrect Password 라는 결과창을 보여준다. 이를 통해, 본 프로그램에서 "Incorrect password"라는 문자열이 쓰인다는 것을 알 수 있다.

 

이번에는 x32dbg를 사용하여 파일을 로드하고 실행하여 EntryPoint를 찾는다.

이 상태에서 문자열 검색을 누르면 아까 보았던 Incorrect Password 문자열을 볼 수 있고, 그 위쪽으로 Congratulation !! 이라는 문자열을 볼 수 있다. 올바른 비밀번호를 입력하면 이 문자열이 출력되는 것으로 추정된다.

 

임의의 문자열을 입력하게 되면 아래 부분으로 실행 지점이 이동하게 되며, 코드의 하단에서 성공 문자열도 볼 수 있다.

성공 문자열까지 무사히 실행 흐름을 유지하기 위해서 어떤 과정을 거치는지 살펴봐야겠다.

 

잘못된 문자열에 의해 실패 지점으로 가는 첫번째 분기문은 0x004010B5 지점이다.

이 위치에서 성공과 실패를 가르는 첫번째 조건은 byte ptr ss:[esp+5]61('a') 가 같아야 한다는 것이다.

byte ptr ss:[esp+5] 가 어떤 값을 가지는지를 보기 위해 esp가 가리키고 있는 콜스택의 값을 확인한다.

테스트로 입력해둔 값은 'aaaa' 인데, 마치 입력한 값을 가리키듯 스택에 들어있는 값 또한 61 61 61 61 (aaaa)을 가진다.

그리고 여기서 esp+5가 가리키는 값은 두번째 입력된 'a'가 된다.

이 값이 61인 a와 같아야 한다니, 정답인 password의 두번째 글자가 'a' 인 것을 알 수 있다.

 

다음으로, 두번째 분기문을 만나게 되는 지점은 0x004010CD 이다.

이 위치에서 성공과 실패를 가르는 기준은 eax의 값이 0이어야 한다는 것이다. (바로 윗 줄의 test eax, eax 때문에)

여기서 eax의 값은 0x004010C3에서 호출되는 easy_crackme.401150 의 return 값과 같게 된다. 그렇기 때문에 호출되는 함수가 어떤 결과를 반환하는지 알아야 한다. 이를 위해 우선 인자로 들어가는 값을 보자. 함수가 호출되기 직전에 스택에 push 되는 두 값이 있다. 하나는 프로그램 내에 하드코딩 되어 있는 문자열 "5y"이고, 다른 하나는 입력한 문자열인 dword ptr ss:[esp+A] 이다. esp+A가 가리키고 있는 값이 무엇인지 확인하기 위해 콜스택을 확인해도 되지만 이번에는 이 값이 ecx에 들어있으므로, ecx에 저장된 값을 통해 확인한다.

그러면, 그 값이 "aa"임을 알 수 있다. 그러나 앞서 테스트값 4글자가 모두 a 였으므로, 어느 자리의 a를 가리키는지 모호하여 서로 다른 글자를 가지는 테스트데이터 "!abc"를 사용하겠다.

이를 사용하여 다시 확인한 결과, 세번째와 네번째 자리의 문자인 "bc"가 ecx의 값이 되는 것을 알 수 있다. 

easy_crackme.401150 함수의 심볼이 혹시나 있는지 보기 위해 IDA를 사용하여 이 함수가 위치한 0x004010C3 주소로 이동하면 문자열의 일치 여부를 확인하는 함수인 strncmp임을 알 수 있다. 따라서 앞서 사용된 두 매개변수와 함께 고려하여 생각해볼 경우, 두 번째 분기문의 조건은 입력된 비밀번호의 3번째와 4번째 문자가 "5y"와 같아야만 함을 나타내는 것을 알 수 있다.

이제까지 알아낸 정보를 가지고 조합한 패스워드는 _a5y__ 이다. 이를 고려하여 !a5yasdf 라는 테스트데이터로 다시 이어서 테스트를 하였다.

이후 3번째 만나는 구간부터는 하드코딩 되어 있는 R3versing 이라는 문자열과 입력된 문자열 중 5번째에 위치한 문자열 전체를 한글자씩 비교하여, 같은지 아닌지 살핀다. 언제라도 다른 문자열을 발견할 경우 실패 지점으로 분기된다. 그렇기 때문에 5번째부터는 R3versing 이라는 문자열을 입력하는 것이 실패로 가지 않는 길이다.

 

현재까지 조합된 패스워드는 _a5yR3versing 이다. 첫번째 자리의 문자가 미정인 상태이다. 이를 확정짓기 위해서는 네번째 분기 지점인 0x00401112를 확인하면 된다.

그리고 이 곳에서 첫번째 자리 문자를 가리키는 esp+4의 값이 45('E')와 같은지 비교한다. 이것으로 첫번째 자리 문자가 'E'임을 알 수 있다.

 

결과적으로, 이것들을 조합한 패스워드인 Ea5yR3versing을 입력하면 다음과 같은 축하 메세지를 얻을 수 있다.

 

문제 파일로는 jpg 포멧의 사진 하나를 준다.

사진을 다운받아 열면 아래와 같은 사진을 볼 수 있다.

 

 

여기서 플래그를 찾아야되는건데..
자세히 보면, 가운데 무슨 글씨가 보인다.. jump..???

 

 

그냥 단순히 사진 확대를 해도 뭔가가 더 보이기는 하는데.. 여전히 확실하게 보기는 힘들다...

그러다 알게된 툴이 Forensically 인데, 온라인 이미지 포렌식 툴이라고 한다.

이 사이트에 접속한 후 파일을 오픈하고 돋보기 기능(Magnifier)을 사용하면 아래와 같이 플래그를 볼 수 있다.

 

 

+ 여기에서 돋보기 기능과 함께 Level Sweep도 적용하니 색상 구분이 좀 더 명확하여 구분하기 용이했다.

 

주어진 문제파일에서 Mr.X가 수행한 포트 스캔 방식이 어떤 것인지 찾는 문제이다.

문제를 읽어보면 포트 스캔 방식의 종류로 6가지가 있음을 알 수 있는데, 각각의 유형이 가리키는 스캔 방식은 다음과 같다.

1. TCP SYN scan (half-open scan)
로그가 남지 않도록 할 때 쓰는 스텔스 스캔 방식 중 하나이다.
TCP 핸드셰이킹 과정의 첫번째 단계인 SYN 패킷만 보낸 다음 이에 대한 ACK 패킷을 받는다. 대신 TCP connection이 확립되면 안되기 때문에 포트가 열려있다고 판단될 경우 RST 패킷을 보내고, 닫혀있다고 판단될 경우 응답하지 않고 멈춘다.

2. TCP ACK scan
ACK 패킷만 먼저 보내고 이에 대한 응답 패킷을 검사하는 방식이다.
포트 스캔을 위한 것이 아닌 방화벽에 대한 검사를 진행하기 위한 방식이다.
ACK 패킷에 대한 응답으로 RST 패킷을 받는 경우 방화벽에 의한 필터링이 되지 않고 있는 것을 판단할 수 있고,
응답이 없거나 ICMP 메세지를 받게 될 경우 방화벽에 의한 필터링이 수행되고 있다고 판단할 수 있다.

3. UDP scan
UDP 프로토콜의 전송 방식과 같이 핸드셰이킹 과정을 사용하지 않는다.
대신 닫힌 포트로 UDP 패킷을 보냈을 때 서버로부터 ICMP 메세지를 받고, 열린 포트로 보냈을 경우에는 응답이 없다는 것을 이용한다.
결론적으로 UDP 패킷을 보내고 서버로부터 응답이 없을 경우 열린 포트, ICMP 메세지를 받을 경우에는 닫힌 포트라고 인식한다.

4. TCP Connect scan
일반적으로 TCP Connection을 확립할 때 일어나는 3-Way 핸드셰이킹 과정을 거친다. 그 후 정상적으로 핸드셰이킹이 완료되었다면 포트가 열려있는 것으로 판단하고, 그렇지 않으면 닫혀있는 것으로 판단한다.

5. TCP Xmas scan
TCP SYN scan 방식과 함께, 로그가 남지 않도록 할 때 쓰는 스텔스 스캔 방식 중 하나이다.
동시에 여러 플래그가 설정된 패킷을 보내서 응답이 없을 경우 열려있다고 판단하고, RST 패킷이 올 경우 닫혀있다고 판단한다.
물론 응답이 없을 경우 무조건 포트가 열려있는 것이 아닌 방화벽에 의해 필터링되어졌을 수 있다.

6. TCP RST scan
이건 뭔지 모르겠다...

 

이 내용을 바탕으로 문제 파일을 살펴보면..
첫 번째로 수행한 포트 스캔 방식을 찾기 위해 맨 처음에 등장한 TCP 핸드셰이킹 과정을 살펴봤다.

 

 

호스트 IP가 10.42.42.253이라는 것을 참고하면, 여기서 제일 처음으로 포트 스캔을 한 곳의 목적지 IP는 10.42.42.50이고, 80번 포트에 대한 포트 스캔이 진행됐다.

 

 

이 패킷의 tcp stream을 따라가보면 SYN - RST/ACK, 이렇게 두 개의 패킷이 송수신되고 있는 것을 볼 수 있는데, 이는 TCP Connect 스캔 방식을 사용했을 때 닫힌 포트임을 판단할 수 있는 모습이다.

+ Recent posts