Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update DNSTwist to use the pe-reports module and run on all P&E orgs #1988

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion backend/Dockerfile.worker
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ RUN apt remove dav1d && apt autoclean && apt autoremove

# Install pe-source module
# Sync the latest from cf-staging branch
RUN git clone -b cf-source-staging https://github.com/cisagov/pe-reports.git && cd pe-reports && git checkout c9cbbd73b22ef38cabe1da6ba50aeb2dc0be4f99 && sed -i 's/"pandas == 1.1.5"/"pandas == 1.5.1"/g' setup.py && sed -i 's/psycopg2-binary == 2.9.3/psycopg2-binary == 2.9.5/g' setup.py && sed -i 's/psycopg2-binary == 2.9.3/psycopg2-binary == 2.9.5/g' setup_reports.py && pip install .
RUN git clone -b cf-source-staging https://github.com/cisagov/pe-reports.git && cd pe-reports && git checkout eedd406b8ce92519c8bbd8672b86cf000ba38af4 && sed -i 's/"pandas == 1.1.5"/"pandas == 1.5.1"/g' setup.py && sed -i 's/psycopg2-binary == 2.9.3/psycopg2-binary == 2.9.5/g' setup.py && sed -i 's/psycopg2-binary == 2.9.3/psycopg2-binary == 2.9.5/g' setup_reports.py && pip install .
# Python dependencies

COPY worker/requirements.txt worker/requirements.txt
Expand Down
2 changes: 1 addition & 1 deletion backend/src/api/scans.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ export const SCAN_SCHEMA: ScanSchema = {
dnstwist: {
type: 'fargate',
isPassive: true,
global: false,
global: true,
cpu: '2048',
memory: '16384',
description:
Expand Down
116 changes: 11 additions & 105 deletions backend/src/tasks/dnstwist.ts
Original file line number Diff line number Diff line change
@@ -1,111 +1,17 @@
import { connectToDatabase, Domain, Vulnerability } from '../models';
import getRootDomains from './helpers/getRootDomains';
import { CommandOptions } from './ecs-client';
import { plainToClass } from 'class-transformer';
import saveVulnerabilitiesToDb from './helpers/saveVulnerabilitiesToDb';
import { spawnSync } from 'child_process';
import saveDomainsToDb from './helpers/saveDomainsToDb';
import * as dns from 'dns';

async function runDNSTwist(domain: string) {
const child = spawnSync(
'dnstwist',
['-r', '--tld', './worker/common_tlds.dict', '-f', 'json', domain],
{
stdio: 'pipe',
encoding: 'utf-8'
}
);
const savedOutput = child.stdout;
const finalResults = JSON.parse(savedOutput);
console.log(
`Got ${
Object.keys(finalResults).length
} similar domains for root domain ${domain}`
);
return finalResults;
}
import { getPeEnv } from './helpers/getPeEnv';

export const handler = async (commandOptions: CommandOptions) => {
const { organizationId, organizationName } = commandOptions;
await connectToDatabase();
const dateNow = new Date(Date.now());
console.log('Running dnstwist on organization', organizationName);
const root_domains = await getRootDomains(organizationId!);
const vulns: Vulnerability[] = [];
console.log('Root domains:', root_domains);
for (const root_domain of root_domains) {
try {
const results = await runDNSTwist(root_domain);

// Fetch existing domain object
let domain = await Domain.findOne({
organization: { id: organizationId },
name: root_domain
});

if (!domain) {
let ipAddress;
const new_domain: Domain[] = [];
try {
ipAddress = (await dns.promises.lookup(root_domain)).address;
} catch (e) {
ipAddress = null;
}
new_domain.push(
plainToClass(Domain, {
name: root_domain,
ip: ipAddress,
organization: { id: organizationId }
})
);
await saveDomainsToDb(new_domain);
domain = await Domain.findOne({
organization: { id: organizationId },
name: root_domain
});
}

// Fetch existing dnstwist vulnerability
const existingVuln = await Vulnerability.findOne({
domain: { id: domain?.id },
source: 'dnstwist'
});
console.log('Running dnstwist on P&E organizations');

// Map date-first-observed to any domain-name that already exists
const existingVulnsMap = {};
if (existingVuln) {
for (const domain of existingVuln.structuredData['domains']) {
existingVulnsMap[domain['domain']] = domain['date_first_observed'];
}
}
// If an existing domain-name is in the new results, set date-first-observed to the mapped value
// Else, set date-first-observed to today's date (dateNow)
for (const domain of results) {
domain['date_first_observed'] =
existingVulnsMap[domain['domain']] || dateNow;
}
if (Object.keys(results).length !== 0) {
vulns.push(
plainToClass(Vulnerability, {
domain: domain,
lastSeen: new Date(Date.now()),
title: 'DNS Twist Domains',
state: 'open',
source: 'dnstwist',
severity: 'Low',
needsPopulation: false,
structuredData: { domains: results },
description: `Registered domains similar to ${root_domain}.`
})
);
await saveVulnerabilitiesToDb(vulns, false);
} else {
continue;
}
} catch (e) {
console.error(e);
continue;
}
}
const child = spawnSync('python', ['-m', 'pe_source', 'dnstwist'], {
stdio: 'inherit',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should remove dnstwist from dockerfile

encoding: 'utf-8',
env: {
...getPeEnv()
},
cwd: '/app/pe-reports'
});
console.log('Done');
};
7 changes: 7 additions & 0 deletions backend/src/tasks/helpers/getPeEnv.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Gets PE environment variables to send to PE scripts.
export const getPeEnv = () => ({
DB_HOST: process.env.DB_HOST!,
PE_DB_NAME: process.env.PE_DB_NAME!,
PE_DB_USERNAME: process.env.PE_DB_USERNAME!,
PE_DB_PASSWORD: process.env.PE_DB_PASSWORD!
});
Loading