diff --git a/tests/discovery/test_linkedin_links.py b/tests/discovery/test_linkedin_links.py new file mode 100644 index 00000000..2dc6f3dc --- /dev/null +++ b/tests/discovery/test_linkedin_links.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# coding=utf-8 +from theHarvester.discovery import linkedinsearch +import pytest + + +class TestGetLinks(object): + + def test_get_links(self): + search = linkedinsearch.SearchLinkedin("facebook.com", '100') + search.process() + links = search.get_links() + for link in links: + print(link) + + +if __name__ == '__main__': + pytest.main() diff --git a/theHarvester/__main__.py b/theHarvester/__main__.py index bbd47caf..eefeed22 100644 --- a/theHarvester/__main__.py +++ b/theHarvester/__main__.py @@ -34,12 +34,13 @@ def start(): parser.add_argument('-c', '--dns-brute', help='perform a DNS brute force on the domain', default=False, action='store_true') parser.add_argument('-f', '--filename', help='save the results to an HTML and/or XML file', default='', type=str) parser.add_argument('-b', '--source', help='''baidu, bing, bingapi, censys, crtsh, dnsdumpster, - dogpile, duckduckgo, exalead, github-code, google, + dogpile, duckduckgo, github-code, google, hunter, intelx, - linkedin, netcraft, securityTrails, threatcrowd, - trello, twitter, vhost, virustotal, yahoo''') - args = parser.parse_args() + linkedin, linkedin_links, netcraft, securityTrails, threatcrowd, + trello, twitter, vhost, virustotal, yahoo, all''') + parser.add_argument('-x', '--exclude', help='exclude options when using all sources', type=str) + args = parser.parse_args() try: db = stash.stash_manager() db.do_init() @@ -282,6 +283,23 @@ def start(): for user in sorted(list(set(people))): print(user) + elif engineitem == 'linkedin_links': + print('\033[94m[*] Searching Linkedin. \033[0m') + from theHarvester.discovery import linkedinsearch + search = linkedinsearch.SearchLinkedin(word, limit) + search.process() + people = search.get_links() + db = stash.stash_manager() + db.store_all(word, people, 'name', 'linkedin') + + if len(people) == 0: + print('\n[*] No links found Linkedin.\n\n') + else: + print(f'\n[*] Links found: {len(people)}') + print('---------------------') + for user in sorted(list(set(people))): + print(user) + elif engineitem == 'netcraft': print('\033[94m[*] Searching Netcraft. \033[0m') from theHarvester.discovery import netcraft diff --git a/theHarvester/discovery/linkedinsearch.py b/theHarvester/discovery/linkedinsearch.py index d59d14fd..22a58699 100644 --- a/theHarvester/discovery/linkedinsearch.py +++ b/theHarvester/discovery/linkedinsearch.py @@ -34,6 +34,10 @@ class SearchLinkedin: rawres = myparser.Parser(self.totalresults, self.word) return rawres.people_linkedin() + def get_links(self): + links = myparser.Parser(self.totalresults, self.word) + return links.links_linkedin() + def process(self): while self.counter < self.limit: self.do_search() diff --git a/theHarvester/lib/core.py b/theHarvester/lib/core.py index ff3a18a1..7cc13be7 100644 --- a/theHarvester/lib/core.py +++ b/theHarvester/lib/core.py @@ -77,6 +77,7 @@ class Core: 'hunter', 'intelx', 'linkedin', + 'linkedin_links', 'netcraft', 'securityTrails', 'threatcrowd', diff --git a/theHarvester/parsers/myparser.py b/theHarvester/parsers/myparser.py index 7e809e61..09c8f825 100644 --- a/theHarvester/parsers/myparser.py +++ b/theHarvester/parsers/myparser.py @@ -77,11 +77,20 @@ class Parser: hostnames = self.unique() return hostnames + def links_linkedin(self): + reg_links = re.compile(r"url=https:\/\/www\.linkedin.com(.*?)&") + self.temp = reg_links.findall(self.results) + resul = [] + for x in self.temp: + y = x.replace("url=", "") + resul.append("https://www.linkedin.com" + y) + return set(resul) + def people_linkedin(self): reg_people = re.compile(r'">[a-zA-Z0-9._ -]* \| LinkedIn') self.temp = reg_people.findall(self.results) resul = [] - for x in self.temp: + for x in (self.temp): y = x.replace(' | LinkedIn', '') y = y.replace(' profiles ', '') y = y.replace('LinkedIn', '')