This is meant for autonomous non-networked systems where we
take the advantage of CFEngine and Bashbunny automation. I liked this exercise as it shows
the great potential of CFEngine as well as the Bashbunny. Now the Bashbunny is an attacking tool, and Im not going to exploit any systems here with CFEngine, rather we put it to good use and use the “evil” device as our policy hub.
Assuming we all know how to configure Bashbunny :)
Check the bunny hostname is correctly set in /etc/hosts on the Bashbunny
if not add to /etc/hosts (Otherwise cf-serverd will have issues)
172.16.64.1 bunny
Check the /etc/dhcp/dhcpd.conf range 172.16.64.10 172.16.64.12 and set to only one value range 172.16.64.64 172.16.64.64
Make sure to set a sane date as the Bashbunny does not know what time it is
root@bunny:~# date -s "20170618 09:00" # apt-get update # apt-get -y install autoconf bison build-essential curl git-core libapr1 libaprutil1 libcurl4-openssl-dev libgmp3-dev libpcap-dev libpq-dev libreadline6-dev libsqlite3-dev libssl-dev libsvn1 libtool libxml2 libxml2-dev libxslt-dev libyaml-dev locate ncurses-dev openssl wget xsel zlib1g zlib1g-dev
Lets build CFEngine on armv7l (no pre-built binaries for arm on CFEgnine webpage)
root@bunny:~#mkdir CFENGINE root@bunny:~CFENGINE# wget https://cfengine-package-repos.s3.amazonaws.com/tarballs/cfengine-3.11.0b1.tar.gz
Run configure
root@bunny:~/CFENGINE/cfengine-3.11.0b1# ./configure <---snip----> checking for getconf... /usr/bin/getconf checking for the pthreads library -lpthreads... no checking whether pthreads work without any flags... no checking whether pthreads work with -Kthread... no checking whether pthreads work with -kthread... no checking for the pthreads library -llthread... no checking whether pthreads work with -pthread... yes checking for joinable pthread attribute... PTHREAD_CREATE_JOINABLE checking if more special flags are required for pthreads... no checking for PQconnectdb in -lpq... yes checking libpq-fe.h usability... yes checking libpq-fe.h presence... yes checking for libpq-fe.h... yes which: no mysql_config in (/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/bin:/usr/alpha-unknown-linux-gnu/gcc-bin/4.9.3) checking for mysql_real_connect in -lmysqlclient... no checking mysql.h usability... no checking mysql.h presence... no checking for mysql.h... no checking for EVP_CIPHER_CTX_init in -lmysqlclient... no checking for mdb_dbi_open in -llmdb... no configure: error: Cannot find Lightning MDB
Get lmdb
root@bunny:~/CFENGINE/cfengine-3.11.0b1# wget https://github.com/LMDB/lmdb/archive/mdb.master.zip root@bunny:~/CFENGINE/lmdb-mdb.mster/libraries/liblmdb# make gcc -pthread -O2 -g -W -Wall -Wno-unused-parameter -Wbad-function-cast -Wuninitialized -c mdb.c INIT: Id "hvc0" respawning too fast: disabled for 5 minutes gcc -pthread -O2 -g -W -Wall -Wno-unused-parameter -Wbad-function-cast -Wuninitialized -c midl.c ar rs liblmdb.a mdb.o midl.o ar: creating liblmdb.a gcc -pthread -O2 -g -W -Wall -Wno-unused-parameter -Wbad-function-cast -Wuninitialized -fPIC -c mdb.c -o mdb.lo gcc -pthread -O2 -g -W -Wall -Wno-unused-parameter -Wbad-function-cast -Wuninitialized -fPIC -c midl.c -o midl.lo gcc -pthread -shared -o liblmdb.so mdb.lo midl.lo gcc -pthread -O2 -g -W -Wall -Wno-unused-parameter -Wbad-function-cast -Wuninitialized -c mdb_stat.c gcc -pthread -O2 -g -W -Wall -Wno-unused-parameter -Wbad-function-cast -Wuninitialized mdb_stat.o liblmdb.a -o mdb_stat gcc -pthread -O2 -g -W -Wall -Wno-unused-parameter -Wbad-function-cast -Wuninitialized -c mdb_copy.c gcc -pthread -O2 -g -W -Wall -Wno-unused-parameter -Wbad-function-cast -Wuninitialized mdb_copy.o liblmdb.a -o mdb_copy gcc -pthread -O2 -g -W -Wall -Wno-unused-parameter -Wbad-function-cast -Wuninitialized -c mdb_dump.c gcc -pthread -O2 -g -W -Wall -Wno-unused-parameter -Wbad-function-cast -Wuninitialized mdb_dump.o liblmdb.a -o mdb_dump gcc -pthread -O2 -g -W -Wall -Wno-unused-parameter -Wbad-function-cast -Wuninitialized -c mdb_load.c gcc -pthread -O2 -g -W -Wall -Wno-unused-parameter -Wbad-function-cast -Wuninitialized mdb_load.o liblmdb.a -o mdb_load gcc -pthread -O2 -g -W -Wall -Wno-unused-parameter -Wbad-function-cast -Wuninitialized -c mtest.c gcc -pthread -O2 -g -W -Wall -Wno-unused-parameter -Wbad-function-cast -Wuninitialized mtest.o liblmdb.a -o mtest gcc -pthread -O2 -g -W -Wall -Wno-unused-parameter -Wbad-function-cast -Wuninitialized -c mtest2.c gcc -pthread -O2 -g -W -Wall -Wno-unused-parameter -Wbad-function-cast -Wuninitialized mtest2.o liblmdb.a -o mtest2 gcc -pthread -O2 -g -W -Wall -Wno-unused-parameter -Wbad-function-cast -Wuninitialized -c mtest3.c gcc -pthread -O2 -g -W -Wall -Wno-unused-parameter -Wbad-function-cast -Wuninitialized mtest3.o liblmdb.a -o mtest3 gcc -pthread -O2 -g -W -Wall -Wno-unused-parameter -Wbad-function-cast -Wuninitialized -c mtest4.c gcc -pthread -O2 -g -W -Wall -Wno-unused-parameter -Wbad-function-cast -Wuninitialized mtest4.o liblmdb.a -o mtest4 gcc -pthread -O2 -g -W -Wall -Wno-unused-parameter -Wbad-function-cast -Wuninitialized -c mtest5.c gcc -pthread -O2 -g -W -Wall -Wno-unused-parameter -Wbad-function-cast -Wuninitialized mtest5.o liblmdb.a -o mtest5 root@bunny:~/CFENGINE/lmdb-mdb.mster/libraries/liblmdb# make install mkdir -p /usr/local/bin mkdir -p /usr/local/lib mkdir -p /usr/local/include mkdir -p /usr/local/share/man/man1 for f in mdb_stat mdb_copy mdb_dump mdb_load; do cp $f /usr/local/bin; done for f in liblmdb.a liblmdb.so; do cp $f /usr/local/lib; done for f in lmdb.h; do cp $f /usr/local/include; done for f in mdb_stat.1 mdb_copy.1 mdb_dump.1 mdb_load.1; do cp $f /usr/local/share/man/man1; done
Return to cfengine configure
root@bunny:~/CFENGINE/cfengine-3.11.0b1# ./configure Summary: > Version: 3.11.0b1 > Required libraries -> OpenSSL: default path -> PCRE: default path > Optional libraries -> MySQL connector: disabled -> PostgreSQL connector: default path -> DB: Lightning MDB: default path -> libvirt: disabled -> libacl: default path -> libcurl: disabled -> libyaml: default path -> libxml2: default path -> User promises: PAM/user* tools -> Enterprise extensions: Plugin or not included -> init.d script: disabled -> Systemd service: disabled -> Workdir: /var/cfengine -> Masterdir: default -> Inputdir: default -> Logdir: /var/cfengine -> Piddir: /var/cfengine -> Statedir: default DONE: Configuration done. Run make/gmake to build CFEngine Community root@bunny:~/CFENGINE/cfengine-3.11.0b1# make && make install
Get masterfiles
# wget https://cfengine-package-repos.s3.amazonaws.com/tarballs/cfengine-masterfiles-3.11.0b1.tar.gz # cd cfengine-masterfiles-3.11.0b1 # make # make install
Run some final configurations
root@bunny:/var/cfengine# ./bin/cf-key
Now edit the cf-serverd configuration part in masterfiles
vi /var/cfengine/masterfiles/controls/cf_serverd.cf
And set the following values for allowconnects, allowallconnects, bindtointerface and access
allowconnects => { "127.0.0.1" , "172.16.64.64"}; allowallconnects => { "127.0.0.1" , "172.16.64.64"}; bindtointerface => "172.16.64.1"; bundle server access_rules() { access: any:: "$(def.dir_masterfiles)" handle => "server_access_grant_access_policy", shortcut => "masterfiles", comment => "Grant access to the policy updates", admit => { "172.16.64.64" }; "$(def.dir_software)" handle => "server_access_grant_access_datafiles", comment => "Grant access to software updates", admit => { "172.16.64.64" }; "$(def.dir_bin)" handle => "server_access_grant_access_binary", comment => "Grant access to binary for cf-runagent", admit => { "172.16.64.64" }; "$(def.dir_modules)" handle => "server_access_grant_access_modules", shortcut => "modules", comment => "Grant access to modules directory", admit => { "172.16.64.64" }; "$(def.dir_plugins)" handle => "server_access_grant_access_plugins", comment => "Grant access to plugins directory", admit => { "172.16.64.64" }; "$(def.dir_templates)" handle => "server_access_grant_access_templates", shortcut => "templates", comment => "Grant access to templates directory", admit => { "172.16.64.64" }; enterprise_edition.policy_server:: "collect_calls" resource_type => "query", admit_ips => { "172.16.64.64" };
root@bunny:/var/cfengine# cp -r promises.cf ../inputs root@bunny:/var/cfengine# /var/cfengine/bin/cf-agent -KI
Prepare the cfengine distributioin folder on the Bashbunny to serve to clients
(Go back home)
root#bunny:~# mkdir cfengine && cd cfengine root#bunny:~/cfengine#
Download all deb and RPMs from https://cfengine.com/product/community/
root@bunny:/var/cfengine# wget https://cfengine-package-repos.s3.amazonaws.com/community_binaries/cfengine-community_3.11.0b1-1_i386.deb root@bunny:/var/cfengine# wget https://cfengine-package-repos.s3.amazonaws.com/community_binaries/cfengine-community_3.11.0b1-1_amd64.deb root@bunny:/var/cfengine# https://cfengine-package-repos.s3.amazonaws.com/community_binaries/cfengine-community-3.11.0b1-1.i386.rpm root@bunny:/var/cfengine# https://cfengine-package-repos.s3.amazonaws.com/community_binaries/cfengine-community-3.11.0b1-1.x86_64.rpm
Create an installer script called cfengine-install.sh for CFEngine on clients (Debian based checker only), place this shellscript in the /root/CFENGINE/ directory
#!/bin/bash #This script is only for debian based systems now .. feel free to expand if [ "$(uname -m)" == "x86_64" ] && [ "$(gawk -F= '/^ID_LIKE/{print $2}' /etc/os-release)" == "debian" ]; then wget -nc http://172.16.64.1/root/cfengine/cfengine-community_3.10.1-1_amd64-debian7.deb && dpkg -i cfengine-community_3.10.1-1_amd64.deb exit 0 elif [ "$(uname -m)" == "x86_64" ] && [ "$(gawk -F= '/^ID_LIKE/{print $2}' /etc/os-release)" == "ubuntu" ]; then wget -nc http://172.16.64.1/root/cfengine/cfengine-community_3.10.1-1_amd64-debian7.deb && dpkg -i cfengine-community_3.10.1-1_amd64.deb exit 0 elif [ "$(uname -m)" == "i686" ] && [ "$(gawk -F= '/^ID_LIKE/{print $2}' /etc/os-release)" == "debian" ]; then wget -nc http://172.16.64.1/root/cfengine/cfengine-community_3.10.1-1_i386.deb && dpkg -i cfengine-community_3.10.1-1_i386.deb exit 0 elif [ "$(uname -m)" == "i686" ] && [ "$(gawk -F= '/^ID_LIKE/{print $2}' /etc/os-release)" == "ubuntu" ]; then wget -nc http://172.16.64.1/root/cfengine/cfengine-community_3.10.1-1_i386.deb && dpkg -i cfengine-community_3.10.1-1_i386.deb exit 0 else echo "Unknown architecture" fi
Next Create your fisrst promises for Bashbunny CFEngine automation, you can use the nice documentation https://docs.cfengine.com/docs/3.10/
On the Bashbunny do setup your (switch1 or switch 2) payload.txt
ATTACKMODE HID STORAGE ECM_ETHERNET #Set some current time ..... check your watch date -s "20170618 21:23" LED ATTACK python -m SimpleHTTPServer 80 & /var/cfengine/bin/cf-serverd && LED FINISH LED R 300 Q ALT F2 Q DELAY 3000 # Im using xterm in my example, this is intended for a Window manager environment on Xorg Q STRING xterm Q ENTER Q DELAY 200 Q ENTER Q STRING wget -nc http://172.16.64.1/root/cfengine/cfengine-install.sh Q ENTER Q DELAY 500 Q STRING chmod +x cfengine-install.sh Q ENTER Q DELAY 200 Q STRING Q ENTER Q STRING cat Q ENTER Q STRING Now you can run the installer script to boot-strap your system Q ENTER Q STRING Please elevate to root or sudo the installer afterwards and run Q ENTER Q STRING the cf-install.sh script in your path Q ENTER Q CTRL C Q STRING ls -ls cfengine-install.sh Q ENTER LED G LED FINISH
On the host once the Bashbunny finishes please run the following sequence to get fully bootsrapped to the cf-serverd running inside the Bashbunny.
# /etc/init.d/cfengine3 status cf-execd is not running cf-serverd is not running cf-monitord is not running # /etc/init.d/cfengine3 start No policy found in /var/cfengine/inputs/promises.cf, not starting core daemons # cp -r /var/cfengine/masterfiles/* /var/cfengine/inputs/ # /etc/init.d/cfengine3 start Starting cf-execd... Starting cf-serverd... Starting cf-monitord... #cf-agent --bootstrap 172.16.64.1
Attaching a video demonstration of the Bashbunny and CFEngine