前言

在研究嵌入式设备的过程中经常需要向设备中上传二进制文件,这里总结一下上传文件的方法。

ftpd服务

busybox上自带ftpd服务,无身份验证,可以进行文件传输操作。
ftpd可通过设定inetd.conf由inetd启动,或者是使用tcpsvd作为单独的守护进程。

ftpd使用参数:

Usage: ftpd [-wvS] [-t N] [-T N] [DIR]

-w 允许上传
-v 打印错误信息
-S 错误信息写入SYSLOG
-t 多长时间无操作算作空闲(默认2分钟, 2 * 60)
-T 多长时间空闲后自动断开与客户端的连接(默认1小时,1 * 60 * 60)
DIR FTP根目录

tcpsvd可以建立TCP Socket,并将其绑定到某个程序上,命令格式如下:

Usage: tcpsvd [选项] IP PORT PROG [PROG ARGS]

IP: 要监听的IP地址
PORT: 要监听的端口
PROG: 要绑定的程序
PROG ARGS: 绑定应用的参数

选项:
    -l NAME, 本地主机名
    -u USER[:GRP], 绑定后切换到USER/GROUP
    -c N, 最大连接数
    -C N[:MSG] 同一个IP的最大连接数(MSG为超过时的响应信息)
    -v 打印详细输出

使用tcpsvd启动ftpd:

tcpsvd 0 21 ftpd -w /ftp_dir

或者配置/etc/inetd.conf:

21 stream tcp nowait root ftpd ftpd -w /ftp_dir

启动inetd服务:

/usr/sbin/inetd &

busybox内置tftpd服务器

服务端配置:

mkdir /tftp_dir
cp /bin/busybox /tftp_dir
udpsvd -vE 0 69 tftpd -c /tftp_dir &     #0表示对所有ip地址都进行侦听

客户端上传文件:

busybox tftp -l test.txt -r test.txt -p 192.168.1.100

客户端下载文件:

busybox tftp -l test.txt -r test.txt -g 192.168.1.100

利用python创建临时服务器

如果设备中安装了python的话就可以使用python脚本搭建一个临时服务器,供telnet访问:

import socket
import base64
port = 55555
filename = 'test.bin'

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('0.0.0.0', port))
sock.listen(5)
while True:
    connection,address = sock.accept()
    try:
        content = 'hello'
        f = file(filename)
        content = base64.b64encode(f.read())
        connection.sendall(content.strip())
        connection.close()
    except socket.timeout:
        print 'time out'
    connection.close()

将二进制文件编码成文本文件,输出到telnet,再写入文件通过python解码成二进制文件:

telnet 127.0.0.1 55555 | tee > temp.txt
tail -n +4 temp.txt > temp2.txt
base64 -d < temp2.txt | tee > test.bin

另外还有通过ssh服务来上传文件的方法,这里不赘述了

利用openssl实现二进制文件上传

之前需要往一个只拿到了telnet权限但没有ftp、ssh服务的设备上上传二进制文件。而且设备上没有python,busybox也没有带其他的解码工具,无法通过上面利用python搭服务器的方法上传文件了。

这时候想到openssl似乎有Base64编/解码的功能,那么就可以利用openssl来进行base64解码从而实现二进制文件上传操作。

将需要上传的文件进行base64编码

import base64

fin = open("./hello", "rb")
fout = open("./base64.txt", "w")

data = fin.read()
base64_str = base64.encodestring(data).decode('ascii')

fout.write(base64_str.replace("\n", "").replace("\r", ""))

fin.close()
fout.close()

用openssl命令行做base64解码

用openssl命令行做base64解码需要每64个字符换行一次,整个编码后字符串末尾也要有换行。且一次最大只能传2000行左右,超过需要分几次上传。用脚本进行编码字符串整理:

f = open('./base64.txt', 'r')
result = list()
i = 64
size = len(f.read())
f.seek(0,0)
lines = 1

while i < size:
    str1 = f.read(64)
    #print(str1)
    str2 = str1 + '\r'
    print(str2)
    result.append(str2)
    i = i + 64
    lines = lines + 1
    if i > size:
        str1 = f.read(size-i)
        #print(str1)
        str2 = str1 + '\r'
        print(str2)
        result.append(str2)
        lines = lines + 1


#print(result)
#print(len(result))

l = 0
num = 1
while l < lines:
    open('result' + str(num) + '.txt', 'w').write('%s' % '\n'.join(result[l:l+2000]))
    num = num + 1
    l = l + 2000
    if l > lines:
        open('result' + str(num) + '.txt', 'w').write('%s' % '\n'.join(result[l:]))

f.close()

传入编码字符串,用openssl进行解码并存入文件:

# echo "
> f0VMRgEBAQAAAAAAAAAAAAMACAABAAAAAAYAADQAAABMEwAABxAAcDQAIAAKACgA
> IgAhAAYAAAA0AAAANAAAADQAAABAAQAAQAEAAAUAAAAEAAAAAwAAAHQBAAB0AQAA
> dAEAAA0AAAANAAAABAAAAAEAAAADAABwqAEAAKgBAACoAQAAGAAAABgAAAAEAAAA
......
> " | openssl enc -base64 -d >> busybox_bak

通过python连接telnet传入文件

下面是用python实现上面手动传入编码字符串的脚本:

import getpass
import telnetlib

HOST = "192.168.1.100"
user = "admin"
password = "yourpasswd"

tn = telnetlib.Telnet(HOST)

tn.read_until(b"login: ")
tn.write(user.encode('ascii') + b"\n")
if password:
    tn.read_until(b"Password: ")
    tn.write(password.encode('ascii') + b"\n")

k = 13

filename = 'busybox'+ str(k) +'.txt'
f = open(filename, 'r')

tn.write(b"echo \"\n")
for i in range(0, 2000):
    str1 = f.readline().encode('ascii')
    tn.write(str1)
    #tn.write(b"\n")
    i = i + 1
tn.write(b"\"| openssl enc -base64 -d >> /ftp_dir/busybox_test\n")
tn.write(b"exit\n")

print(tn.read_all().decode('ascii'))

点击收藏 | 1 关注 | 1
登录 后跟帖