Skip to content

Instantly share code, notes, and snippets.

@snehesht
Last active July 4, 2019 06:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save snehesht/b6eeb376f53832cb08becd416c0beb22 to your computer and use it in GitHub Desktop.
Save snehesht/b6eeb376f53832cb08becd416c0beb22 to your computer and use it in GitHub Desktop.
Lie to DNS requests
#!/bin/sh
# Forked from https://gitlab.com/moviuro/moviuro.bin/blob/master/lie-to-me
set -e
_target="127.0.0.1"
_format="unbound"
__usage () {
cat << EOF
$0 [-d] [-f format] [-o out] [-t target]
$0 -h
Create a lying DNS file for the specified format.
o -d: enable debug (set -x)
o -f format: specify an output format.
Supported formats are:
- unbound
- bind
- hosts (see hosts(5))
- none (one hostname per line)
Default: $_format
o -o out: specify an output file.
Default: <stdout>
o -t target: specify the target
Default: $_target
EOF
}
while getopts ":df:ho:t:" _opt; do
case "$_opt" in
d) set -x ;;
f) _format="$OPTARG" ;;
h) __usage; exit 0 ;;
o) _output_file="$OPTARG" ;;
t) _target="$OPTARG" ;;
*) __usage >&2 ; exit 1 ;;
esac
done
shift "$((OPTIND-1))"
true() {
:
}
# first choice is curl(1), should be OK for Linux
if command -v curl >/dev/null 2>&1; then
__download () {
curl -s "$1"
}
# second is fetch(1), for FreeBSD
elif command -v fetch >/dev/null 2>&1; then
__download () {
fetch -q -o - "$1"
}
# last comes ftp(1), which does far more than its name implies (OpenBSD only)
elif [ "$(uname -s)" = OpenBSD ] && command -v ftp >/dev/null 2>&1; then
__download () {
ftp -o - "$1"
}
else
printf '%s\n' "Oh no! You don't seem to have curl(1) or fetch(1)" >&2
printf '%s\n' "I'm cowardly exiting" >&2
exit 4
fi
# If we're here, we're actually going to do something
_temp_dir="$(mktemp -d -t "$(basename "$0").XXXXXX")"
_temp="$_temp_dir/hosts"
_temp_ack="$_temp_dir/acks"
__cleanup () {
[ -d "$_temp_dir" ] && rm -fr "$_temp_dir"
}
trap __cleanup INT TERM
__add_hosts () {
printf '# Original file at %s\n' "$1" >> "$_temp_ack"
__download "$1" | awk "/^$2 / "'{ print $2 }' >> "$_temp"
}
__add_simple () {
printf '# Original file at %s\n' "$1" >> "$_temp_ack"
# We only want the lines that are not comments, and we don't fail on empty files
__download "$1" | grep -e '^[^\#]' >> "$_temp" || true
}
__to_unix () {
# We remove weird characters
tr -d '\r' < "$_temp" |
# We cast everything to lower-case
tr '[:upper:]' '[:lower:]' |
# We ignore lines with spaces or empty lines
grep -vE '( |^$)' |
# We sort the file
sort -u > "$_temp".2
# We replace the original file
mv "$_temp".2 "$_temp"
}
__to_output () {
if [ -z "$_output_file" ]; then
cat -
else
if [ -e "$_output_file" ]; then
# just in case something goes wrong
# I wrote that script though. It shouldn't go wrong.
# Right...?
cp "$_output_file" "$_output_file".bak
fi
cat - > "$_output_file"
fi
}
__headers () {
:
}
# We define the __to_format function that properly prints the host redirection
# in the specified form.
# Usage: __to_format "host" "target"
# Example: __to_format "example.com" "10.10.10.10"
case "$_format" in
"unbound")
__to_format () {
printf 'local-zone: "%s" redirect\n' "$1"
printf 'local-data: "%s A %s"\n' "$1" "$2"
}
;;
"none")
__to_format () {
printf '%s\n' "$1"
}
;;
"bind")
echo "I do NOT include the headers in $_output_file" >&2
__to_format () {
printf '%s. IN A %s\n' "$1" "$2"
}
;;
"hosts")
__to_format () {
printf '%s %s\n' "$2" "$1"
}
__headers () {
printf '%s\n' "# /etc/hosts: static lookup table for host names"
printf '\n'
printf '%s %s %s\n' "127.0.0.1" "localhost.localdomain" "localhost"
printf '%s %s %s\n' "::1" "localhost.localdomain" "localhost"
printf '\n'
}
;;
esac
__add_simple "https://ransomwaretracker.abuse.ch/downloads/RW_DOMBL.txt"
__add_simple "https://ransomwaretracker.abuse.ch/downloads/CW_C2_DOMBL.txt"
__add_simple "https://ransomwaretracker.abuse.ch/downloads/CW_PS_DOMBL.txt"
__add_simple "https://ransomwaretracker.abuse.ch/downloads/TC_C2_DOMBL.txt"
__add_simple "https://ransomwaretracker.abuse.ch/downloads/TC_PS_DOMBL.txt"
__add_simple "https://ransomwaretracker.abuse.ch/downloads/LY_C2_DOMBL.txt"
__add_simple "https://ransomwaretracker.abuse.ch/downloads/LY_PS_DOMBL.txt"
__add_simple "https://ransomwaretracker.abuse.ch/downloads/TL_C2_DOMBL.txt"
__add_simple "https://ransomwaretracker.abuse.ch/downloads/TL_PS_DOMBL.txt"
__add_simple \
"https://palevotracker.abuse.ch/blocklists.php?download=domainblocklist"
__add_simple "https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt"
__add_simple "https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt"
__add_simple "https://s3.amazonaws.com/lists.disconnect.me/simple_malware.txt"
__add_simple "https://s3.amazonaws.com/lists.disconnect.me/simple_malvertising.txt"
__add_hosts "http://someonewhocares.org/hosts/hosts" '127\.0\.0\.1'
__add_hosts "http://winhelp2002.mvps.org/hosts.txt" '0\.0\.0\.0'
__add_hosts "https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts" \
'0\.0\.0\.0'
__add_hosts \
"http://pgl.yoyo.org/adservers/serverlist.php?hostformat=hosts&mimetype=plaintext" \
'127\.0\.0\.1'
__add_hosts "https://zeustracker.abuse.ch/blocklist.php?download=hostfile" \
'127\.0\.0\.1'
__add_hosts "https://www.malwaredomainlist.com/hostslist/hosts.txt" \
'127\.0\.0\.1'
__to_unix
{ # We print the headers too, if we know how to do it
__headers
# We print the acks first
cat "$_temp_ack"
while IFS= read -r _host; do
__to_format "$_host" "$_target"
done
} < "$_temp" | __to_output
__cleanup
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment