大家好,我是自觉人生路漫漫,赚钱很困难的小鱼。今天我们继续拆机研究。
正式开始前,先自己套个马甲。
警告&免责声明:本文所述的拆机破解方法仅供学习和研究目的。任何人选择根据本文内容进行行动,均应自行承担责任。小鱼不对因使用本文中的方法可能导致的损失或法律责任负责。
穿好了,开始!
开始之前还是照惯例,先看个广告
今天文章很硬核,广告也要硬一些
这个公众号,对,就这个
鱼香ROS专注于机器人技术分享学习、包含ROS及ROS2机器人操作系统、Moveit机械臂运动规划框架、激光视觉SLAM、机器人仿真等相关技术。
关注+星标
最后! 鱼香小铺正式开业,最低499可入手一台能建图会导航的移动机器人(Bot虽小,五脏俱全,FishBot装起来!,某宝搜店:鱼香ROS
好了,广告时间结束!
昨天(扫地机居然用十年前的系统?2024第四拆来了)小鱼成功找到了扫地机器人主板的TX和RX测试点
为了调试方便,小鱼就把烧录器用几根很长的线和板子焊接在板子上
像这样
昨天说要切入系统,还是要从u-boot入手,u-boot 就是开机前的一段程序,昨天文章有介绍
根据开机的日志可以知道
boot A system
WORK_MODE_BOOT
[ 2.387]Hit any key to stop autoboot: 0
开机的时候输入任意键停止自动boot
好的,没问题
开机,一直按 f ,然后看到
[ 7.322107] WDIOC_SETFUNCCONFIG: 1
[ 7.341094] WDIOC_SETFUNCCONFIG: 1
Ubuntu 14.04.3 LTS rockrobo ttyS0
rockrobo login:ffffffffffffffff
好家伙,继续 BOOT 了
咋整,搜一下,换个按键,停止用 s
再次关机,开机,按 s
board_common.c:check_android_misc:will be boot A system
to be run cmd=run setargs_mmc boot_normal
boot A system
WORK_MODE_BOOT
[ 0.902]Hit any key to stop autoboot: 0
sunxi#ss
成功进入 u-boot
然后呢?不知道咋办先看看 help
看看 uboot 能干嘛
sunxi#help
? - alias for 'help'
ext4load- load binary file from a Ext4 filesystem
ext4ls - list files in a directory (deffault /)
....
mmc - MMC sub system
md - memory display
....
true - do nothing, successfully
uburn - do a burn from boot
version - print monitor, compiler and linker verrsion
命令太多,小鱼留下几个要用的在这里
ext4load 可以加载二进制的文件从文件系统
ext4ls 可以查看文件列表
mmc 可以用来操作 emmc
md 可以展示内存数据
先学这三个吧
接着我们来理一下思路先
通过昨天的文章我们知道,这个扫地机的系统是Ubuntu14的
Ubuntu 小鱼熟悉呀
密码文件不就放在 /etc/shadow 下吗(当然是加密后的
先找到这个文件看看
去哪里找呢?
又要用到昨天的知识点了,先看分区表
--------fastboot partitions--------
-total partitions:9-
-name- -start- -size-
boot-res : 1000000 800000
env : 1800000 1000000
app : 2800000 1000000
recovery : 3800000 20000000
system_a : 23800000 20000000
system_b : 43800000 20000000
Download : 63800000 21000000
reserve : 84800000 1000000
UDISK : 85800000 0
-----------------------------------
只看大小 recovery, system_a ,system_b ,这三个里面肯定是有文件系统
看起始地址和size,这三个还是挨在一起的
好,我们来找文件了
先看看所有的flash上的分区
此时可以用上 mmc 命令
sunxi#mmc part
Partition Map for MMC device 2 -- Partition Type: DOS
Partition Start Sector Num Sectors Type
1 4415488 3366912 b
2 73728 16384 6
3 1 4325376 5 Extd
5 90112 32768 83
6 122880 32768 83
7 155648 1048576 83
8 1204224 1048576 83
9 2252800 1048576 83
10 3301376 1081344 83
11 4382720 32768 83
画重点, device 2 ,然后看 Num Sectors
7 8 9 10 ,这四个是系统的概率很大
直接查文件列表
ext4ls 上
sunxi#ext4ls mmc 2:7 /etc/
<DIR> 5120 .
<DIR> 1024 ..
<DIR> 1024 selinux
19 issue.net
....
166 hosts
<DIR> 1024 usbmount
<DIR> 1024 dbus-1
<DIR> 1024 pam.d
679 shadow
找到 /etc/shadow,在 2-7 上
看看文件里的内容
ext4load 先上
sunxi#ext4load mmc 2:7 40008000 /etc/shadow
Loading file "/etc/shadow" from mmc device 2:7
679 bytes read
679 字节加载成功
md 上(这里有点搞笑
sunxi#md 40008000
40008000: 746f6f72 2436243a 6e653172 78343839 root:$6$r1en984x
40008010: 2e323324 47694179 33516c50 39437550 $32.yAiGPlQ3PuC9
40008020: 41664b71 2e486c4c 39616256 686d6967 qKfALlH.Vba9gimh
40008030: 77336b54 39485855 35647267 69375549 Tk3wUXH9grd5IU7i
40008040: 5a49726b 55704e56 502f3346 53524b30 krIZVNpUF3/P0KRS
40008050: 69664850 74625879 50585978 7a372e2f PHfiyXbtxYXP/.7z
40008060: 6f4a4e54 3a2e7033 393a303a 39393939 TNJo3p.::0:99999
40008070: 3a3a373a 61640a3a 6e6f6d65 313a2a3a :7:::.daemon:*:1
40008080: 32353636 393a303a 39393939 3a3a373a 6652:0:99999:7::
40008090: 69620a3a 3a2a3a6e 35363631 3a303a32 :.bin:*:16652:0:
400080a0: 39393939 3a373a39 730a3a3a 2a3a7379 99999:7:::.sys:*
400080b0: 3636313a 303a3235 3939393a 373a3939 :16652:0:99999:7
400080c0: 0a3a3a3a 636e7973 313a2a3a 32353636 :::.sync:*:16652
400080d0: 393a303a 39393939 3a3a373a 61670a3a :0:99999:7:::.ga
400080e0: 3a73656d 36313a2a 3a323536 39393a30 mes:*:16652:0:99
400080f0: 3a393939 3a3a3a37 6e616d0a 313a2a3a 999:7:::.man:*:1
重点来了,这一段
40008000: 746f6f72 2436243a 6e653172 78343839 root:$6$r1en984x
40008010: 2e323324 47694179 33516c50 39437550 $32.yAiGPlQ3PuC9
40008020: 41664b71 2e486c4c 39616256 686d6967 qKfALlH.Vba9gimh
40008030: 77336b54 39485855 35647267 69375549 Tk3wUXH9grd5IU7i
40008040: 5a49726b 55704e56 502f3346 53524b30 krIZVNpUF3/P0KRS
40008050: 69664850 74625879 50585978 7a372e2f PHfiyXbtxYXP/.7z
40008060: 6f4a4e54 3a2e7033 393a303a 39393939 TNJo3p.::0:99999
拆出来就这句话
root: 6 6 6r1en984x$32.yAiGPlQ3PuC9qKfALlH.Vba9gimhTk3wUXH9grd5IU7ikrIZVNpUF3/P0KRSPHfiyXbtxYXP/.7zTNJo3p.
看不出来密码是什么吧
当然,这是加密后的密码
小鱼来介绍下,这段文本的格式是 root: 6 6 6wUKnT9Uh$xxx
其中 root: 表示用户名是 root
6 6 6 表示使用的哈希算法是 SHA-512
wUKnT9Uh 是用作盐(salt)的部分(就是一堆随机数,让密码更复杂,更难破解)
xxx 是经过哈希处理的密码
怎么处理呢?像这样
原始密码(123)———>SHA512加密算法(各种加减乘除小括号)——>512bit的密文(人看不懂的密文)
这种加密的方式特点就是反推困难
512bit的密文—— 困难 ——>原始密码(123)
那怎么办?
你肯定想到了,可以从0开始试密码
穷举/遍历密码———>SHA512加密算法——>我的512bit的密文 对比 512bit的密文
对比成功,就表示找到了密码
再多扩展一下
前几年比特币很火,小鱼也曾幻想挖矿发家致富
可惜连一块显卡都买不起
比特币就是使用 SHA-256 哈希算法来证明谁算力更强,就是比谁穷举的快,256加密运算的快
说回正题,假设这个机器人的开发人员图方便,把密码设计的很简单
像这样的 0,1,123,abc
小鱼这小破电脑,多花点时间应该是测的出来
好,写代码
记得年轻那会,小鱼人送外号,脚本王子
安排
import itertools
import string
import crypt
def checkpswd(known_plain_password):
known_hashed_password = "$6$r1en984x$32.yAiGPlQ3PuC9qKfALlH.Vba9gimhTk3wUXH9grd5IU7ikrIZVNpUF3/P0KRSPHfiyXbtxYXP/.7zTNJo3p."
encryption_method = '6'
salt = 'r1en984x'
# 使用相同的加密方式和盐来校验密码
hashed_password = crypt.crypt(known_plain_password, f"${encryption_method}${salt}$")
return known_hashed_password == hashed_password
count = 0
import time
combination_length = 3 # 修改这个组合,修改密码位数
start_time = time.time()
letters = string.ascii_letters + string.digits # 包括所有字母和数字
for combination in itertools.product(letters, repeat=combination_length):
combination_str = ''.join(combination)
count += 1
if checkpswd(combination_str):
print(combination_str)
break
if count % 1000 == 0:
print(f"current:{count} rate:{1000 / (time.time() - start_time)}")
start_time = time.time()
正在小鱼准备运行的时候突然想到,2:7 分区好像是 recovery 恢复分区
正常启动的系统是 system_a
按照fastboot给的顺序 recovery,system_a,system_b
所以 system_a 的密码文件应该是在 2:8
好家伙,又大意了
接着重新找到 2:8 对应的文件密码,更新代码
def checkpswd(known_plain_password):
known_hashed_password = "$6$wUKnT9Uh$HC.bPxRj0vCmtfzbddIBW6wb2JexMO7AI1gmuiJqvC2/gYt9SYsDhQoJjURafsP2c6wE9JYjKXzMx4IhqtC.X/"
encryption_method = '6'
salt = 'wUKnT9Uh'
开始运行
python3 sc.py
current:1000 rate:126.95969609371453
current:2000 rate:138.1747021643396
current:3000 rate:107.7845597808118
current:4000 rate:128.05771351053232
current:5000 rate:117.9104355513385
current:6000 rate:114.05144989973364
current:7000 rate:132.21091439569744
current:8000 rate:130.07574579806555
current:9000 rate:133.39684012978185
current:10000 rate:134.04584905051348
current:11000 rate:129.47750475974388
current:12000 rate:121.92480133787801
一百多次尝试每秒,这速度很感人!
电脑不错的小伙伴可以把上面的代码放自己电脑上测试下,看看速度
简单算了下,如果位数不多,还是有希望尝试出来的
但是就怕它有十几位密码,用小鱼这破电脑至少要花个十亿年
据说量子计算机在这种需要算力的场景很有优势,懂的留言
让脚本飞一会
小鱼带你继续探索下u-boot
每个分区的文件康康
当看到 2:6 的时候
发现了几个奇怪的文件
sunxi#ext4ls mmc 2:6 /
<DIR> 1024 .
<DIR> 1024 ..
<DIR> 12288 lost+found
18452 librrafm.so
97 device.conf
16 vinda
12 adb.conf
device.conf ?vinda ?adb.conf ?
这看起来很像配置文件呀
一个个瞅瞅
device.conf
sunxi#ext4load mmc 2:6 40008000 /device.conf
Loading file "/device.conf" from mmc device 2:6
97 bytes read
sunxi#md 40008000
40008000: 3d646964 34343436 36393533 79656b0a did=64443596.key
40008010: 6354343d 6e4b7a71 3459726b 47737758 =4TcqzKnkrY4XwsG
40008020: 616d0a34 34333d63 3a45433a 453a3030 4.mac=34:CE:00:E
40008030: 32303a37 0a41343a 646e6576 723d726f 7:02:4A.vendor=r
40008040: 726b636f 0a6f626f 65646f6d 6f723d6c ockrobo.model=ro
40008050: 6f726b63 762e6f62 75756361 31762e6d ckrobo.vacuum.v1
整理下格式是这样的
did=64443596
key=4TcqzKnkrY4XwsG
mac=34:CE:00:E7:02:4A
vendor=rockrobo
model=rockrobo.vacuum.v1
设备编号,key,mac地址
emmm 有意思
继续第二个文件 vinda
这个名字很奇怪,像抽纸
看内容
sunxi#ext4load mmc 2:6 40008000 /vinda
Loading file "/vinda" from mmc device 2:6
16 bytes read
sunxi#md 40008000
40008000: 52415a5c 5f585b58 4e565a45 50525950 \ZARX[X_EZVNPYRP
很短的16字节 \ZARX[X_EZVNPYRP
也看不太懂的内容
但是这玩意为什么和设备配置文件放在一起,名字还那么奇怪
跟密码有没有什么关联?
等脚本结果也是等,不如研究下这个小 vinda
这个 \ZARX[X_EZVNPYRP 就是密码的可能性不大(肯定不是,别问,问就是小鱼试过了
那有可能是密码的密文,但又不像是sha或者rsa加密的结果
那就有可能是用的简单加密
简单加密手段常用的就几个,小鱼介绍下
凯撒密码 这个听起来很高大上,
让人想起这位大帝
其实凯撒密码就是最简单的移位替换,比如 1 写成 2, 2写成3 ,a 写成 b
小鱼按照这个思路,简单又写个个脚本,移动一位比特,相当于/2
python3 yw.py
¸.´- ¤)°,¶-°,¾/"´-¬+' (²,¤) (
结果没法看,考虑到这种加密太容易被破解,而且移动多了后会导致跑到不可见字符区域,加上这种写代码麻烦,考虑到这家机器人工程师比较懒,暂时放弃凯撒
第二种常用的就是 异或操作,即 XOR
XOR加密最早起源于在电报传输中的使用的,历史悠久
XOR:eXclusive OR 的缩写,中文称为"异或运算"
它的定义是:两个值相同时,返回 false,否则返回 true。也就是说,XOR 可以用来判断两个值是否相同
真的 XOR 真的 = 假的
假的 XOR 假的 = 假的
真的 XOR 假的 = 真的
假的 XOR 真的 = 真的
XOR有一个非常巧妙的地方
XOR 运算有一个很奇妙的特点:XOR一次+XOR一次=没有XOR
比如
// 第一次 第二次
0101 XOR 1111 = 1010 XOR 1111 = 0101
显而易见,用XOR加密和解密写代码的时候真的很方便
那这个vinda 文件有没有可能用的这种方法呢?
这时候该脚本老王子小鱼上场了
安排
def xor_with_x(character,x):
result = ord(character) ^ x
return chr(result)
# 输入ASCII字符集中的字符
ascii_characters = '\ZARX[X_EZVNPYRP'
for x in range(0x00,0xff):
result_str = ''
for char in ascii_characters:
result = xor_with_x(char,x)
result_str += result
print(f"{result_str}")
因为不知道每个字节 XOR 的对象,就从0x00(0)开始到0xff(255)全部来了一遍
运行
python3 xor_test.py
\ZARX[X_EZVNPYRP
][@SYZY^D[WOQXSQ
^XCPZYZ]GXTLR[PR
_YBQ[X[\FYUMSZQS
X^EV\_\[A^RJT]VT
Y_DW]^]Z@_SKU\WU
...
OIRAKHKLVIE]CJAC
HNUFLOLKQNBZDMFD
IOTGMNMJPOC[ELGE
JLWDNMNISL@XFODF
KMVEOLOHRMAYGNEG
DBYJ@C@G]BNVHAJH
ECXKABAF\COWI@KI
F@[HBABE_@LTJCHJ
....
ljqbhkhoujf~`ib`
nhs`jijmwhd|bk`b
oirakhklvie}cjac
hnuflolkqnbzdmfd
iotgmnmjpoc{elge
jlwdnmnisl`xfodf
kmveolohrmaygneg
dbyj`c`g}bnvhajh
ecxkabaf|cowi`ki
gazic`cd~amukbik
`f}ndgdcyfjrlenl
...
9?$7=>=: ?3+5<75
:<'4>=>9#<0(6?46
;=&5?<?8"=1)7>57
42):0307-2>&81:8
53(;1216,3?'90;9
...
ÅÃØËÁÂÁÆÜÃÏ×ÉÀËÉ
ÆÀÛÈÂÁÂÅßÀÌÔÊÃÈÊ
ÇÁÚÉÃÀÃÄÞÁÍÕËÂÉË
ÀÆÝÎÄÇÄÃÙÆÊÒÌÅÎÌ
ÁÇÜÏÅÆÅÂØÇËÓÍÄÏÍ
...
ûýæõÿüÿøâýñé÷þõ÷
ôòéúðóð÷íòþæøñúø
。。。
ìêñâèëèïõêæþàéâà
íëðãéêéîôëçÿáèãá
îèóàêéêí÷èäüâëàâ
ïéòáëèëìöéåýãêáã
...
¶°«¸²±²µ¯°¼¤º³¸º
·±ª¹³°³´®±½¥»²¹»
±·¬¿µ¶µ²¨·»£½´¿½
³µ®½·´·°ªµ¹¡¿¶½¿
¯©²¡«¨«¬¶©¥½£ª¡£
¢¤¿¬¦¥¦¡»¤¨°®§¬®
结果应该是255行(包含一些不可见的字符),为了省空间,小鱼就加了点省略号
可是这么多密码,要是一个个开机输入试
估计试完小鱼人都没了
嘿嘿,别忘记了我们还有一个穷举的兄弟脚本里还有一个函数 checkpswd
安排
import crypt
def checkpswd(known_plain_password):
known_hashed_password = "$6$wUKnT9Uh$HC.bPxRj0vCmtfzbddIBW6wb2JexMO7AI1gmuiJqvC2/gYt9SYsDhQoJjURafsP2c6wE9JYjKXzMx4IhqtC.X/"
encryption_method = '6'
salt = 'wUKnT9Uh'
hashed_password = crypt.crypt(known_plain_password, f"${encryption_method}${salt}$")
return known_hashed_password== hashed_password
def xor_with_x(character, x):
result = ord(character) ^ x
return chr(result)
ascii_characters = '\ZARX[X_EZVNPYRP'
for x in range(0x00, 0xff):
result_str = ''
for char in ascii_characters:
result = xor_with_x(char, x)
result_str += result
if checkpswd(result_str):
print(result_str)
最后加了个 if checkpswd(result_str): ,找到密码就打印
运行
python3 xor_test.py
kmveolohrmaygneg
Traceback (most recent call last):
File "/home/fishros/github/example_micoros_board/example25_encoder/test/xor_test.py", line 24, in <module>
if checkpswd(result_str):
File "/home/fishros/github/example_micoros_board/example25_encoder/test/xor_test.py", line 7, in checkpswd
hashed_password = crypt.crypt(known_plain_password, f"${encryption_method}${salt}$")
File "/usr/lib/python3.10/crypt.py", line 82, in crypt
return _crypt.crypt(word, salt)
ValueError: embedded null character
报错了
BUT,在报错之前,居然出现了一行打印
没错,就是它
kmveolohrmaygneg
hash后成功碰撞,密码就算不是它,登录应该也没问题
小鱼这激动的心,颤抖的手
根据提示,uboot 输入
run setargs_mmc boot_normal
开机,输入用户名 root ,还有密码
rockrobo login: root
Password:
Last login: Thu Jan 1 19:47:21 CST 1970 from 192.168.1.13 on pts/1
Welcome to Ubuntu 14.04.3 LTS (GNU/Linux 3.4.39 armv7l)
* Documentation: https://help.ubuntu.com/
root@rockrobo:~#
成功进入!!!
搞拆机,运气有时候真重要!
这个扫地机器人系统里装没装ROS, 为什么SSH 和 ADB 打不开?
下期揭晓。
本文的最后,先收尾一下前面留的问题。
之前说内存是 4Gb 的,显示确实 512 MB, 不得其解,经过后台小伙伴的提示
找到问题了,是小鱼看错了,把 小b 即 bit 当成 大B 即 Bytes
1 Bytes = 8 bit
所以 4Gb/8=512MB 五八四十对不对
然后另外一个问题,有小伙伴留言说为啥拆元器件的时候不用风枪吹,主要原因是元器件附近有 0201 的小电阻和电容,手头又没有高温胶带,担心一不小心吹飞了
还有最后一个,你点赞,分享,在看了吗?