#!/usr/bin/python3# -*- coding: utf-8 -*-# Author: Erdog, Loveforkeeps, Allukaimport base64import jsonimport loggingimport requestsimport osimport sysfrom retry.api import retry_callif __name__ == '__main__': # 当作为脚本直接执行时的处理方式 from exception import FofaError from helper import get_language, encode_queryelse: # 当作为包/模块导入时的处理方式 from .exception import FofaError from .helper import get_language, encode_queryif __name__ == "__main__": client = Client() logging.basicConfig(level=logging.DEBUG) print(client.can_use_next()) print(json.dumps(client.get_userinfo(), ensure_ascii=False)) print(json.dumps(client.search('app="网宿科技-公司产品"', page=1), ensure_ascii=False)) print(json.dumps(client.search_host('78.48.50.249', detail=True), ensure_ascii=False)) print(json.dumps(client.search_stats('domain="baidu.com"', fields='title'), ensure_ascii=False))[docs]class Client: """ A class representing the FOFA client. :param key: The Fofa api key. If not specified, it will be read from the FOFA_KEY environment variable. :type key: str :param base_url: The base URL of the FOFA API. Defaults to 'https://fofa.info'. :type base_url: str :param proxies: A proxies array for the requests library, e.g. {'https': 'your proxy'} :type proxies: dict """ def __init__(self, key='', base_url='', proxies=None): """ Initialize the FOFA client. """ key = os.environ.get('FOFA_KEY', '') if base_url == '': base_url = os.environ.get('FOFA_BASE_URL', 'https://fofa.info') self.key = key self.base_url = base_url.rstrip('/') self.lang = 'en' sys_lang = get_language() if sys_lang != None and sys_lang.startswith('zh'): self.lang = 'zh-CN' self._session = requests.Session() if proxies: self._session.proxies.update(proxies) self._session.trust_env = False # retry config, in seconds self.tries = 5 # Number of retry attempts self.delay = 1 # Initial delay between retries self.max_delay = 60 # Maximum delay between retries self.backoff = 2 # Backoff factor for exponential backoff
[docs] def get_userinfo(self): """ Get user info for current user. :return: User information in JSON format. :rtype: dict :raises FofaException: If an error occurs during the API request. :Example: The returned JSON result will be in the following format: .. code-block:: json { "username": "sample", "fofacli_ver": "4.0.3", "fcoin": 0, "error": false, "fofa_server": true, "avatar": "https://nosec.org/missing.jpg", "vip_level": 0, "is_verified": false, "message": "", "isvip": false, "email": "username@sample.net" } """ return self.__do_req( "/api/v1/info/my")
[docs] def search(self, query_str, page=1, size=100, fields="", opts={}): """ Search data in FOFA. :param query_str: The search query string. Example 1: 'ip=127.0.0.1' Example 2: 'header="thinkphp" || header="think_template"' :type query_str: str :param page: Page number. Default is 1. :type page: int :param size: Number of results to be returned in one page. Default is 100. :type size: int :param fields: Comma-separated list of fields to be included in the query result. Example: 'ip,city' :type fields: str :param opts: Additional options for the query. This should be a dictionary of key-value pairs. :type opts: dict :return: Query result in JSON format. :rtype: dict .. code-block:: json { "results": [ [ "111.**.241.**:8111", "111.**.241.**", "8111" ], [ "210.**.181.**", "210.**.181.**", "80" ] ], "mode": "extended", "error": false, "query": "app=\\"网宿科技-公司产品\\"", "page": 1, "size": 2 } """ param = opts param['qbase64'] = encode_query(query_str) param['page'] = page param['fields'] = fields param['size'] = size logging.debug("search '%s' page:%d size:%d", query_str, page, size) return self.__do_req('/api/v1/search/all', param)
[docs] def can_use_next(self): """ Check if the "search_next" API can be used. :return: True if the "search_next" API can be used, False otherwise. :rtype: bool """ try: self.search_next('bad=query', size=1) except FofaError as e: if e.code == 820000: return True return False
[docs] def search_next(self, query_str, fields='', size=100, next='', full=False, opts={}): """ Query the next page of search results. :param query_str: The search query string. Example 1: 'ip=127.0.0.1' Example 2: 'header="thinkphp" || header="think_template"' :param fields: The fields to be included in the response. Default: 'host,ip,port' :type fields: str :param size: The number of results to be returned per page. Default: 100 Maximum: 10,000 :type size: int :param next: The ID for pagination. The next value is returned in the response of previous search query. If not provided, the first page of results will be returned. :type next: str :param full: Specify if all data should be searched. Default: False (search within the past year) Set to True to search all data. :type full: bool :param opts: Additional options for the search. :type opts: dict :return: The query result in JSON format. :rtype: dict """ param = opts param['qbase64'] = encode_query(query_str) param['fields'] = fields param['size'] = size param['full'] = full if next and next != '': param['next'] = next logging.debug("search next for '%s' size:%d, next:%s", query_str, size, next) return self.__do_req('/api/v1/search/next', param)
[docs] def search_stats(self, query_str, size=5, fields='', opts={}): """ Query the statistics of the search results. :param query_str: The search query string. Example 1: 'ip=127.0.0.1' Example 2: 'header="thinkphp" || header="think_template"' :type query_str: str :param size: The number of results to be aggregated for each item. Default: 5 :type size: int :param fields: The fields to be included in the aggregation. Example: 'ip,city' :type fields: str :param opts: Additional options for the search. :type opts: dict :return: query result in json format .. code-block:: json { "distinct": { "ip": 1717, "title": 411 }, "lastupdatetime": "2022-06-17 13:00:00", "aggs": { "title": [ { "count": 35, "name": "百度一下,你就知道" }, { "count": 25, "name": "百度网盘-免费云盘丨文件共享软件丨超大容量丨存储安全" }, { "count": 16, "name": "百度智能云-登录" }, { "count": 2, "name": "百度翻译开放平台" } ], "countries": [] }, "error": false } """ param = opts param['qbase64'] = encode_query(query_str) param['fields'] = fields param['size'] = size return self.__do_req('/api/v1/search/stats', param)
[docs] def search_host(self, host, detail=False, opts={}): """ Search for host information based on the specified IP address or domain. :param host: The IP address or domain of the host to search for. :type host: str :param detail: Optional. Specifies whether to show detailed information. Default is False. :type detail: bool :param opts: Optional. Additional options for the search. Default is an empty dictionary. :type opts: dict :return: The query result in JSON format. :rtype: dict .. code-block:: json { "error": false, "host": "78.48.50.249", "ip": "78.48.50.249", "asn": 6805, "org": "Telefonica Germany", "country_name": "Germany", "country_code": "DE", "protocol": [ "http", "https" ], "port": [ 80, 443 ], "category": [ "CMS" ], "product": [ "Synology-WebStation" ], "update_time": "2022-06-11 08:00:00" } """ param = opts param['detail'] = detail u = '/api/v1/host/%s' % host return self.__do_req(u, param)
def __do_req(self, path, params=None, method='get'): u = self.base_url + path data = None req_param = {} if not self.key or self.key == '': raise FofaError("Empty fofa api key") if params == None: req_param = { "key": self.key, "lang": self.lang, } else: req_param = params req_param['key'] = self.key req_param['lang'] = self.lang if method == 'post': data = params params = None def make_request(): headers = {"Accept-Encoding": "gzip"} response = self._session.request(url=u, method=method, data=data, params=req_param, headers=headers) if response.status_code != 200: raise Exception("Request failed with status code: {}".format(response.status_code)) return response res = retry_call(make_request, tries = self.tries, delay = self.delay, max_delay = self.max_delay, backoff=self.backoff) data = res.json() if 'error' in data and data['error']: raise FofaError(data['errmsg']) return data
fofa.client — FOFA 2.0.0 documentation (2024)
Top Articles
Kaufen Sie täglich grüne Kontaktlinsen - JADE
Shoppen Sie grüne 6-Monats-Kontaktlinsen – JADE
Shoppen Sie grüne Monats-Kontaktlinsen – JADE
Latest Posts
Junshi Biosciences Announces UK MHRA Approval for Marketing of Toripalimab
Baldur's Gate Ii: Shadows Of Amn 120 Fps Ps5
Recommended Articles
- Search Anime - MyAnimeList.net
- Craig T Nelson Movies, Bio, Wiki, Age, Wife, and Net Worth
- When The Devil Takes Hold Lines
- 9 of the Very Best Tweezers for Hair Removal
- Ian Bryce Fans
- Ketone Testing - How To Test for Ketones & Ketone Test Levels
- Alarm Für Cobra 11 - Die Autobahnpolizei English Movie
- Wheelchair Vans Available for Delivery in Fort Wayne, IN
- Metal Slug Anthology Pc Specs
- Ouji To Majo To Himegimi To Season 2 Ep 5 Release Date
- Hajimari No Boukensha-Tachi: Legend Of Crystania Season 2 Episode 22
- Bloodborne Pathogens | EHS
- 5 Best Eyelid Tapes – Unbiased Review
- [Top 10] Jujutsu Kaisen Most Powerful Characters (Ranked)
- 5 Best Skin Moisture Analyzers - Dec. 2024 - BestReviews
- Sizes of Tattoos: A Pro's Guide with Examples (2022 Updated) - Hero Tattoo
- Phenolic Compounds in Tea: Phytochemical, Biological, and Therapeutic Applications
- Why Is All You Need Is Love (2015) So Popular
- Gozen No Mori Season 3 Episode 6 Release Date
- What Is Melody Of Love (2024) Movie About
- What Genre Is Judge Vs. Judge
- Ginga Eiyuu Densetsu: Die Neue These 4Th Season Episode 12 English
- When Did Samurai Cat Book Come Out
- Richard Dix From
- God Troubles Me 2Nd Season Ep 22 Eng Dub
- Cast In I Love You, Beth Cooper (2009)
- Your Guide to Professional Toenail Clippers
- Tumblr Soshite, Hare Ni Naru
- What Happened After Inmu 2: Flesh Dreams (2001)
- NAILS’ Guide to Electric Filing
- Pixeline Skolebøger: Dansk Animated Series
- When Did Claire Shanley Became Famous
- Razors Made in the USA | The GREAT American Made Brands & Products Directory - Made in the USA Matters
- Sonoya Mizuno, star of 'Devs,' is poised to conquer the multiverse
- G64 Max Money
- Deron Street Sucking
- When Does The Next Season Of Ppta Come Out
- Watch Flame Of Recca: Final Burning Episode 7
- The Pier Streaming
- Kathryn Beaumont Soles
- Can You Play Negligee: Love Stories On Iphone
- Pożegnanie Sepultury w katowickim Spodku. Zespół zaskoczył fanów [RELACJA]
- 12 Korean Sunscreens You Need In Your Skincare Routine ASAP
- Journal of Computer Science IJCSIS April 2017 Part II.pdf
- ITCCA - Maastricht - School voor Tai Chi Chuan - De originele Yang stijl
- Reviews Of Secret Of The Midwife (2016)
- Tchia: Oléti Edition Outbreak
- Fotos Actuales De Wendy Rice
- Is When Hitchcock Met O'casey (2019) On Hbo Max
- Vektor Tank Support Ticket
- Who Wrote 倾城之恋 Novel
- Who Played In The Smart Money Woman
- Alien Encounters: Fact or Fiction: Season 1, Episode 6 | Rotten Tomatoes
- The Best Eco-Friendly, Non-Toxic Nail Polish Removers - The Filtery
- Rayman: The Animated Series - WikiMili, The Best Wikipedia Reader
- Izabel London Nagellack Beauty Expert Lab Ethyl Acetate Base & Top Coat Nagellack 02 10 ml
- Hottest Madeleine Stowe Pictures
- Jenifer FitzGibbon Profile - New jobs in Oromia 2024, vacancies in Oromia, Oromiajobs | Oromia jobs
- The Wizard Of Oz (1939) Novel
- How To Watch Ramez The Sea Shark Us
- Blades Of Steel Hairstyle
- Every Skincare Routine Should Start with a Quality Cleanser – Here Are 19 We Rate
- Stichting Cultuurbehoud Westkapelle - Tradities/way of life
- Yakuza Reincarnation: Yakuza Princess Of Another World Live Action Where To Watch
- Get Aim Assist - Microsoft Store
- Sekai Meisaku Douwa: Hakuchou No Ouji 21.Rész
- 10 Beginner Tips For Cobra Kai 2: Dojos Rising
- Magnetic Eyelashes | Ulta Beauty
- Chia Anime Tenkuu Seiryuu
- Ruler's Reign Atlantis
- Heroes Of Might & Magic Iii: Hd Edition Can't Join Friends
- Unlocking the Power of Apple Cider Vinegar for Rapid Weight Lo · Customer Self-Service
- Cardfight!! Vanguard: will+Dress
- Iyayoiyayo Mo Kiss No Uchi Pictures
- Hetare Maou To Tsundere Yuusha+
- Satomi Hakkenden Hamaji Hime No Ki Owner
- Strongest Cike Wuliuqi Characters Reddit
- Evil Apples: Dirty As ____. App Store
- Black Friday Meow Wars: Card Battle
- How To Get Word Ace On Switch
- Pokémon Bushido Tips And Tricks 2023
- Le Concert Elitepvpers
- What Makes Marionette Mansion One of Junji Ito's Most CHILLING Stories
- Who Composed Emperor Akihito
- Chicago Sky Announce 2025 Season Schedule
- Chicago Sky Announce 2025 Season Schedule
- Chicago Sky Announce 2025 Season Schedule
- Chicago Sky Announce 2025 Season Schedule
- Chicago Sky Announce 2025 Season Schedule
- How To Use Bobby Pins Without Pulling Your Hair Out
- Psycho-Pass 3: First Inspector Staffel 4 Episode 41
- Скачать GeForce Experience | NVIDIA
- REO Speedwagon's 10 greatest songs, ranked
- Potency Assays for Cell and Gene Therapy
- Kamek's Island All Versions
- Article: Exploring the Untamed Frontier: A Journey Through Iconic Wild West Literature
- Khara, Sunrise Produce 'Kidou Senshi Gundam: GQuuuuuuX' TV Anime
- Princess Maker 2 Regeneration Review (Switch) - Hey Poor Player
Article information
Author: Clemencia Bogisich Ret
Last Updated:
Views: 5999
Rating: 5 / 5 (60 voted)
Reviews: 83% of readers found this page helpful
Author information
Name: Clemencia Bogisich Ret
Birthday: 2001-07-17
Address: Suite 794 53887 Geri Spring, West Cristentown, KY 54855
Phone: +5934435460663
Job: Central Hospitality Director
Hobby: Yoga, Electronics, Rafting, Lockpicking, Inline skating, Puzzles, scrapbook
Introduction: My name is Clemencia Bogisich Ret, I am a super, outstanding, graceful, friendly, vast, comfortable, agreeable person who loves writing and wants to share my knowledge and understanding with you.