├── .github └── workflows │ └── docker-image.yml ├── Dockerfile ├── README.md ├── berate_radius.sh ├── certs ├── example.com.crt ├── example.com.issuer.crt └── example.com.key ├── confedit.sh ├── hostapd_configs ├── hostapd.conf.template ├── hostapd.eap_user └── hostapd.radius_client.template ├── images ├── 2023-06-28-14-29-05.png └── 2023-06-28-16-32-21.png └── output └── hostapd.credout /.github/workflows/docker-image.yml: -------------------------------------------------------------------------------- 1 | name: Create and publish the Docker image 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*.*.*' 7 | schedule: 8 | - cron: '0 0 * * 1' 9 | 10 | env: 11 | REGISTRY: ghcr.io 12 | IMAGE_NAME: ${{ github.repository }} 13 | 14 | 15 | 16 | jobs: 17 | build-and-push-image: 18 | runs-on: ubuntu-latest 19 | permissions: 20 | contents: read 21 | packages: write 22 | 23 | steps: 24 | - 25 | name: Checkout 26 | uses: actions/checkout@v3 27 | - 28 | name: Set up QEMU 29 | uses: docker/setup-qemu-action@v2 30 | - 31 | name: Set up Docker Buildx 32 | uses: docker/setup-buildx-action@v2 33 | - 34 | name: Log in to the Container registry 35 | uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 36 | with: 37 | registry: ${{ env.REGISTRY }} 38 | username: ${{ github.actor }} 39 | password: ${{ secrets.GITHUB_TOKEN }} 40 | - 41 | name: Extract metadata (tags, labels) for Docker 42 | id: meta 43 | uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 44 | with: 45 | images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} 46 | tags: | 47 | type=schedule 48 | type=ref,event=branch 49 | type=ref,event=pr 50 | type=semver,pattern={{version}} 51 | type=semver,pattern={{major}}.{{minor}} 52 | type=semver,pattern={{major}} 53 | type=sha 54 | - 55 | name: Build and push 56 | uses: docker/build-push-action@v3 57 | with: 58 | context: . 59 | platforms: linux/amd64,linux/arm64 60 | push: true 61 | tags: ${{ steps.meta.outputs.tags }} 62 | labels: ${{ steps.meta.outputs.labels }} -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.18 AS BUILDER 2 | 3 | RUN apk add openssl-dev libnl3-dev linux-headers git alpine-sdk 4 | 5 | COPY --chmod=755 confedit.sh /confedit.sh 6 | 7 | WORKDIR /hostapd-mana 8 | RUN git clone https://github.com/sensepost/hostapd-mana . &&\ 9 | git checkout 1302a7204d9118efa0668df1924c938dbe8d1b11 10 | 11 | WORKDIR /hostapd-mana/hostapd 12 | RUN /confedit.sh 13 | 14 | 15 | FROM alpine:3.18 16 | 17 | RUN apk add libnl3 libssl3 18 | 19 | COPY --from=BUILDER /hostapd-mana/hostapd/hostapd_cli /usr/bin/hostapd-mana_cli 20 | COPY --from=BUILDER /hostapd-mana/hostapd/hostapd /usr/sbin/hostapd-mana 21 | COPY --from=BUILDER /hostapd-mana/hostapd/nt_password_hash /usr/bin/nt_password_hash 22 | 23 | WORKDIR /hostapd_configs 24 | 25 | COPY --chmod=755 /hostapd_configs/hostapd.conf.template /hostapd_configs/hostapd.conf.template 26 | COPY --chmod=755 /hostapd_configs/hostapd.radius_client.template /hostapd_configs/hostapd.radius_client.template 27 | COPY /hostapd_configs/hostapd.eap_user /hostapd_configs/hostapd.eap_user 28 | 29 | COPY certs /certs 30 | COPY output /output 31 | 32 | COPY --chmod=755 berate_radius.sh /berate_radius.sh 33 | 34 | ENTRYPOINT ["/berate_radius.sh"] -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # About berate_radius 2 | 3 | This project was created to simplify the process of creating a malicious RADIUS server. 4 | 5 | # Usage 6 | 7 | First, create a cerificate if you don't already have one. 8 | 9 | If you would like to create a certificate that is signed by a trusted CA, we recommend that you use [lego](https://go-acme.github.io/lego/usage/cli/obtain-a-certificate/) together with a CloudFlare API [key](https://go-acme.github.io/lego/dns/cloudflare/). 10 | 11 | An example command to get your certificates using lego and a CloudFlare API key: 12 | 13 | ``` 14 | docker run --rm -it -v ./certs:/.lego/certificates \ 15 | -e "CF_API_EMAIL=tester@example.com" \ 16 | -e "CF_DNS_API_TOKEN=PLtbXXXXXXXXXXXXXXXVRqda" \ 17 | goacme/lego --email "tester@example.com" --dns cloudflare --domains "wifi.example.com" -a run 18 | ``` 19 | 20 | To get the malicious RADIUS server up running you can either build the Docker image yourself or pull it from `ghcr.io/sensepost/berate_radius`. 21 | 22 | ``` 23 | docker run -it --rm -p 1813:1813/udp -p 1812:1812/udp -v ./certs:/certs ghcr.io/sensepost/berate_radius -d wifi.example.com 24 | ``` 25 | 26 | Berate_radius takes three parameters, namely domain, radius-password and radius-client-ip-range. However, these are optional as they have been set with default values. 27 | 28 | Note, if your volume mounts are different from the above commands then you will need to make sure to move over the certificates. As hostapd is configured to look in the certs directory for the following: 29 | 30 | ``` 31 | domain.crt 32 | domain.issuer.crt 33 | domain.key 34 | ``` 35 | 36 | Where domain is the domain you passed to berate_radius using `-d | --domain`. 37 | 38 | Next, configure your Access Point with the malicious RADIUS server. If you are using hostapd, would need to set the following: 39 | 40 | ``` 41 | eap_server=0 42 | auth_server_addr=127.0.0.1 43 | auth_server_port=1812 44 | auth_server_shared_secret=P@ssw0rd 45 | ``` 46 | -------------------------------------------------------------------------------- /berate_radius.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | export LC_ALL=C 4 | 5 | PROGNAME="$(basename $0)" 6 | 7 | usage() { 8 | echo "Usage: "$PROGNAME" [-h] [--domain example.com] [--radius-password P@ssw0rd] [--radius-client-ip-range 0.0.0.0/0]" 9 | echo 10 | echo "Options:" 11 | echo " -h, --help Show this help" 12 | echo " -d, --domain Domain of the certificate (default: \"example.com\")" 13 | echo " -p, --radius-password Radius client password (default: \"P@ssw0rd\")" 14 | echo " -r, --radius-client-ip-range Radius client allowed IP range (default: \"0.0.0.0/0\")" 15 | echo 16 | } 17 | 18 | # defaults 19 | export PASSWORD="P@ssw0rd" 20 | export RANGE="0.0.0.0/0" 21 | export DOMAIN="example.com" 22 | 23 | GETOPT_ARGS=$(getopt -o hd:p:r: -l "help","domain:","radius-password:","radius-client-ip-range:" -n "$PROGNAME" -- "$@") 24 | [ $? -ne 0 ] && exit 1 25 | eval set -- "$GETOPT_ARGS" 26 | 27 | while :; do 28 | case "$1" in 29 | -h|--help) 30 | usage 31 | exit 0 32 | ;; 33 | -d|--domain) 34 | shift 35 | DOMAIN="$1" 36 | shift 37 | ;; 38 | -p|--radius-password) 39 | shift 40 | PASSWORD="$1" 41 | shift 42 | ;; 43 | -r|--radius-client-ip-range) 44 | shift 45 | RANGE="$1" 46 | shift 47 | ;; 48 | --) 49 | shift 50 | break 51 | ;; 52 | esac 53 | done 54 | 55 | /hostapd_configs/hostapd.conf.template > /hostapd_configs/hostapd.conf 56 | /hostapd_configs/hostapd.radius_client.template > /hostapd_configs/hostapd.radius_client 57 | 58 | 59 | # Add flag for verbosity 60 | hostapd-mana /hostapd_configs/hostapd.conf -------------------------------------------------------------------------------- /certs/example.com.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDmjCCAoICCQDPrwm5Ys8s+DANBgkqhkiG9w0BAQsFADCBjjELMAkGA1UEBhMC 3 | VUsxDzANBgNVBAgMBkxvbmRvbjEPMA0GA1UEBwwGTG9uZG9uMRIwEAYDVQQKDAlT 4 | ZW5zZVBvc3QxCzAJBgNVBAsMAklUMRkwFwYDVQQDDBB3aWZpLmV4YW1wbGUuY29t 5 | MSEwHwYJKoZIhvcNAQkBFhJ0ZXN0ZXJAZXhhbXBsZS5jb20wHhcNMjMwNjI4MTM1 6 | MTIyWhcNMjMwNzI4MTM1MTIyWjCBjjELMAkGA1UEBhMCVUsxDzANBgNVBAgMBkxv 7 | bmRvbjEPMA0GA1UEBwwGTG9uZG9uMRIwEAYDVQQKDAlTZW5zZVBvc3QxCzAJBgNV 8 | BAsMAklUMRkwFwYDVQQDDBB3aWZpLmV4YW1wbGUuY29tMSEwHwYJKoZIhvcNAQkB 9 | FhJ0ZXN0ZXJAZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK 10 | AoIBAQCdnyzcwaAkchow7+2Y07ozcqHACx33UKXqroQQtSfngnFd/1H6Q1ILYGiE 11 | Mh0ctt/6hD0EKmSVF9qhivmu4q7oMqpIPb49NSkgt4Diu+K9YXhG/rtItpw6hTs2 12 | jXYXqK3p76ngczKoW997VGAFDkxADFRC2lzERKu02KF0fOQIzTLueVMYDGFqkSx4 13 | Z9ovT+AXqz9XqQnvHDN00NCUA7XDZfkqqJYXtGrq6SPbkwQkqURw73lxr74LMwJC 14 | zbGwVV9Amp2lS4m2qfCF3Q4hy0ydPkcw5EvxkwNiaeUJTn86QI52VRybG6rQb9Jj 15 | 1QnJgOlRy4voaKpAjRSbAwsqimNXAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAF53 16 | xqQeQNvYIpf/vIsQMWU/77eWS5PmRnDN1rc+OrPE3AnTFavX7cT32trAX3LjDXS8 17 | PrzKxfSntLcBKL6wbCQfdmfUU8tTcM109uKTH18Z46OF8sQ710ogt1u+0ZXPDN5G 18 | wpLhufdnACgrk3YavcVo7rAM2VbPZauEExaxAVBuZ6AgPRzOr51M5nIf/Re7i6ow 19 | XMm+Q2IqEehjVmj9BBwgEfKyoskWnbegEzwCfxkGt5OaeiPlJ9yyNl49fCwo97ZF 20 | Bdi+HW8tfKP5lzIlTXY73JuurG1SYS4lKuX/M4vwQWuUA4lfGizfl/3R8/kiiKxm 21 | 4rYgLjp/Qw2OSd7XcGo= 22 | -----END CERTIFICATE----- 23 | -------------------------------------------------------------------------------- /certs/example.com.issuer.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDmjCCAoICCQDPrwm5Ys8s+DANBgkqhkiG9w0BAQsFADCBjjELMAkGA1UEBhMC 3 | VUsxDzANBgNVBAgMBkxvbmRvbjEPMA0GA1UEBwwGTG9uZG9uMRIwEAYDVQQKDAlT 4 | ZW5zZVBvc3QxCzAJBgNVBAsMAklUMRkwFwYDVQQDDBB3aWZpLmV4YW1wbGUuY29t 5 | MSEwHwYJKoZIhvcNAQkBFhJ0ZXN0ZXJAZXhhbXBsZS5jb20wHhcNMjMwNjI4MTM1 6 | MTIyWhcNMjMwNzI4MTM1MTIyWjCBjjELMAkGA1UEBhMCVUsxDzANBgNVBAgMBkxv 7 | bmRvbjEPMA0GA1UEBwwGTG9uZG9uMRIwEAYDVQQKDAlTZW5zZVBvc3QxCzAJBgNV 8 | BAsMAklUMRkwFwYDVQQDDBB3aWZpLmV4YW1wbGUuY29tMSEwHwYJKoZIhvcNAQkB 9 | FhJ0ZXN0ZXJAZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK 10 | AoIBAQCdnyzcwaAkchow7+2Y07ozcqHACx33UKXqroQQtSfngnFd/1H6Q1ILYGiE 11 | Mh0ctt/6hD0EKmSVF9qhivmu4q7oMqpIPb49NSkgt4Diu+K9YXhG/rtItpw6hTs2 12 | jXYXqK3p76ngczKoW997VGAFDkxADFRC2lzERKu02KF0fOQIzTLueVMYDGFqkSx4 13 | Z9ovT+AXqz9XqQnvHDN00NCUA7XDZfkqqJYXtGrq6SPbkwQkqURw73lxr74LMwJC 14 | zbGwVV9Amp2lS4m2qfCF3Q4hy0ydPkcw5EvxkwNiaeUJTn86QI52VRybG6rQb9Jj 15 | 1QnJgOlRy4voaKpAjRSbAwsqimNXAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAF53 16 | xqQeQNvYIpf/vIsQMWU/77eWS5PmRnDN1rc+OrPE3AnTFavX7cT32trAX3LjDXS8 17 | PrzKxfSntLcBKL6wbCQfdmfUU8tTcM109uKTH18Z46OF8sQ710ogt1u+0ZXPDN5G 18 | wpLhufdnACgrk3YavcVo7rAM2VbPZauEExaxAVBuZ6AgPRzOr51M5nIf/Re7i6ow 19 | XMm+Q2IqEehjVmj9BBwgEfKyoskWnbegEzwCfxkGt5OaeiPlJ9yyNl49fCwo97ZF 20 | Bdi+HW8tfKP5lzIlTXY73JuurG1SYS4lKuX/M4vwQWuUA4lfGizfl/3R8/kiiKxm 21 | 4rYgLjp/Qw2OSd7XcGo= 22 | -----END CERTIFICATE----- 23 | -------------------------------------------------------------------------------- /certs/example.com.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCdnyzcwaAkchow 3 | 7+2Y07ozcqHACx33UKXqroQQtSfngnFd/1H6Q1ILYGiEMh0ctt/6hD0EKmSVF9qh 4 | ivmu4q7oMqpIPb49NSkgt4Diu+K9YXhG/rtItpw6hTs2jXYXqK3p76ngczKoW997 5 | VGAFDkxADFRC2lzERKu02KF0fOQIzTLueVMYDGFqkSx4Z9ovT+AXqz9XqQnvHDN0 6 | 0NCUA7XDZfkqqJYXtGrq6SPbkwQkqURw73lxr74LMwJCzbGwVV9Amp2lS4m2qfCF 7 | 3Q4hy0ydPkcw5EvxkwNiaeUJTn86QI52VRybG6rQb9Jj1QnJgOlRy4voaKpAjRSb 8 | AwsqimNXAgMBAAECggEAUW3HHnDFS67KyxdYVsii/CsvVugnXfoDDR+FSKBd8iMY 9 | cCgT8MdQnmH6/LhrA8eSJHimkP1ZoxCEuUnzvZ6MH5b1E4caPcK18Zn7cqb/9zhg 10 | i8TTejgks7LaqU8hgA17c0yGJVc+B24XIT6wsEv3pmr4KOVoYVjcn/v+RRC0ObsA 11 | 8lzOJ0bN7e/sQrhEgm6JJ+qFZHvmBAScGeWPmhxGYVkoizcyZ0fzj39OobQk4Yeu 12 | zdcPkFAYP1J9EwC+pWw6jWCijSYT7hEVz/fuezINUXKlhR7oVMxYFtOlgGlZ5aNl 13 | fVRsjOt6aT+rgAFhaNfLBjLJaaEMUyk9cXvaWzdHoQKBgQDQOC/OyKnN2bHWo8jh 14 | kD7b1gBJNrvxv9p5EWnxfwooA8bbfc1+gd2tS5Kx507mkBa2+lvBRBniGia0Nngr 15 | M653Sz+Wy4+6v82U4G0v8gR5ly/AWSeusiieUleDp7wDlLpXHoM187Doa6++5gN/ 16 | jRBjIkrwSp1Angh9n9OVfqup8QKBgQDByqLi8CTzc5yTaWoCvZNcJQdEMrcqA7rM 17 | HZGr8qunhR3KLIV06tTtXjqkPmPtwCaqqw94hHOBGweox24cCAVt0zr7nb7qX2MK 18 | C5Nm98/k1Yd2BVHx3hMzIJKGfbs0kj2wJJ+ke7KoC3eFSFqk8rs2/z2WlcTGNIc7 19 | S8czBMzZxwKBgGtygyEnJZDnZMEJVdEoWXeiEBW32/addUUCenQ3hWsuv8BmQ9Oj 20 | elxB4lpRrcKG2mHkAdNSrDSkIBLhBNPuYHqI5zCOrQXGknTf9xhFwI9qOCb/Gt4o 21 | a5N/lE+JEBmc9yebxEPkFAdsAo31Lhr1FV7CxH8JUeqVYnZJMqszaaxRAoGBAJAq 22 | IPbWU4bQsOBxAS48vY1E9pzjZaNZ1vLV5HKYOt6KhtjKOhX6RKC5AsMArvJFif5Y 23 | 909eqVaYNyB2DBHKXc+P3kck2MweXd0xM1zcacoAl59S4d0eqgXU62wlyMiZKk8J 24 | T8HbS9L7hNSgON6QvHlzc+u8SwBwP1H7U5s+rO4tAoGBAIS9TGLP0XQIQS3aeI5O 25 | brlvEwuGu3mTqQk2lisPsKQgG3K/27vR7FmWR6IOcjuT5DwQJxLdg5eMK858XKEe 26 | liczW2Wg1mroCJHGTmZH0ksJ4lKsANXNmtnP2AZWBeED90A2psihnkA2eOL4SQ8v 27 | vECbqT+v3y9zstztkB8Ts39/ 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /confedit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Stolen from https://git.alpinelinux.org/aports/tree/main/hostapd/APKBUILD 4 | { sed \ 5 | -e '/^#CONFIG_DRIVER_NL80211=y/s/^#//' \ 6 | -e '/^#CONFIG_RADIUS_SERVER=y/s/^#//' \ 7 | -e '/^#CONFIG_DRIVER_WIRED=y/s/^#//' \ 8 | -e '/^#CONFIG_DRIVER_NONE=y/s/^#//' \ 9 | -e '/^#CONFIG_IEEE80211N=y/s/^#//' \ 10 | -e '/^#CONFIG_IEEE80211R=y/s/^#//' \ 11 | -e '/^#CONFIG_IEEE80211AC=y/s/^#//' \ 12 | -e '/^#CONFIG_IEEE80211AX=y/s/^#//' \ 13 | -e '/^#CONFIG_FULL_DYNAMIC_VLAN=y/s/^#//' \ 14 | -e '/^#CONFIG_LIBNL32=y/s/^#//' \ 15 | -e '/^#CONFIG_ACS=y/s/^#//' \ 16 | -e '/^#CONFIG_WEP=y/s/^#//' \ 17 | -e '/^#CONFIG_SAE=y/s/^#//' \ 18 | defconfig 19 | echo "CC ?= ${CC:-gcc}" 20 | echo "CFLAGS += -I/usr/include/libnl3" 21 | echo "LIBS += -L/usr/lib" 22 | } >> .config 23 | 24 | CFLAGS="$CFLAGS -flto=auto" make all nt_password_hash -------------------------------------------------------------------------------- /hostapd_configs/hostapd.conf.template: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | cat <