4
import shodan
import sys
from ConfigParser import ConfigParser

#grab the api key from auth.ini
config = ConfigParser()
config.read('auth.ini')
SHODAN_API_KEY = config.get('auth','API_KEY')

#initialize the api object
api = shodan.Shodan(SHODAN_API_KEY)\

# Input validation
if len(sys.argv) == 1:
        print 'Usage: %s <search query>' % sys.argv[0]
        sys.exit(1)

try:

        query = ' '.join(sys.argv[1:])
        parent = query
        exploit = api.Exploits(parent)
        #WHY DOESNT THIS WORK 
        #AttributeError: 'str' object has no attribute '_request'
        print exploit.search(query)

except Exception, e:
        print 'Error: %s' % e
        sys.exit(1)

I a using Python 2.7 I get the AttributeError: 'str' object has no attribute '_request' traceback error shows line 79 in client.py in the Shodan API, is it just me or is their code wonky?

here is the Traceback

Traceback (most recent call last):
  File "exploitsearch.py", line 26, in <module>
    print exploit.search('query')
  File "/usr/local/lib/python2.7/dist-packages/shodan/client.py", line 79, in search
    return self.parent._request('/api/search', query_args, service='exploits')
AttributeError: 'str' object has no attribute '_request'
Joshua Harper
  • 43
  • 1
  • 5
  • Clearly, you're passing a string - the command-line arguments joined with spaces - as the parent, whereas the Exploits class is expecting something else that has a _request parameter. You should read the documentation of your api to see what. – Daniel Roseman Oct 30 '15 at 16:55
  • 2
    I'm not familiar with Shodan, but it looks like you're supposed to use `api.exploits` instead of `api.Exploits`. – John Gordon Oct 30 '15 at 16:55

3 Answers3

3

I'm the founder of Shodan and author of the relevant library you're using. The correct answer is provided by John Gordon above:

You don't need to instantiate the Exploits class, it is done for you automatically when you create the Shodan() instance. This means that you can directly search for things without any extra work:

    api = shodan.Shodan(YOUR_API_KEY)
    results = api.exploits.search('apache')
achillean
  • 520
  • 4
  • 10
0

The parent variable should be of type Shodan. You are initializing the Exploits class with string variable. Here is the line you causing you the problems https://github.com/achillean/shodan-python/blob/master/shodan/client.py#L79.

mic4ael
  • 7,974
  • 3
  • 29
  • 42
0

Exploits is a subclass of the Shodan superclass. This class has a method called _request. When you initialize an instance of Exploits and execute the search method, the code internally calls the super (read: Shodan) method, _request. Since you pass a string type to the class constructor, it's attempting to call this method on the string object and (rightly) complains that the method isn't a member of str.

Here is the git repo. In line 79, you can see where this call is taking place:

return self.parent._request('/api/search', query_args, service='exploits')

Thus, you can see your parent variable should be an instance of Shodan, or your api variable.

TayTay
  • 6,882
  • 4
  • 44
  • 65