プロジェクト

全般

プロフィール

CTF Crypto » base64_extraction.py

kanata, 2025/04/13 14:35

 
#!/usr/bin/env python
# -*- coding: utf-8 -*-

# base64_extraction.sh ver 0.2
# 引数のファイルに含まれるbase64部分を抽出・デコードしてファイルに保存する
# 第一引数… 入力フィル名
# 第二引数… 指定した数値より短い文字列はBase64の変換対象にしない(default 16)
# 2016.08.06 kanata

import os
import sys
import base64
import commands
import traceback

def write_decorded_base64(decodeed_base64,out_file_base,file_offset):
# write file
try :
file_content=base64.b64decode(decodeed_base64)
except :
#print "Base64 error"
return(1)
file_name=out_file_base[0] + "_" +str(file_offset)
out_fd = open(file_name, 'w+')
out_fd.write(file_content)
out_fd.close()
analysis_file_type(file_name)

def analysis_file_type(file_name):
# detect filename extension & rename
if os.name == "posix":
file_extention=commands.getoutput("file -i "+file_name+"|awk -F'/' '{print $NF}'|awk '{print $1}'|awk -F'-' '{print $NF}'|tr -d ';'")
else:
file_extention="dat"
#print "Debug:"+file_extention
new_file_name = file_name+"."+file_extention
if os.path.exists(new_file_name):
os.remove(new_file_name)
os.rename(file_name, new_file_name)
print "\t"+new_file_name
return(0)

if __name__ == '__main__':
allow_decord_length=16 # The strings length shoter than this number. The strings not base64 target.
file_offset=0
file_content=""
state_base64=False # True:in False:out
i=0 # counter
base64_length=0 # for chek allow_decord_length

if os.name != "posix":
print "[WARNING] I wonder this is not work encode for base64 by my windows7 enviroment. Please compare encoded file content by other ways."

if len(sys.argv) >= 2:
in_file=sys.argv[1]
out_file_base=os.path.splitext(os.path.basename(in_file))
file_size=os.path.getsize(in_file)
else:
print "ex)"+sys.argv[0]+" [filename] [minimum base64 length]"
sys.exit(1)

if len(sys.argv) == 3 and sys.argv[2].isdigit():
allow_decord_length=int(sys.argv[2])

try :
in_fd = open(in_file,'rb')
except :
print "file error"

while 1 :
b = in_fd.read(1)

if b in "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" : # base64対象文字列
state_base64=True
file_content = file_content + b
base64_length=base64_length + 1
elif b in "=":
file_content = file_content + b
elif b in "\n\r":
pass
elif b in "\\":
b = in_fd.read(1)
if b in "n":
pass
# TODO:2count \n are not pass
else:
if state_base64 and base64_length > allow_decord_length:
#print "Debug:"+file_content+" "+str(i)
# ファイル出力処理,ファイル命名処理 #
write_decorded_base64(file_content,out_file_base,i)
state_base64=False
file_content=""
base64_length=0
else:
if state_base64 and base64_length > allow_decord_length:
#print "Debug:"+file_content+" "+str(i)
# ファイル出力処理,ファイル命名処理 #
write_decorded_base64(file_content,out_file_base,i)
state_base64=False
file_content=""
base64_length=0
sys.stdout.write("\rchecking..."+str(i)+"/"+str(file_size))
sys.stdout.flush()
i = i + 1

if i > file_size:
break
in_fd.close()
sys.stdout.write("\r")
sys.stdout.flush()

    (1-1/1)