I’ve been spending a bit of time playing with the LUA functionality of Power DNS, it was inevitable that I got round to implementing a generic shell over DNS. It’s not very polished it doesn’t like interactive commands or commands with odd characters and it is more insecure than a very insecure thing that isn’t very safe. It is however a surprisingly short amount of code for what it does.
There are a very few circumstances I can think of where a very restricted version of this might be useful, but really there’s always going to be a better and more sensible option. However it’s an interesting proof of concept and more importantly it was fun. If you don’t understand this code do not use it , if you do understand this code you know why you don’t want to use it.
The code as shown below won’t actually work if you just put it into a file and call it from PDNS. If you need any help in making this work then you really shouldn’t be touching this – not even with someone elses barge pole.
This code just takes a DNS query made to the PDNS server running the code removes the “.command”, replaces underscores with spaces and then runs it, returning the output as a DNS response. If you can’t work out the query type well shame on you.
-- Look for the super special domain ".command" the command to run pre-pends this
if string.find(domain,".command.$") then
-- get rid of our super special domain name
myrun=string.gsub(domain,".command.","")
-- Replace all the "_" characters with " "
myfix=string.gsub(myrun,"_"," ")
--- run the command - note the lack of sanity checking or security
myopen=io.popen(myfix)
-- start the return array
ret={}
-- put each line of response from our command into the array
for line in myopen:lines()do
ret[#ret + 1] = {qtype=16, content="\""..line.."\"", ttl=3}
end
-- OK with luck the command exited so just return what ever we've got
return 0, ret
-- That's it job done.
end