Skip to content

Instantly share code, notes, and snippets.

@0xca7
Created December 31, 2023 17:22
Show Gist options
  • Save 0xca7/2411ec5cb8260ab70a917539217b6ea2 to your computer and use it in GitHub Desktop.
Save 0xca7/2411ec5cb8260ab70a917539217b6ea2 to your computer and use it in GitHub Desktop.
"""
crappy python script to extract v o l g m e r configuration
see: https://asec.ahnlab.com/en/57685/
1. pull the full resource section
2. search for ZIP magic, cut everything before
3. get all strings from the binary, one is the password
4. try all the strings until the zip is decrypted
5. search for the smaller of the two extracted files, this is the config
6. parse the config and spew out ip addresses and ports
"""
import os
import sys
import pefile
from os import walk
from zipfile import ZipFile
FILEPATH='../eff3e37d0406c818e3430068d90e7ed2f594faa6bb146ab0a1c00a2f4a4809a5'
"""
extract the resource section
"""
def extract_rsrc():
pe = pefile.PE(FILEPATH)
for section in pe.sections:
if b"rsrc" in section.Name:
return section.get_data()
"""
collect strings in the binary
"""
def get_strings():
strings = []
temp = []
with open(FILEPATH, "rb") as f:
data = f.read()
for byte in data:
if byte >= 0x20 and byte <= 0x7e:
temp.append(byte)
else:
if len(temp) > 5:
s = ''.join(chr(e) for e in temp)
strings.append(s)
temp = []
return strings
def main():
# get the resource section and strings
rsrc = extract_rsrc()
strings = get_strings()
# find the zipfile in the resource section
ZIPMAGIC = b"\x50\x4b\x03\x04"
idx = rsrc.find(ZIPMAGIC)
rsrc = rsrc[idx:]
# create the output directory
os.mkdir("out")
# write the zipfile to disk
with open("out/extracted_zip.zip", "wb") as f:
f.write(rsrc)
# now try all of the strings until we find the one that is the ZIP password
with ZipFile("out/extracted_zip.zip") as zf:
for string in strings:
try:
zf.extractall(path="out/", pwd=bytes(string, "utf-8"))
print("extracted with pwd: {}".format(string))
break
except:
pass
# collect the files we extracted
files = []
for (dirpath, dirnames, filenames) in walk("out/"):
files.extend(filenames)
break # need only toplevel
# now find the smallest of the files, which contains the config
MIN_SIZE = sys.maxsize
MIN_FILE = ""
for file in files:
with open("out/" + file, "rb") as f:
size = len(f.read())
if MIN_SIZE > size:
MIN_SIZE = size
MIN_FILE = file
print("smallest file stores the config: {}".format(MIN_FILE))
# decode the config. IP addresses start at offset 0x12
# read 8 bytes at a time, 4 bytes for the IP 4 bytes for the port
#
# (sidenote: a port is at most 0xffff, why store 4 bytes!?
# 2 bytes are wasted)
#
# print all of the IPs and ports (defanged)
with open("out/" + MIN_FILE, "rb") as f:
data = f.read()
data = data[0x12:] # this is where the IPs and ports start
for i in range(0, len(data)-8, 8):
if data[i:i+8] == b'\x00\x00\x00\x00\x00\x00\x00\x00':
break
ip = data[i:i+4]
port = data[i+4:i+8]
print("IP: {}[.]{}.{}.{} Port: {}".format(
ip[0], ip[1], ip[2], ip[3], int(port[0] << 8 | port[1])))
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment