matrix-fuzz

git clone git://archive.git.mtrnord.blog/MTRNord/matrix-fuzz.git
Log | Files | Refs | README | LICENSE

commit 80139672bea0b9548ac7dfdee54315f4fa6214ff
parent e6f1a4011125086c5bf82cd4953be089aee4debc
Author: MTRNord <mtrnord1@gmail.com>
Date:   Fri, 12 Aug 2022 20:28:19 +0200

Add basic afl target

Diffstat:
M.gitignore | 5+++--
MCargo.toml | 10+++++++++-
MREADME.md | 24++++++++++++++++++++++--
Aafl/createRoom/in/1 | 2++
Aafl/createRoom/in/2 | 2++
Aafl/createRoom/in/3 | 2++
Aafl/createRoom/in/4 | 2++
Aafl/createRoom/in/5 | 2++
Aafl/createRoom/in/6 | 2++
Aafl/createRoom/in/7 | 2++
Asrc/fuzzTargets/createRoom.rs | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/lib.rs | 16++++++++--------
Msrc/types/create_room.rs | 11++++++-----
13 files changed, 125 insertions(+), 18 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -4,4 +4,5 @@ notes.md src/secrets.rs /fuzz /meep.rs -/weird_ones/security_issues -\ No newline at end of file +/weird_ones/security_issues +/afl/*/out/* +\ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml @@ -3,9 +3,17 @@ edition = "2021" name = "matrix-fuzz" version = "0.1.0" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +name = "matrix_fuzz" +path = "src/lib.rs" + +[[bin]] +name = "createRoom" +path = "src/fuzzTargets/createRoom.rs" [dependencies] +afl = "*" +arbitrary = {version = "1", features = ["derive"]} fuzzcheck = {git = "https://github.com/MTRNord/fuzzcheck-rs.git", branch = "patch-1"} once_cell = "1.13.0" reqwest = {version = "0.11.11", features = ["blocking", "json", "gzip"]} diff --git a/README.md b/README.md @@ -8,9 +8,9 @@ Matrix fuzzing is a dumb fuzzer fuzzing a few matrix endpoints. It requires a HS # Current targets -- `/_matrix/client/v3/createRoom` - `tests::tests::fuzz_create_room` +- `/_matrix/client/v3/createRoom` - `tests::tests::fuzz_create_room` - `createRoom` -# Usage +# Usage of fuzzcheck-rs 1. Create a HS 1. Setup a user @@ -29,6 +29,26 @@ Matrix fuzzing is a dumb fuzzer fuzzing a few matrix endpoints. It requires a HS 1. Verify the error by trying the output json yourself 1. Please make sure to follow https://matrix.org/security-disclosure-policy/ for found errors instead of posting them in public unless you are 100% sure they are not a security issue. If you are in doubt prefer the security disclosure policy. +# Usage of afl.rs + +1. Create a HS +1. Setup a user +1. Add the secrets to src/secrets.rs. + + Example code: + + ```rust + pub const USERNAME: &str = "@a:localhost"; + pub const PASSWORD: &str = "abc123"; + ``` + +1. Install afl.rs -> `cargo install afl` +1. Run `cargo afl build` +2. Run `cargo afl fuzz -i ./afl/<target>/in -o ./afl/<target>/out ./target/debug/<target>` +3. Wait until it crashes +4. Verification is a little harder. See https://github.com/rust-fuzz/afl.rs/issues/215 on how to reproduce things +5. Please make sure to follow https://matrix.org/security-disclosure-policy/ for found errors instead of posting them in public unless you are 100% sure they are not a security issue. If you are in doubt prefer the security disclosure policy. + # Hall of Explosions (Bugs found) - https://github.com/matrix-org/synapse/issues/13510 diff --git a/afl/createRoom/in/1 b/afl/createRoom/in/1 @@ -0,0 +1 @@ +{"initial_state":[{"content_keys":["","",""],"content_values":["","","",""],"type":"","state_key":""}],"room_version":"","topic":""} +\ No newline at end of file diff --git a/afl/createRoom/in/2 b/afl/createRoom/in/2 @@ -0,0 +1 @@ +{"initial_state":[{"content_keys":["","",""],"content_values":["","","",""],"type":"","state_key":""}],"room_alias_name":"�iy|?i�sY��=b�W\"�R\b���\u001for\n�6']��+䵥�s��\u001e�Q�\t�,fS{��!�\\\bR\u0012I��\u0018���\u0002\u0000�<\u001c0�ߡN\u0005ɺ��7����X��\u001e#,�w���hV��t;\u000eLTC��P\u001c\u000e\u000eV�\u000eΗ[u\u0011���\u0003\u0005���2���(^��\u0003��,_�\u0014���\u0006�$�$\u0011bA\u0002�qrf��L�Sl�%�c�vK�\u001c","room_version":"","topic":""} +\ No newline at end of file diff --git a/afl/createRoom/in/3 b/afl/createRoom/in/3 @@ -0,0 +1 @@ +{"creation_content_keys":["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","��","","","","\u0001","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","\u0003","","","","","","","�","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","\u0002�","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","H","","","","","","�","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","��","","","","","","T�","","","","","","","","","�C","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","j","","","","","","","","�","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","�","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","�","","","","","","","","","","","","","","","","","","","","","�","","","","","","","","","�","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","�2","","","","","","","","","","","","","","","","","","","","","","","","","\u001c","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","�","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","O","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","��","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","�","","","","","","","","","","","","","","","","","","","","","","","","","\u0016","","","","","","","","","","","","","","","","","","","","","","","=","","","","","","","","h�!","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","\u0002","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","\u0006","","","","","","","","","","$","","","�","",""],"creation_content_values":["","","","","","","","","","","","","","","�I4�","","�","","","","","","","","e","","","","","","","","","","","\u001e-H'�","","","�","","\u0018","","","","","","","","�W","","","","","�","","","","","","","","","","","","","","","","b\u0003͊","","�Y","","","","","","","","","","","","","","","","","","","","","","","","\u000b�","","","","","","","","","","","","","","","","","","","","","","","","","","","","","=","","","","","","","","","","","","","","","","","","","","","","","","","","","`","","","","","","","","","",")","\u0003","\u001f","","","","","","�","","","","","","","","%b","","","","","","\u0001k�u","","","","","","","","","",":","","","","","","","","","","","�","","","","\tc�","�?","","","","","","","","","","","","","","","","","","","","�","","","","","","","","","\b","","%","","","","","","","","","","","","","","","","","t","","�","","����","","","","","","","","","�","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","�","*","","","","","","","","","","c","","","","","","�","","","","","","","","�","","","","","","","","","","m","","B","","","","","","","","","","","","","","","","","","","","","","","","","","","","U","","","","","","","","","","�\u0017�","","","","","�","","","})","","","","�","","","","","�2","","","","","","","","","2�","","","","","","","","","","","l","","","","","","","","","",""],"initial_state":[{"content_keys":["","","","",""],"content_values":[],"type":"","state_key":""},{"content_keys":["","","","","","","","","","","","",""],"content_values":["","","","","u","","","","","","","",""],"type":"","state_key":""},{"content_keys":[""],"content_values":["","",""],"type":"","state_key":""},{"content_keys":["","",""],"content_values":[""],"type":"","state_key":""},{"content_keys":["&",""],"content_values":["","","","","",""],"type":"","state_key":""},{"content_keys":["","","",""],"content_values":["","","",""],"type":"","state_key":""},{"content_keys":["","","","","","","","","","","","","","","","","","","","�","","","","","","","","","","","","","","","","","",""],"content_values":[""],"type":"","state_key":""},{"content_keys":[],"content_values":["",""],"type":"","state_key":""},{"content_keys":[],"content_values":["","",""],"type":"","state_key":""},{"content_keys":[],"content_values":[],"type":"","state_key":""},{"content_keys":["",""],"content_values":["","",""],"type":"","state_key":""},{"content_keys":[],"content_values":[""],"type":"","state_key":""},{"content_keys":["","",""],"content_values":[""],"type":"","state_key":""},{"content_keys":[],"content_values":["",""],"type":"","state_key":""},{"content_keys":["","","","","","","","","}","","","","","",""],"content_values":["","","","","","","","","",""],"type":"","state_key":""},{"content_keys":[],"content_values":["","","",""],"type":"","state_key":""},{"content_keys":["",""],"content_values":[""],"type":"","state_key":""},{"content_keys":["",""],"content_values":["",""],"type":"","state_key":""},{"content_keys":["","","",""],"content_values":["","","","",""],"type":"","state_key":""},{"content_keys":["",""],"content_values":["","","","",""],"type":"","state_key":""},{"content_keys":["",""],"content_values":[],"type":"","state_key":""},{"content_keys":[],"content_values":[],"type":"","state_key":""},{"content_keys":["",""],"content_values":[""],"type":"","state_key":""},{"content_keys":["","","","",""],"content_values":["","J","","","","!"],"type":"q","state_key":""},{"content_keys":["",""],"content_values":[""],"type":"","state_key":""},{"content_keys":[""],"content_values":[],"type":"","state_key":""},{"content_keys":["","","","",""],"content_values":["",""],"type":"","state_key":""},{"content_keys":[],"content_values":[],"type":"","state_key":"�"},{"content_keys":[],"content_values":[""],"type":"","state_key":""},{"content_keys":["","","","","",""],"content_values":["","","","","",""],"type":"","state_key":""},{"content_keys":["",""],"content_values":[""],"type":"","state_key":""},{"content_keys":[""],"content_values":[""],"type":"","state_key":""},{"content_keys":[""],"content_values":["",""],"type":"","state_key":""},{"content_keys":["",""],"content_values":[""],"type":"","state_key":""},{"content_keys":[],"content_values":["","","",""],"type":"","state_key":""},{"content_keys":[""],"content_values":[""],"type":"","state_key":"K"},{"content_keys":[""],"content_values":[],"type":"","state_key":""},{"content_keys":[""],"content_values":["","",""],"type":"","state_key":""},{"content_keys":["","","","","",""],"content_values":["","","",""],"type":"","state_key":""},{"content_keys":[""],"content_values":["","","",""],"type":"�","state_key":""},{"content_keys":[],"content_values":[""],"type":"","state_key":""},{"content_keys":[""],"content_values":[],"type":"","state_key":""},{"content_keys":["","","","","","",""],"content_values":[""],"type":"","state_key":""},{"content_keys":[],"content_values":[""],"type":"","state_key":""},{"content_keys":[""],"content_values":["","",""],"type":"","state_key":""},{"content_keys":["","","",""],"content_values":[],"type":"","state_key":""},{"content_keys":[""],"content_values":[""],"type":"","state_key":""},{"content_keys":["",""],"content_values":["","","","~","",""],"type":"","state_key":""},{"content_keys":[""],"content_values":["","",""],"type":"","state_key":""},{"content_keys":["","",""],"content_values":[""],"type":"","state_key":""},{"content_keys":[],"content_values":[],"type":"","state_key":""},{"content_keys":["","","","","","","","",""],"content_values":["","","",""],"type":"","state_key":""},{"content_keys":["","","","","","",""],"content_values":["",""],"type":"","state_key":""},{"content_keys":[],"content_values":["","","","",""],"type":"","state_key":""},{"content_keys":["","",""],"content_values":[],"type":"","state_key":""},{"content_keys":[""],"content_values":[""],"type":"","state_key":""},{"content_keys":[],"content_values":["",""],"type":"","state_key":""},{"content_keys":["","","",""],"content_values":["","","","",""],"type":"","state_key":""},{"content_keys":[],"content_values":[""],"type":"","state_key":""},{"content_keys":[],"content_values":["","",""],"type":"","state_key":"K��"},{"content_keys":[""],"content_values":["","","","","","","","","","","",""],"type":"","state_key":"5"}],"invite":["","�","","","","","","�","","","","","","","","","","","","","","\"","","","","","","","","","�","","","","","","","","","","","","","","","","","","","\u0010\u0019","","","\u0007","","","","","","","","","","","[","","","","","","","","","","","W","","","","","","�","","","","","","","","","","","","","","","","","","","","","","","","","","","","G","","�","","","","","","","","","","","","","","","","�","=��\u001e","","","","","","","","�,","","","","","","","","","","q","","","","","","","","","","","","","","","","","","�*","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","R","","","","","","","","","","�","","","","","","","","","","","","","","","","","","","","","p","","","","","","&","","","","","","","","","","","","","","","","e","\u000e","","�","","","","�","","","�","","","","","","","","","","","","","","","","","l","","","","","","","����ˆ@�","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","\f","","","","","","","","","�","","","","","","�","","","","G","","","","","","","","<","","","","I","","","�","","","","","","","","E\u0003\u0019","","","","","","","","","","","","","l�","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","\u0012","","","","","","","","","","","","","","","","","�","","","","","","","�","","","","","","","","","","","","","","","�","","","","","","","","","","","","","","","","","","","","","","","","","\u0006","","","","","","","","","","","","","\u001a","","","","","","","","","","","","","","","","","�","","","","","","","","","","","","","","","","","","","c","","","","","","","","","","","","","","","","","","","","","","","","","","","","","5fv","","","","","","","","","�","","","","","","","","","","\u0007","","","","","","","","","","","","","","","","","","","","a","","","","","","","","","","","\u0002t\u0012\u001e��3�\u0010����}","","","","","","|","","","","","","","","'","","","","2","�<��","","","","","","","","","","","","","","","","","","�","","","\u001b","","","","","","","�","","","","","","","","","","","","","","","","","<θ\u0015","","","","","","","","","","","","","","","","","","�","","","","","","\u0011y�","","","","R","","�RI���#","","","","�","","","","","","","","","","","","","","","","","","","","","","","","","","","","","I","","","","","","","","","","","","","","","!","","","","","","","","","","","","","","��","","","","","��","","","","","","\u001d","","Y�","","","","","","","","�","","","","","","","","","","","","","","","","","","","*�g","","","A","","","","","","","","","","","","","","","","","","","�","","","\u0010�\r","�","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","�","","","","","","","","","","","","","","","",";","","","","\u0006","","","�","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","\u0015\r|","",""],"room_version":"|","visibility":""} +\ No newline at end of file diff --git a/afl/createRoom/in/4 b/afl/createRoom/in/4 @@ -0,0 +1 @@ +{"room_version":"","topic":"��"} +\ No newline at end of file diff --git a/afl/createRoom/in/5 b/afl/createRoom/in/5 @@ -0,0 +1 @@ +{"room_alias_name":"","room_version":""} +\ No newline at end of file diff --git a/afl/createRoom/in/6 b/afl/createRoom/in/6 @@ -0,0 +1 @@ +{"creation_content_keys":["b","","","","","","","","","","","","","\u0006","","","","","","","","","","","","","","","","","","","","","","","","","�","","","","","","","","","","","","","","","�","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","@","","A\u0010U","","","","","","","","","","","","","","","","","","","","","","_","","","","","","","","","","�","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""],"invite":["","","","","","","","","",""," ","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","�","","","","","","","","","","","","","","","","","","","","","�","","","","","","","","","","","","","","","","","� �","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","�S","�","�g-","","","�","","!","","","","","","","","�","","\u000e","","","","","","","","","","","","","","","","","","Lj","","","","","","","=","","�","","","","","","","","(e","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","�","","","","","",""],"is_direct":true,"name":"�?�jah�\u001a�h�����^�z]ɼ���$:%�t�\u001a��\\m�\u0000$Z���","preset":"�)m,|���b��\u001cNn","room_version":"\u001f"} +\ No newline at end of file diff --git a/afl/createRoom/in/7 b/afl/createRoom/in/7 @@ -0,0 +1 @@ +2�����La\u0002�3�Ԟ9U8�Y��\u001c����Vץʅ�9��K�� �rw}�@R\u0007\u001f�\t����\u000bJ\u000e�d��","room_version":"\u001f"} +\ No newline at end of file diff --git a/src/fuzzTargets/createRoom.rs b/src/fuzzTargets/createRoom.rs @@ -0,0 +1,63 @@ +#![allow(non_snake_case)] +use matrix_fuzz::{client, secrets::ACCESS_TOKEN, types::create_room::CreateRoomMagicJSON}; + +fn main() { + afl::fuzz_nohook!(|data: CreateRoomMagicJSON| { + // FIXME: We probably should set it to null and not do a false positive + // HACK due to https://github.com/matrix-org/synapse/issues/13510 + if let Some(room_alias_name) = &data.room_alias_name { + if room_alias_name.contains('\0') { + return; + } + } + // HACK due to NUL in type or state_key + if let Some(initial_state) = &data.initial_state { + for state in initial_state { + if state._type.contains('\0') { + return; + } + if state.state_key.contains('\0') { + return; + } + } + } + /*// HACK due to https://github.com/matrix-org/synapse/issues/13511 + if let Some(pids) = &data.invite_3pid { + for pid in pids { + if pid.address.is_empty() { + return; + } + } + }*/ + + // TODO: Login once and reuse the access token + let access_token = ACCESS_TOKEN; + let client = client(); + let resp = client + .post("http://localhost:8008/_matrix/client/v3/createRoom") + .header("Authorization", format!("Bearer {}", access_token)) + .json(&data) + .send(); + if let Ok(resp) = resp { + let status = resp.status(); + if !status.is_success() { + //println!("Status: {:?}", status); + let content = resp.text(); + if let Ok(ref content) = content { + if content.contains("M_ROOM_IN_USE") + || content.contains("Invalid characters in room alias") + || content.contains("':' is not permitted in the room alias name. Please note this expects a local part — 'wombat', not '#wombat:example.com'.") + || content.contains("M_UNSUPPORTED_ROOM_VERSION") + || content.contains("Invalid user_id") + || content.contains("is not a valid preset") + || content.contains("You are not allowed to set others state") + { + return; + } + } + + panic!("Content: {:?}", content); + } + } + }); +} diff --git a/src/lib.rs b/src/lib.rs @@ -7,17 +7,17 @@ use crate::types::{Flow, LoginGet, LoginPost}; use once_cell::sync::OnceCell; use std::collections::HashMap; -mod secrets; -mod types; +pub mod secrets; +pub mod types; #[no_coverage] -fn access_token() -> &'static String { +pub fn access_token() -> &'static String { static INSTANCE: OnceCell<String> = OnceCell::new(); INSTANCE.get_or_init(login) } #[no_coverage] -fn client() -> &'static reqwest::blocking::Client { +pub fn client() -> &'static reqwest::blocking::Client { static INSTANCE: OnceCell<reqwest::blocking::Client> = OnceCell::new(); INSTANCE.get_or_init(|| { reqwest::blocking::Client::builder() @@ -134,17 +134,17 @@ mod tests { // FIXME: We probably should set it to null and not do a false positive // HACK due to https://github.com/matrix-org/synapse/issues/13510 if let Some(room_alias_name) = &data.room_alias_name { - if room_alias_name.contains("\0") { + if room_alias_name.contains('\0') { return true; } } // HACK due to NUL in type or state_key if let Some(initial_state) = &data.initial_state { for state in initial_state { - if state._type.contains("\0") { + if state._type.contains('\0') { return true; } - if state.state_key.contains("\0") { + if state.state_key.contains('\0') { return true; } } @@ -168,7 +168,7 @@ mod tests { .json(&json_data) .send(); if let Ok(resp) = resp { - let status = resp.status().clone(); + let status = resp.status(); if !status.is_success() { //println!("Status: {:?}", status); let content = resp.text(); diff --git a/src/types/create_room.rs b/src/types/create_room.rs @@ -1,8 +1,9 @@ +use arbitrary::Arbitrary; use fuzzcheck::DefaultMutator; use serde::{Deserialize, Serialize}; use std::collections::HashMap; -#[derive(Clone, Serialize, Deserialize, Debug, Default)] +#[derive(Clone, Serialize, Deserialize, Debug, Default, Arbitrary)] pub struct CreateRoomMagicJSON { #[serde(skip_serializing_if = "Option::is_none")] pub creation_content: Option<HashMap<String, String>>, @@ -74,7 +75,7 @@ impl From<&CreateRoomMagic> for CreateRoomMagicJSON { } } -#[derive(Clone, Serialize, Deserialize, Debug, Default, DefaultMutator)] +#[derive(Clone, Serialize, Deserialize, Debug, Default, DefaultMutator, Arbitrary)] pub struct CreateRoomMagic { #[serde(skip_serializing_if = "Option::is_none")] pub creation_content_keys: Option<Vec<String>>, @@ -103,7 +104,7 @@ pub struct CreateRoomMagic { pub visibility: Option<String>, } -#[derive(Clone, Serialize, Deserialize, Debug, DefaultMutator, Default)] +#[derive(Clone, Serialize, Deserialize, Debug, DefaultMutator, Default, Arbitrary)] pub struct Invite3pid { pub address: String, pub id_access_token: String, @@ -111,7 +112,7 @@ pub struct Invite3pid { pub medium: String, } -#[derive(Clone, Serialize, Deserialize, Debug, Default)] +#[derive(Clone, Serialize, Deserialize, Debug, Default, Arbitrary)] pub struct StateEventJSON { pub content: HashMap<String, String>, #[serde(rename = "type")] @@ -150,7 +151,7 @@ impl From<StateEvent> for StateEventJSON { } } -#[derive(Clone, Serialize, Deserialize, Debug, DefaultMutator, Default)] +#[derive(Clone, Serialize, Deserialize, Debug, DefaultMutator, Default, Arbitrary)] pub struct StateEvent { pub content_keys: Vec<String>, pub content_values: Vec<String>,