码迷,mamicode.com
首页 > Web开发 > 详细

斐讯K2P通过配置文件开启telnet的原理分析

时间:2018-04-20 00:20:06      阅读:552      评论:0      收藏:0      [点我收藏+]

标签:one   组成   while   openssl   killall   exit   技术   proc   version   

看过几篇教程之后我已经知道怎么备份固件了。但是现在有一个问题,我的本意是把K2P原机带的固件备份出来,用教程上的方法进行开启telnet、备份固件等操作是否会改变固件呢?下面我们来验证这个问题。

OpenWrt的文件系统

K2P使用的是OpenWrt系统,我们先来看一下K2P的Flash Layout(图片来自恩山)

技术分享图片

图片上的 firmware 就是我要的固件,它分成 Kernel 和 rootfs 两部分。其中 rootfs 使用SquashFS和JFFS2实现了一个可读写的文件系统,但实际上SquashFS是只读的压缩包,所有的文件修改都是记录在JFFS2,也就是rootfs_data上的。

感兴趣的话可以看看:

https://wiki.openwrt.org/doc/techref/filesystems

https://blog.csdn.net/lee244868149/article/details/57076615

路由器重置的原理

我们知道所有的文件修改都是记录在 rootfs_data 上的,系统重置实际上就是将这部分数据抹掉,我们来验证一下。

我之前下了一个网友备份的固件,地址

打开 "/usr/lib/lua/luci/controller/admin/backuprestore.lua" 文件,查看第136~141行。

136     elseif reset_avail and luci.http.formvalue("reset") then
137         luci.template.render("backuprestore", {
138             reset_process = 1
139         })
140         fork_exec("sleep 3; killall dropbear lighttpd miniupnpd; sleep 3; mtd -r erase rootfs_data")
141     else

mtd -r erase rootfs_data 这一句就是抹掉 rootfs_data 的数据。

通过配置文件开启telnet的原理

我们来看一下恢复配置文件是怎么实现的。

还是 "/usr/lib/lua/luci/controller/admin/backuprestore.lua" 这个文件,查看第81~136行。

 81     elseif luci.http.formvalue("restore") then
 82         local fs = require("luci.fs")
 83         luci.http.formvalue("filename")
 84         --校验配置文件
 85         luci.util.exec("encryconfig decrypt /tmp/backupFile_encode /tmp/backupFile")
 86         nixio.fs.unlink("/tmp/backupFile_encode")
 87         local fd = io.open("/tmp/backupFile", r)
 88         local restore_error_message
 89         if fd ~= nil then
 90             local line = fd:read()
 91             fd:close()
 92             if line ~= nil then
 93                 if not checkfwversion() then
 94                     nixio.fs.unlink("/tmp/backupFile")
 95                     restore_error_fwversion = {"restore_error"}
 96                     luci.template.render("backuprestore", {
 97                         restore_error_fwversion = restore_error_fwversion
 98                     })
 99                 else
100                     luci.util.exec("sed 1,10d /tmp/backupFile >/tmp/restore_rm_header")
101                     luci.util.exec("tar -xzC/ -f /tmp/restore_rm_header")
102                     nixio.fs.unlink("/tmp/restore_rm_header")
103                     local cur_lan_mac = luci.util.exec("uci get network.lan.macaddr")
104                     local cur_wan_mac = luci.util.exec("uci get network.wan.macaddr")
105                     local flash_lan_mac = luci.util.exec("eth_mac r lan")
106                     local flash_wan_mac = luci.util.exec("eth_mac r wan")
107                     if cur_lan_mac ~= flash_lan_mac then
108                         luci.util.exec("uci set network.lan.macaddr=%s" % flash_lan_mac)
109                     end
110                     if cur_wan_mac ~= flash_wan_mac then
111                         luci.util.exec("uci set network.wan.macaddr=%s" % flash_wan_mac)
112                     end
113                     luci.util.exec("uci commit")
114                     local upload = luci.http.formvalue("restore")
115                     if upload and #upload > 0 then
116                         luci.template.render("backuprestore", {
117                             restore_avail = 1
118                         })
119                         fork_exec("sleep 3; reboot")
120                     end
121                 end
122             else
123                 restore_error_message = {"restore_error"}
124                 nixio.fs.unlink("/tmp/backupFile")
125                 luci.template.render("backuprestore", {
126                     restore_error_message = restore_error_message
127                 })
128             end
129         else
130             nixio.fs.unlink("/tmp/backupFile")
131             restore_error_message = {"restore_error"}
132             luci.template.render("backuprestore", {
133                 restore_error_message = restore_error_message
134             })
135         end
136     elseif reset_avail and luci.http.formvalue("reset") then

 第101行,tar -xzC/ -f /tmp/restore_rm_header,这条命令把配置文件解压缩到根目录下覆盖现在用的文件。

利用这个特性我们可以向系统写入我们想要的数据,比如自启动脚本。

/etc/rc.local

在 "/etc/rc.local" 脚本中加入命令开启telnet服务是一个不错的选择。

修改后的文件如下:

 1 # Put your custom commands here that should be executed once
 2 # the system init finished. By default this file does nothing.
 3 
 4 case `cat /proc/cpuinfo | grep MT76` in
 5   *7621*)
 6     CONFIG_RALINK_MT7621=y
 7     ;;
 8   *7623*)
 9     CONFIG_ARCH_MT7623=y
10     ;;
11 esac
12 if [ "$CONFIG_RALINK_MT7621" = "y" ]; then
13 echo 2048 > /proc/sys/vm/min_free_kbytes
14 #echo 2 > /proc/sys/vm/overcommit_memory
15 #echo 50 >  /proc/sys/vm/overcommit_ratio
16 fi
17 block mount
18 
19 # add nat rule manually
20 
21 smp.sh wifi
22 hwnat-enable.sh
23 brctl addif br-lan ra0
24 brctl addif br-lan rax0
25 /usr/sbin/telnetd -l /bin/login.sh
26 exit 0

第25行 /usr/sbin/telnetd -l /bin/login.sh 就是开启服务的命令。注意,在这个命令中要写完整路径名。

打包配置文件

生成配置文件的代码在 "/sbin/sysupgrade" 脚本里,第131~174行。

 1 do_save_conffiles() {
 2     local conf_tar="${1:-$CONF_TAR}"
 3 
 4 if [ -z "$CONF_BACKUP" ]; then
 5     platform_config_prepare
 6 fi
 7 
 8     [ -z "$(rootfs_type)" ] && {
 9         echo "Cannot save config while running from ramdisk."
10         ask_bool 0 "Abort" && exit
11         return 0
12     }
13     run_hooks "$CONFFILES" $sysupgrade_init_conffiles
14     ask_bool 0 "Edit config file list" && vi "$CONFFILES"
15 
16 #    v "Saving config files..."
17     [ "$VERBOSE" -gt 1 ] && TAR_V="v" || TAR_V=""
18     tar c${TAR_V}zf "$conf_tar" -T "$CONFFILES"
19 
20 if [ -n "$CONF_BACKUP" ]; then
21     #fix project name must be first line
22     #phic_fac -g product > /tmp/backup_add_header
23     #fix project hardware info must be second line
24     #phic_fac -g hw_ver  >> /tmp/backup_add_header
25     #fix project software version must be third line
26     #phic_fac -g fw_ver >> /tmp/backup_add_header
27     #we leave here 7 blank lines,so we have total 10 lines include above 3 lines at the top of /tmp/backup_2
28     echo "product=`uci get system.system.hostname`" >> /tmp/backupFile
29     echo "hw_ver=`uci get system.system.hw_ver`" >> /tmp/backupFile
30     echo "fw_ver=`uci get system.system.fw_ver`" >> /tmp/backupFile
31     for i in 4 5 6 7 8 9 10
32     do
33         echo "" >> /tmp/backupFile
34     done 
35     cat $conf_tar >> /tmp/backupFile
36     encryconfig encrypt /tmp/backupFile /tmp/backupFile_encode
37     #cat /tmp/backup_add_header_encry 2>/dev/null
38 
39     #rm -f "/tmp/backup_add_header"
40     #rm -f "/tmp/backup_add_header_encry"
41     rm -f "$conf_tar"
42 fi
43     rm -f "$CONFFILES"
44 }

配置文件由文件头和一个tar包组成。文件头是10行文本,这个可以在备份出的文件中截取。在tar包里放我们想写入的文件,与文件头合并成在一起。最后用openssl加密就可以了。

 

斐讯K2P通过配置文件开启telnet的原理分析

标签:one   组成   while   openssl   killall   exit   技术   proc   version   

原文地址:https://www.cnblogs.com/LikeVirgo/p/8884716.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!