Ошибка атрибута ожидания Python. «NoneType» не имеет атрибута «линия отправки»

Написание скрипта с использованием Pexpect для подключения через ssh, но он выдает ошибку атрибута.

import pexpect
PROMPT = ['# ', '>>> ', '> ', '\$ ', '~# ']
def send_command(child, cmd):
    child.sendline(cmd)
    child.expect(PROMPT)
    print child.before, child.after
def connect(user, host, password):
    ssh_newkey = 'Are you sure you want to continue connecting (yes/no)?'
    connStr = 'ssh ' + user + '@' + host
    child = pexpect.spawn(connStr)
    ret = child.expect([ssh_newkey, 'password:'])
    if ret == 0:
        print '[-] Error Connecting'
        return
    elif ret == 1:
        child.sendline('yes')
        ret = child.expect('password:')
        if ret == 0:
            print '[-] Error Connecting'
            return
    child.sendline(password)
    child.expect(PROMPT)
    return child
def main():
    host = 'test.rebex.net'
    user = 'demo'
    password = 'password'
    child = connect(user, host, password)
    send_command(child, 'cat /etc/shadow | grep root')
if __name__ == '__main__':
    main()

Я получаю следующую ошибку:

[-] Error Connecting
Traceback (most recent call last):
  File "./bruteSSH.py", line 33, in <module>
    main()
  File "./bruteSSH.py", line 31, in main
    send_command(child, 'cat /etc/shadow | grep root')
  File "./bruteSSH.py", line 6, in send_command
    child.sendline(cmd)
AttributeError: 'NoneType' object has no attribute 'sendline'

Я считаю, что это как-то связано с тем, что мой дочерний объект является «NoneType», но я не могу определить, что я делаю неправильно.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
675
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Прежде всего, ваш отступ неверен на 6-й строке.

Это вызывает эту ошибку, потому что дочерний объект еще не был правильно настроен и успешно подключен.

Если это именно ваш код, то проблема в том, что "child.sendline()" выполняется вне функции, тогда как child является локальной переменной внутри функции "send_command" поэтому глобально дочерняя переменная еще не определена

в моем фактическом коде он имеет правильный отступ, я исправил это в своем вопросе.

jstamp 23.06.2019 06:33
Ответ принят как подходящий

Вы не возвращаете значение для нескольких условий. Вот где вы получаете свой None и что вызывает вашу ошибку. См. прокомментированные строки ниже:

if ret == 0:
    print '[-] Error Connecting'
    return  # THIS WILL CAUSE YOUR ERROR

elif ret == 1:
    child.sendline('yes')
    ret = child.expect('password:')
    if ret == 0:
        print '[-] Error Connecting'
        return  # THIS WILL ALSO CAUSE YOUR ERROR

Но ваша логика в любом случае ущербна. Expect возвращает 0 или индекс совпадения, если вы передаете ему массив. В вашем коде вы передаете ему массив. Таким образом, возвращаемое значение 0 указывает на то, что оно успешно соответствует вашей первой записи — условию «Вы уверены». Если вы соответствуете этому, вы хотите отправить «да». Ниже больше того, что, как я думаю, вам нужно...

import pexpect
PROMPT = ['# ', '>>> ', '> ', '\$ ', '~# ']
def send_command(child, cmd):
    child.sendline(cmd)
    child.expect(PROMPT)
    print child.before, child.after

def connect(user, host, password):
    ssh_newkey = 'Are you sure you want to continue connecting (yes/no)?'
    connStr = 'ssh ' + user + '@' + host
    child = pexpect.spawn(connStr)
    ret = child.expect(['password:', ssh_newkey])
    if ret == 1:
        child.sendline('yes')
        ret = child.expect('password:')
    if ret != 0:
        print '[-] Error Connecting'
        return  # THIS WILL RETURN A NONE SO YOU SHOULD CHECK FOR IT.  SHOULD EXPLICITLY DO A return None TO MAKE IT CLEARER
    child.sendline(password)
    child.expect(PROMPT)
    return child

def main():
    host = 'localhost'
    user = 'demo'
    password = 'password'
    child = connect(user, host, password)
    if child is not None:
        send_command(child, 'cat /etc/shadow | grep root')
    else:
        print "Problem connecting!"

if __name__ == '__main__':
    main()

Проблема прямо перед вами. Когда вы сталкиваетесь с ошибкой в ​​функции подключения, как показано в операторе печати «[*] Error Connection», вы ничего не возвращаете. Только если соединение было успешным, оно возвращает дочерний объект, но поскольку соединение не удалось, вы возвращаете «нулевой объект» и выходите из своей функции. Вы не можете установить успешное соединение, и поэтому дочерний объект никогда не возвращается к вашей «дочерней» переменной в вашей основной функции. И вы передаете этот же «нулевой объект» своей send_command() и, следовательно, не работает


import sys

def connect(user, host, password):
    ssh_newkey = 'Are you sure you want to continue connecting (yes/no)?'
    connStr = 'ssh ' + user + '@' + host
    child = pexpect.spawn(connStr)
    ret = child.expect([ssh_newkey, 'password:'])
    if ret == 0:
        print '[-] Error Connecting'
        sys.exit()
    elif ret == 1:
        child.sendline('yes')
        ret = child.expect('password:')
        if ret == 0:
            print '[-] Error Connecting'
            sys.exit()
    child.sendline(password)
    child.expect(PROMPT)
    return child

Теперь ваша программа продолжит работу только в том случае, если соединение было успешным. Возможно, ожидания и пароль могут быть неправильными, общая проблема в том, что вы не можете установить успешное соединение.

Другие вопросы по теме