RAG 시작

 

먼저 가장 중요한 것은 데이터입니다. 내가 원하는 답변을 얻기 위해서는 결국 데이터가 필요하고 이러한 데이터들을 전처리하고 가져와야합니다.

이러한 과정중 이번 포스트에서는 가져오는 부분을 다루도록 하겠습니다.

 

필요한 데이터는 다음과 같습니다.

index.txt
0.00MB
sample.csv
0.01MB
SK_sample.pdf
9.39MB

 

 

RAG 기능을 추가하기 위해 한가지 프레임워크에 집중합니다(LangChain, Llamaindex, 등)

여기선 LanChain위주로 다루도록 하겠습니다.

 

(1) WebBaseLoader

해당 모듈로는 웹 페이지의 모든 텍스트를 HTML 다운스트림에서 사용할 수 있는 문서 형식으로 로드됩니다.

먼저 다음과 같이 설치를 진행합니다. (필자는 가상환경에서 진행하였습니다.) -> python 3.11.9

LangChain이 2024.09.16 업데이트가 진행되면서 파이썬 버전은 3.8은 10월부터 지원하지 않음으로 그냥 무조건 3.11 버전에서 진행하는 것을 권장합니다.

pip install -qU langchain_community beautifulsoup4

 

다음 사진과 같이 진행을 하였습니다.

from langchain_community.document_loaders import WebBaseLoader

loader = WebBaseLoader(["https://blog.naver.com/ikm1110", "https://foxforensic.tistory.com/45"])
loader.requests_kwargs = {'verify':False} #SSL 검증 오류 우회하려면 True

docs = loader.load()
print(docs[1]) #첫 번째 docs
print(docs[1].metadata) #첫 번째 docs의 메타데이터

 

위와 같이 작성을 해주고 실행을 한 결과는 다음과 같습니다.

 

(2) Text Loader

가장 간단한 텍스트를 로드 하는 방법은 다음과 같습니다.

from langchain_community.document_loaders import TextLoader

loader = TextLoader("./index.txt", autodetect_encoding=True)
docs = loader.load()

print(docs)

위 코드는 ./index.txt를 로드 하는데

autodetect_encoding을 true로 함으로써 자동으로 인코딩을 탐지할 수 있도록 해줍니다.

다음은 결과 사진입니다.

(3) CSV Loader

CSV로더는 간단하게 다음과 같이 작성할 수 있습니다.

from langchain_community.document_loaders.csv_loader import CSVLoader

loader = CSVLoader(file_path='sample.csv', autodetect_encoding=True)
data = loader.load()

print(data)

 

 

(4) PDF Loader

PDF 로더는 다양한 방식으로 로드하는 방식들이 존재하는데 여기선 전통적인 PDF 로더 기능을 사용하겠습니다.

pip install -q pypdf
from langchain_community.document_loaders import PyPDFLoader

pdf_filepath = 'SK_sample.pdf'
loader = PyPDFLoader(pdf_filepath)
pages = loader.load()

print(pages)

다음과 같은 결과를 얻을 수 있습니다.

로더(Loader) 마무리

 

이러한 다양하게 불러들이는 것은 직접 코드를 짜서 만들어도 되지만
Langchain, Llamaindex 등 프레임워크를 사용하는 것을 추천드립니다.
그 이유는 랭체인, 라마인덱스에서 제공해주는 다양한 도구들(모듈이나 알고리즘)이 처리하기 쉬운 형태로 변환해주기 때문입니다.

 

 

 

 

 

Oracle 설치 방법

 

1. Oracle XE 설치

2. Oracle sql developer 설치

 

무조건 XE 먼저 설치하고 <- 이게 메인 데이터 베이스

oracle sql developer 설치 해야한다. <- 이게 GUI 환경으로 편하게 볼 수 있는 도구라고 생각하자

 

------------------------------------------------------------------------------------------------------------------------------------------

이제부터 진짜다

 

0. Oracle XE 설치 오류

1. 네트워크 어댑터 오류

2. ORA-12505

총 2가지 오류로 나를 괴롭힌다.

 

 

먼저 간단하게 해결하는 방법은 다음과 같습니다.

listener.ora 에 있는 호스트: localhost -> 본인 내부 IP로 수정

같은 경로에 존재하는

tnsnames.ora 역시 HOST = localhost -> 본인 내부 IP로 수정

 

SID는 XE 대문자로 되어 있지만 sql developer에서 접속할 때 소문자로 해도 상관 없다. 삽질 하지 말자

 

-----------------------------------------------------------------------------------------------------------------------------------------------

0번 오류 해결부터 본격적으로 살펴보자

설치 중간에 뜨는 설치 오류는 이미 한번 설치해서 그런 오류일 수 있다.

따라서

C:\app\본인\product\ 을 삭제하고 재부팅 하고 다시 재설치 해보자

 

1번 오류는 천천히 살펴보겠습니다.

먼저 service 윈도우 검색창에 서비스에 들어가면 다음과 같이 오라클 서비스들이 나옵니다.

절.대.핵.심

위 두가지 서비스가 핵심중에 핵심이라 둘다 꺼져 있다면 절대 접속할 수 없습니다.

 

먼저 해당오류를 해결해주기 위해서 다음과 같은 경로로 가줍니다.

C:\app\honggilldong\product\21c\homes\OraDB21Home2\network\admin

빨간 밑줄친 파일 두개를 메모장으로 편집을 눌러서 확인해줍니다.

 

다음과 같이 내부 IP를 수정해주면 됩니다. 자신의 내부 아이피 확인 방법은

Windows라면 ipconfig 리눅스 계열이라면 ifconfig로 확인해보시면 됩니다.

내 내부 IP 확인

 

해당 IP를 가지고 listerner.ora 파일에 들어가서(메모장 편집) 해서 다음과 같이 수정합니다. 해당 파일을 쉽게 찾는 방법은 everything 앱을 사용해서 찾는 것을 추천합니다.

listerner.ora

여기서 PORT는 1522로 수정할 필요 없습니다.기본값이 1521임으로 그냥 1521로 두어도 상관없습니다.

 

다음은 tnsnames.ora 파일에서 다음과 같이 수정을 해주면 됩니다. xe 부분이 바로 중요한 SID 부분입니다.

 

위 두가지 설정을 완료 했다면

TNSListener

OracleServiceXE

위 두가지 서비스를 재시작을 해주면 해결됩니다.

 

2번 오류는 위 서비스를 재시작하면 해결이 됩니다.

 

 

오라클 말고 Mysql 추천드립니다.

 

 

 

 

 

 

 

 

 

 

기본적으로 패킷을 분석하기 전에

패킷을 캡처하고 해당 캡처본을 확인한다.

 

1. 우선 http로 필터링을 한다.

2. 분석하려는 패킷을 follow로 tcp stream 한다.

3. 패킷을 분석한다.

 

http.response.code == 200

를 할 경우 응답 코드가 200인 패킷들만 필터링 해서 가져오기 때문에 패킷에서 분석을 할 때 보내는 것은 있지만 어떠한 응답이 왔는지 확인하기 위해서 필터링을 해줄 수 있다.

 

파일을 주고 받는 http 리퀘스트와 응답을 확인할 수 있다. dpkt를 이용해서 원하는 패킷만 따로 분류할 수도 있다.

 

https://apackets.com/

 

📊 A-Packets: Online PCAP Analysis and Network Traffic Insights

Unlock PCAP analysis with A-Packets. Analyze PCAP files, explore network traffic, extract passwords, and gain insights into HTTP, SMB, DNS, and SSL/TLS protocols.

apackets.com

이 사이트를 이용해 패킷을 분석할 수도 있다 그 대신에 해당 파일 정보가 해당 사이트로 넘어가기 때문에 이를 주의하고 사용하면 된다.

 

 

 

scapy 사용시에는 반드시 IDA를 관리자 권한으로 실행할 것


오류 발견

처음 오류는

WinPcap을 설치하지 않았다고 해서 설치하려는데 다음과 같은 오류 발생

 

 

이를 찾아보니까 Windows 10부터 지원하지 않는다고 공식 사이트에서 나와있어서 최신 Npcap을 설치 하고 실행해보니 다음과 같이 오류 발생

 

 

이 오류는 winpcap이 설치되어 있지 않다고 나와 있는데 (winpcap is not installed) Npcap이 제대로 설치가 안되었거나 무슨 문제가 있는 것이 분명하다고 생각했고 천천히 와이어샤크 Windows ARM 버전용으로 설치를 진행하였다. (MAC OS apple silicon, windows 11)

Npcap의 최신 버전인 1.79버전이 아닌 1.78이 자동으로 설치되도록 나와있어서 1.78로 설치를 진행함

 

이후에도 같은 에러가 나타남


문제 원인

문제의 원인은 IDA와 NPCAP이 아닌 Python에 문제가 있었다.

https://bugs.python.org/issue41100

 

Issue 41100: Support macOS 11 and Apple Silicon Macs - Python tracker

Issue41100 Created on 2020-06-24 11:51 by ronaldoussoren, last changed 2022-04-11 14:59 by admin. This issue is now closed. File name Uploaded Description Edit build.log harlantc, 2021-04-15 15:38 build log for ARM M1 Big Sur URL Status Linked Edit PR 2111

bugs.python.org

위 사이트에서 해당 오류를 확인해 볼 수 있는데 요약하자면

애플 실리콘 아키텍처에서 3.10, 3.9, 3.8 버전의 파이썬을 사용하면 라이브러리를 제대로 가져오지 못하는 문제가 발생(컴파일 오류 였다.)

즉 파이썬을 3.11 이상인 최신버전을 이용하면 해결이 되는 문제였다.

따로 윈도우 데스크탑에서 똑같은 환경으로 테스트 해보니 정상 작동이 되었다.

 

그럼 애플 실리콘 윈도우에선 안되는 걸까?

 


해결 방법

IDA Pro 7.6버전은 공식적으로 3.9.0~1 버전까지만 지원된다.

1. IDA Pro 7.6은 3.9.1까지만 지원하여 파이썬 버전을 올릴 수 없으니 IDA Pro 버전을 올리면 된다. IDA Pro 올리면 자연스레 Python도 최신 버전을 설치하게 된다.

2. 그냥 인텔 아키텍처 사용 -> 너무 간단하지만 확실하다

3. 공유? 라이브러리 설정 <- 이부분은 저도 잘 모르겠습니다. 1번과 2번으로 원만한 합의 보시길..

 

 

 

 

 

 

 

추가적으로 해결 방법이 존재하신다면 피드백 주시면 감사하겠습니다.

 

 

 

 

 

문제 설명

FIXFIXFIX! FFFAAATTT!

 

 

문제 풀이 1.

문제 설명에서는 FFFAAATTT를 고쳐라 라는 뜻으로 볼 수 있겠다. 우선 문제파일을 다운 받으면

FFFFAAAATTTT 파일이 나오게 된다.

 

우선 HXD로 열었을 때 다음과 같이 나왔다.

첫 이미지

FIX the disk라고 디스크를 고치라는 이야기 인것 같다.

고치기 위해서 파일시스템이 무엇인지 알아야 하기 때문에 다음과 같이 찾아낼 수 있었다.

FAT32

FAT32라는 것을 알 수 있었고 이 파일 시스템에서는 6번째 섹터가 복구 섹터라는 것을 알아낼 수 있었고 해당 섹터를 FIX the disk 부분 즉 부팅 영역에 붙이고 이미지 파일을 FTK imager로 열어 보았습니다.

 

위처럼 Dreamhack 폴더가 존재해서 들어가 보았더니 위처럼 파일이 존재했습니다.

zip파일 안에는 flag 파일이 존재 했지만 비밀번호가 걸려있어서 내용을 확인해볼 수 없었습니다.

비밀번호를 알아내면 flag를 얻어낼 수 있을 것 같다고 생각했습니다.

모든 파일을 다 확인해본 결과 GG.PNG파일을 텍스트로 열어보니 다음과 같이 나왔습니다.

비밀번호를 알아낼 수 있었고 이를 이용해 zip파일을 열어봐서 다음과 같이 플래그를 획득할 수 있었습니다.

이제 돌아가서 FTK imager를 사용하지 않고 해결하는 방법은 다음과 같습니다.

 

문제풀이 2.

zip key를 다음과 같이 알아낼 수 있고

zip 파일을 가져오기 위해서 시그니처를 이용해서 가져옵니다. 모든 zip파일을 가져 와서 압축 해제 해보면 됩니다.

시그니처는 다음과 같습니다.

50 4B 03 04

P  K 
 ZIP

해당 zip 부분을 전부 가져와서 임의의 파일을 생성해 빈 영역에 그대로 복사 붙혀넣고 .zip으로 만들고 압축해제를 하면 똑같이 풀이해낼 수 있었습니다.

0. 문제 지문

Do you know "Windows Search" with (windows + s) command?

Find the flag.txt!

 

Windows Search와 windows + s 커맨드를 아냐고 묻고 flag.txt을 찾으라고 하는 내용입니다.

 

1. 문제 풀이

windows.edb 파일

 

우선 Windows Search 란 윈도우 버튼을 눌렀을 때 나오는 검색화면을 지원하기 위해

운영체제에서 파일 시스템 전체를 인덱싱하는  기능입니다.

 

그렇다면 .edb 파일은 해당 데이터들을 모아둔 데이터들의 집합체 라고 생각해낼 수 있었습니다.

해당 파일을 열어주기 위해

WinSearchDBAnalyzer 도구를 이용해 다음과 같이 풀 수 있었습니다.

 

Desktop -> flag.txt 존재

 

플래그 값

 

 

 

mssecsvc.exe 파일 대상으로 진행

 

 

socket 예제

import idautils
import idc
import re
import socket #도메인을 IP로 가져오기 위한 모듈 선언

def find_network_iocs():
    """
    전체 바이너리에서 네트워크 관련 IOC를 찾아 출력합니다. 이에는 IP 주소와 도메인 이름이 포함됩니다.
    """
    ip_pattern = re.compile(r'\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b') #IP관련 요소 추출 정규식 표현 패턴
    domain_pattern = re.compile(r'\b(?:http?:\/\/)?(?:www\.)?([a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*\.(com|net|org|info|biz|gov|edu))\b')
    #도메인 http:www.a-z.com혹은 net,org 추출인데 http, www 부분은 있으면 추출되고 없어도 뒤에 패턴으로 추출하는 것
    print("네트워크 IOC 추출:")

    for seg in idautils.Segments(): #세그먼트 전체 순회하기 위한 for 문
        for head in idautils.Heads(idc.get_segm_start(seg), idc.get_segm_end(seg)): #첫 번째 부터 마지막까지 순회
            disasm = idc.GetDisasm(head)                 #해당하는 명령어나 메모리 주소를 디스어셈블 결과를 disasm에 저장
            ip_matches = ip_pattern.findall(disasm)      # ip 패턴을 findall로 다 찾는다 disasm에서 그 결과를 ip_matches에 저장
            domain_matches = [match[0] for match in domain_pattern.findall(disasm)]
            #findall로 튜플형태로 반환하는데 전체 도메인 형식만을 추출하기 위해서 match[0]을 함
            #반환 되는 값이 idnsajn.com, com 으로 반환 되기 때문이다.

            if ip_matches or domain_matches:   #도메인 이나 IP 가 있다면 for
                print(f"명령어 주소: {hex(head)}")
                if ip_matches:
                    print(f"  IP 주소: {', '.join(ip_matches)}")
                if domain_matches:
                    print(f"  도메인 주소: {', '.join(domain_matches)}")
                    for domain in domain_matches:   # 도메인 인 경우에 IP를 가져오기 위한 반복
                        try:
                            ip_address = socket.gethostbyname(domain)
                            print(f"    도메인으로부터 얻은 IP 주소: {ip_address}")
                        except socket.gaierror:
                            print(f"    해당 도메인에는 IP주소가 존재하지 않습니다.: {domain}")

if __name__ == "__main__":
    find_network_iocs()

socket 핵심은 gethostbyname함수로 해당 함수 내에 도메인 문자열을 넣어주면 IP주소로 반환해줍니다.

이 코드 예제에서는 domain에 해당하는 도메인 주소가 담겨있기 때문에 domain을 넣어주었습니다.

자세한 코드 분석은 코드에 달아두었습니다.

 

실행 결과는 다음과 같습니다.

해당 도메인에 대응되는 IP 주소를 획득할 수 있습니다.

 

 

whois 모듈

socket 예제에서 다음과 같이 수정 해주면 됩니다.

try:
    domain_info = whois.whois(domain)
    print(f"    도메인 WHOIS 정보: {domain_info}")
except Exception as e:
    print(f"    WHOIS 조회 실패: {e}")

다음과 같이 결과를 확인할 수 있습니다.

whois 사이트는 다음과 같습니다.

https://whois.domaintools.com/

 

Whois Lookup, Domain Availability & IP Search - DomainTools

 

whois.domaintools.com

 

 

 

 

 

 

참조 :

https://wikidocs.net/4308#mn

 

08-2 정규 표현식 시작하기

정규 표현식에서는 메타 문자(meta characters)를 사용한다. 먼저 메타 문자가 무엇인지 알아보자. [TOC] ## 정규 표현식의 기초, 메타 문자 메타 문자란 원…

wikidocs.net

https://hotel-iu.tistory.com/321

 

파이썬 python 정규표현식 (정규식) 문자열 추출 예제 정리

파이썬 python 정규표현식 (정규식) 문자열 추출 예제 정리 Python에서 정규 표현식은 re 모듈에서 지원됩니다. 파이썬에서 정규 표현식을 사용하려면 먼저 import re를 사용하여 re 모듈을 가져와야 합

hotel-iu.tistory.com

https://whois.domaintools.com/

 

Whois Lookup, Domain Availability & IP Search - DomainTools

 

whois.domaintools.com

 

0. 지문

드림이 : 우와! 밖에 눈이 많이와요!
드림맘 : 그렇네~
드림이 : 거의 모두 하얀공간뿐이네요.

 

1. 문제 풀이

파일을 다운 받으면 DH 디렉터리와 그 안에

flag.txt, Snow.jpeg를 확인해볼 수 있었다.

 

우선 flag.txt를 먼저 확인해 본 결과 다음과 같이 나온다.

그런데 뭔가 커서의 위치가 이상한데로 가져 있는 것을 확인할 수 있었고 자세히 확인해보기 위해 HXD로 확인해보았다.

어... 눈을 표현한 것 같다.

일단 단서는 이게 전부임으로 Snow.jpeg도 살펴 보았다.

어떠한 정보도 획득할 수 없었다.

 

일단 스테가노그래피가 사용되었을 것으로 추측을 해볼 수가 있는데 문제는 어떠한 방식으로 스테가노그래피가 적용이 되어 있는지 확인하기가 어렵다.

따라서 사진파일은 우선 제쳐두고 flag.txt 파일 내에서 이상하게 굳이 점으로 눈을 표현할 필요가 있었을까 라는 생각이 들었다.

 

혹시 몰라 snow 스테가노 그래피를 검색해보니

snow 관련 스테가노그래피 툴이 나오게 되었다.

https://darkside.com.au/snow/index.html

이곳에서 설치할 수 있고

 

Snow.exe -C 실행 파일

이렇게 해주면 된다는 것 같다.

 

.jpeg를 곧장 넣어보았다. 아무런 일이 일어나지 않았다.

하지만 flag.txt를 넣어보니

정답이 나오게 되었다.

 

0. 문제 지문 읽기

문제 설명에는 다음과 같이 작성되어 있습니다.

Someone deleted the PDF file which has flag!

How can I recover it?

 

플래그가 담겨있는 PDF파일이 삭제 되었다고 합니다. 이를 복구 해달라고 합니다.

 

 

1. 문제 풀이

문제 파일을 다운로드 받습니다.

Image.E01 파일

sha256 : 36c6d523ed44e2be02dbfebb2369154125ebc6775952c947dff9e89efbc105ca

SHA1: cb75da360c5bf93756119f11a159744f6cc60fb9

 

확장자가 E01파일입니다. 이는 Encase Forensic Image 포렌식 이미지 포맷 형식임으로 유명한 도구 FTK Imager로 열어보도록 하겠습니다.

 

다음 사진은 FTK Imager로 확인한 결과 입니다.

위 사진에서 가장 눈에 띄는 것은 이전 글에도 올린 unallocated space 입니다. 비할당 영역을 살펴보자 다음 사진처럼 나왔습니다.

아직까진 무엇을 의미하는지 잘 모르겠지만 파일의 크기가 적당히 있다 정도만 알 수 있는 것 같습니다.

다음 사진은 root에서 삭제된 파일만 확인해본 결과를 캡처해온 사진입니다. seg1, seg2, seg3, seg4가 삭제되었다 라는 것을 확인해 볼 수 있었습니다.

위 두 사진과 공통점을 하나 발견할 수 있었는데 그것은 파일의 크기입니다. 현재 저 삭제된 파일을 눌러보면 아무것도 뜨지 않지만 비할당 영역에서 똑같은 사이즈를 클릭해보면 정보를 확인해 볼 수 있었습니다.

그렇다면 비할당 영역에 있는 것은 아직 덮어써져 있지 않기를 바라면서 위의 오른쪽 사진 정보를 확인해보면 PDF파일이라는 것을 확인할 수가 있었습니다. 우선 seg1파일을 pdf확장자로 변환 해주고 복구가 되었는지 확인해보았습니다.

이게 정답이 아니였다는 것을 알 수 있었습니다.

그럼 어떤식으로 풀이를 해야 정확하게 답을 얻어낼 수 있을까 생각했고 유명한 NTFS Log Tracker 도구로 파일이 어떻게 삭제 되었는지 확인을 해볼 필요가 있다고 생각했습니다.

FTK Imager 에서 $J, $LogFile, $MFT 를 export 해주고 파서를 진행하였습니다.

 

당연히 제일 먼저 seg1이 생성되었는지부터 확인해본 결과 다음 사진과 같이 나오게 되었습니다.

2067(12)가 의미하는 바는 seg1 파일이 2067번 클러스터부터 12개 클러스터 영역에 생성된 것을 의미합니다.

다음 사진은 seg2를 살펴보았고 마찬가지로 3405번 클러스터 13개 영역에 생성

다음 사진은 seg3이고 4466 클러스터 부터 14개 영역에 생성

다음 사진은 seg4이고 5082 클러스터 영역부터 18개 영역에 생성

 

그 다음으로는 seg4, seg1, seg2, seg3 가 삭제 된 것을 볼 수 있습니다.

 

 

위의 내용을 아래와 같이 정리할 수 있습니다,

- seg1 : 2067 => 0x813, 12(0xC) 영역3

- seg2 : 3405 => 0xD4D, 13(0xD) 영역

- seg3 : 4466 => 0x1172, 14(0xE) 영역

- seg4 : 5082 => 0x13DA, 18(0x12) 영역

위와 같이 seg1 ~ seg4의 각각의 시작 영역을 섹터로 HXD를 이용해 image.E01을 직접 확인해보면 다음과 같습니다.

 

 

따라서 seg1~seg4 순서대로 파일을 합쳐주면 다음과 같이 플래그가 담긴 PDF파일을 복구할 수 있습니다.

 

산타 옆에 크게 flag 값

 

1. 간단한 인터프리터 예제

2. 간단한 실제 사용 예제

 

 

1. 간단한 인터프리터 예제

1.1 현재 위치 주소

1.2 최소 최대 주소

 

1.1 here() : 현재 위치의 주소를 리턴한다.(현재 커서에 있는 위치)

hex(here())
here()

 

1.2 idc.get_inf_attr(idc.INF_최대,최소_EA) : IDA 데이터 베이스에서 바이너리의 전체 범위에 대한 최대와 최소 주소값 반환

idc.get_inf_attr(idc.INF_MIN_EA)
idc.get_inf_attr(idc.INF_MAX_EA)

 

 

2. 간단한 실제 사용 예제

2.1 세그먼트별 주소 출력 예제

2.2 함수 목록 출력 예제

2.3 전체 명령어 추출 스크립트 예제

2.4 전체 주석 추출 스크립트 예제

2.5 IP 주소와 도메인 이름 추출 예제

 

2.1 세그먼트별 주소 출력 예제

# 세그먼트의 개수와 세부 정보를 출력
for n in range(idaapi.get_segm_qty()):
    seg = idaapi.getnseg(n)  # n번째 세그먼트 정보를 가져옴
    if seg:
            # 세그먼트 이름, 시작 주소, 끝 주소를 가져와서 출력
        segname = idc.get_segm_name(seg.start_ea)
        start_address = seg.start_ea
        end_address = seg.end_ea
        print(f"Segment Name: {segname}, Start: {hex(start_address)}, End:{hex(end_address)}")

 

2.2 함수 목록 출력 예제

import idautils

def print_functions():
    # 모든 함수들을 순회
    for func in idautils.Functions():
        # 함수의 시작 주소를 가져옴
        start_address = func
        # 함수의 이름을 가져옴
        func_name = ida_funcs.get_func_name(start_address)
        
        # 함수의 시작 주소와 이름을 출력
        print(f"Function Name: {func_name}, Start Address: {hex(start_address)}")

if __name__ == "__main__":
    print_functions()

 

 

2.3 전체 명령어 추출 스크립트 예제

import idautils
import idc

def find_instructions_with_comments(keyword):
    """
    전체 바이너리에서 특정 명령어를 포함하는 코드를 찾아 그 코드의 주소, 명령어, 주석을 출력합니다.
    :param keyword: 검색할 명령어 키워드
    """
    print(f"Searching for instructions containing '{keyword}':")
    print("-" * 50)
    for seg in idautils.Segments():
        for head in idautils.Heads(idc.get_segm_start(seg), idc.get_segm_end(seg)):
            disasm = idc.GetDisasm(head)
            if keyword in disasm:
                # 명령어에 키워드가 포함되어 있는 경우
                comment = idc.get_cmt(head, 0)  # 일반 주석
                rcomment = idc.get_cmt(head, 1) # 반복 주석
                print(f"Address: {hex(head)} - Instruction: {disasm}")
                if comment:
                    print(f"  Comment: {comment}")
                if rcomment:
                    print(f"  Repeatable Comment: {rcomment}")
                print("-" * 40)

if __name__ == "__main__":
    # 예를 들어, 'call' 명령어를 포함하는 코드를 찾으려면
    find_instructions_with_comments("call")

 

 

2.4 전체 주석 추출 스크립트 예제

import idautils
import idc

def extract_all_comments():
    print("Extracting all comments from the binary:")
    print("-" * 50)
    for seg in idautils.Segments():
        for head in idautils.Heads(idc.get_segm_start(seg), idc.get_segm_end(seg)):
            # 주석 가져오기
            comment = idc.get_cmt(head, 0)  # 일반 주석
            rcomment = idc.get_cmt(head, 1) # 반복 주석
            if comment or rcomment:
                print(f"Address: {hex(head)}")
                if comment:
                    print(f"  Comment: {comment}")
                if rcomment:
                    print(f"  Repeatable Comment: {rcomment}")
                print("-" * 40)

if __name__ == "__main__":
    extract_all_comments()

 

2.5 IP 주소와 도메인 이름 추출 예제

import idautils
import idc
import re

def find_network_iocs():
    """
    전체 바이너리에서 네트워크 관련 IOC를 찾아 출력합니다. 이에는 IP 주소와 도메인 이름이 포함됩니다.
    """
    ip_pattern = re.compile(r'\b(?:\d{1,3}\.){3}\d{1,3}\b')
    domain_pattern = re.compile(r'\b(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,6}\b')
    print("Searching for Network IOCs (IP Addresses and Domain Names):")
    print("-" * 60)
    for seg in idautils.Segments():
        for head in idautils.Heads(idc.get_segm_start(seg), idc.get_segm_end(seg)):
            disasm = idc.GetDisasm(head)
            comments = idc.get_cmt(head, 0)  # 일반 주석
            rcomments = idc.get_cmt(head, 1) # 반복 주석
            strings = idc.get_strlit_contents(head)
            search_text = f"{disasm} {comments if comments else ''} {rcomments if rcomments else ''} {strings if strings else ''}"

            ip_matches = ip_pattern.findall(search_text)
            domain_matches = domain_pattern.findall(search_text)
            if ip_matches or domain_matches:
                print(f"Address: {hex(head)}")
                if ip_matches:
                    print(f"  IP Addresses: {', '.join(ip_matches)}")
                if domain_matches:
                    print(f"  Domain Names: {', '.join(domain_matches)}")
                print("-" * 60)

if __name__ == "__main__":
    find_network_iocs()

유의미한 정보 추출

 

 

 

 

 

 

 

 

 

 

 

+ Recent posts