TNO-S3 / WuppieFuzz

A coverage-guided REST API fuzzer developed on top of LibAFL
Apache License 2.0
89 stars 4 forks source link

Fuzzing fails with "not yet implemented" error #38

Closed kranonetka closed 51 minutes ago

kranonetka commented 11 hours ago

Describe the bug When attempting to fuzz Keycloak, the application sometimes closes with an error and a stack trace:

[2024-11-05T05:08:11Z INFO  wuppiefuzz::fuzzer] [Objective] New 'crash' observed! After run time: 0h-10m-57s, total number of objectives reached: 6732
[2024-11-05T05:08:11Z DEBUG wuppiefuzz::fuzzer] Sending 3 requests
thread 'main' panicked at src/input/mod.rs:168:35:
not yet implemented
stack backtrace:
   0:        0x102dae83c - <std::sys::backtrace::BacktraceLock::print::DisplayBacktrace as core::fmt::Display>::fmt::h243268f17d714c7f
   1:        0x102ad9bf8 - core::fmt::write::hb3cfb8a30e72d7ff
   2:        0x102daa79c - std::io::Write::write_fmt::hfb2314975de9ecf1
   3:        0x102daf954 - std::panicking::default_hook::{{closure}}::h14c7718ccf39d316
   4:        0x102daf57c - std::panicking::default_hook::hc62e60da3be2f352
   5:        0x102e80bac - libafl::executors::hooks::unix::unix_signal_handler::setup_panic_hook::{{closure}}::h0944af54287ee760
   6:        0x102db093c - std::panicking::rust_panic_with_hook::h09e8a656f11e82b2
   7:        0x102dafdbc - std::panicking::begin_panic_handler::{{closure}}::h1230eb3cc91b241c
   8:        0x102daecd8 - std::sys::backtrace::__rust_end_short_backtrace::hc3491307aceda2c2
   9:        0x102dafab8 - _rust_begin_unwind
  10:        0x1030a8110 - core::panicking::panic_fmt::ha4b80a05b9fff47a
  11:        0x1030a817c - core::panicking::panic::h298549a7412a7069
  12:        0x102f0c504 - wuppiefuzz::input::OpenApiRequest::resolve_parameter_references::hf4a7600d38137725
  13:        0x102e0e57c - <libafl::executors::inprocess::GenericInProcessExecutor<H,HB,HT,OT,S> as libafl::executors::Executor<EM,Z>>::run_target::h531014a6079cb717
  14:        0x102e7fd9c - libafl::stages::Stage::perform_restartable::h8735d8560c410c0b
  15:        0x102f04410 - wuppiefuzz::fuzzer::fuzz::hca7a2eefe4616bcd
  16:        0x102f25f5c - wuppiefuzz::main::hc9efc6438231f1c3
  17:        0x102e37758 - std::sys::backtrace::__rust_begin_short_backtrace::hf135faac0f67de2b
  18:        0x102e376c4 - std::rt::lang_start::{{closure}}::h3de5b8c8bda62348
  19:        0x102da35b8 - std::rt::lang_start_internal::hdd117cb81a316264
  20:        0x102f3ac0c - _main
[2024-11-05T05:08:11Z INFO  wuppiefuzz::fuzzer] [Objective] New 'crash' observed! After run time: 0h-10m-57s, total number of objectives reached: 6733
[2024-11-05T05:08:11Z INFO  libafl::executors::inprocess] Bye!

Versions:

To Reproduce

  1. Fuzzing target: Keycloak 25.0.6 (with edited openapi.yaml to avoid cyclic links in components)
  2. WuppieFuzz command:
    ./wuppiefuzz fuzz \
    -i corpus_directory \
    --coverage-host localhost:6300 \
    --coverage-format jacoco \
    --timeout 7200 \
    --jacoco-class-dir ~/keycloak/services/target/classes \
    --source-dir ~/keycloak/services/src/main/java \
    --output-format human-readable \
    --header header.yaml \
    --log-level debug \
    --method-mutation-strategy follow-spec \
    --jacoco-class-prefix org/keycloak \
    --report \
    KeyCloak_OpenAPI/openapi.yaml
  3. OpenAPI spec used: https://pastebin.com/jhtBDXVg
  4. Any corpus. Just generate by OpenAPI
  5. Script to generate auth token in header.yaml:
    
    curl -d 'client_id=security-admin-console' \
    -d 'username=admin' \
    -d 'password=admin' \
    -d 'grant_type=password' \
    'http://localhost:8080/realms/master/protocol/openid-connect/token' \
    | grep -Eo '"access_token": *"[^"]*"' \
    | sed 's/"access_token": *"\([^"]*\)"/authorization: Bearer \1/' > header.yaml

./wuppiefuzz verify-auth \ --openapi-spec KeyCloak_OpenAPI/openapi.yaml \ --header header.yaml

6. Docker-compose to run Keycloak with JaCoCo (JaCoCo binaries need to be added manually):
```yaml
services:
  postgres:
    image: postgres:15.2
    container_name: keycloak_db
    environment:
      POSTGRES_DB: keycloak
      POSTGRES_USER: keycloak
      POSTGRES_PASSWORD: keycloak
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - keycloak_network

  keycloak:
    image: quay.io/keycloak/keycloak:25.0.6
    container_name: keycloak
    command:
      - start-dev
    environment:
      KC_DB: postgres
      KC_DB_URL_HOST: postgres
      KC_DB_URL_PORT: 5432
      KC_DB_SCHEMA: public
      KC_DB_URL_DATABASE: keycloak
      KC_DB_USERNAME: keycloak
      KC_DB_PASSWORD: keycloak
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: admin
      PRINT_ENV: true
      DEBUG_MODE: true
      DEBUG_PORT: "*:5005"
      KC_LOG_LEVEL: "INFO"
      JAVA_OPTS_APPEND: -javaagent:/opt/keycloak/jacoco/jacocoagent.jar=output=tcpserver,address=*,includes=org.keycloak.*
    volumes:
      - ./jacoco_distr/lib:/opt/keycloak/jacoco/
    ports:
      - "8080:8080"
      - "5005:5005"
      - "6300:6300"
    depends_on:
      - postgres
    networks:
      - keycloak_network

volumes:
  postgres_data:

networks:
  keycloak_network:
    driver: bridge

After starting Keycloak, go to http://localhost:8080, where the login and password are admin. Go to Clients->security-admin-console and enable Direct Access Grants.
Then go to Realm Settings->Tokens and increase Access Token Lifespan and Client Login Timeout to a longer duration, like 1 day, to generate long-lived tokens.

Expected behavior The fuzzing process should not stop with a "not yet implemented" error.

grebnetiew commented 4 hours ago

Good point! I have attempted a quick fix - would you please check if this solves the issue you're experiencing? You can find it on the fix-resolve-textplain-body-references branch, and in PR #40.

kranonetka commented 3 hours ago

It's been working for more than 15 minutes, it looks like the solution worked