资料介绍
软件简介
我们在做企业安全时,弱口令检测是系统/网络安全的最基础的部分之一,根据经验,经常会出现弱口令的服务如下:
- FTP
- SSH
- SMB
- MYSQL
- MSSQL
- POSTGRESQL
- REDIS
- MONGODB
- ELASTICSEARCH
那咱们就一起用GO来写一款常见服务的弱口令扫描器,且支持以插件的形式增加新的服务扫描模块。我们的教程暂定为只扫以上服务。
给扫描器启一个屌炸天的名字x-crack,在$GOPATH/src/中建立一个x-crack项目后开始撸码,不要给我说什么底层原理、框架内核,老夫敲代码就是一把梭。
开工
数据结构定义
- 扫描模块的输入内容为为IP、端口及协议的列表,我们需要定义一个IpAddr的数据结构;
- 每个服务的每次扫描需要传入的参数为IP、端口、协议、用户名和密码,需要定义一个Service结构来包括这些内容;
- 每条Service的记录在扫描模块进行尝试后,会得出扫描结果成功与否,我们再定义一个ScanResult数据结构。
按照开发规范,数据结构的定义统一放到models目录中,全部的数据结构定义如下:
package models
type Service struct {
Ip string
Port int
Protocol string
Username string
Password string
}
type ScanResult struct {
Service Service
Result bool
}
type IpAddr struct {
Ip string
Port int
Protocol string
}
FTP扫描模块
go语言有现成的FTP模块,我们找一个star数最多的直接go get安装一下即可使用了:
go get -u github.com/jlaffaye/ftp
我们把所有的扫描模块放到plugins目录中,FTP协议的扫描插件如下所示:
package plugins
import (
"github.com/jlaffaye/ftp"
"x-crack/models"
"x-crack/vars"
"fmt"
)
func ScanFtp(s models.Service) (err error, result models.ScanResult) {
result.Service = s
conn, err := ftp.DialTimeout(fmt.Sprintf("%v:%v", s.Ip, s.Port), vars.TimeOut)
if err == nil {
err = conn.Login(s.Username, s.Password)
if err == nil {
defer conn.Logout()
result.Result = true
}
}
return err, result
}
每个连接需要设置超时时间,防止因网络问题导致的阻塞,我们打算通过程序的命令行来控制超时时间,所以定义了一个全局变量TimeOut。 放在vars模块中的原因是防止放在这个模块中后会和其他模块互相调用导致的循环import
写代码虽然可以一把梭,但是不能等着洋洋洒洒地把几万行都写完再运行,比如我们的目标是造一辆豪车,不能等着所有零件设计好,都装上去再发动车测试,正确的开发流程是把写边测,不要等轮子造出来,而是在螺丝、齿轮阶段就测试。
以下为FTP扫描插件这个齿轮的测试代码及结果。
package plugins_test import ( "x-crack/models" "x-crack/plugins" "testing" ) func TestScanFtp(t *testing.T) { s := models.Service{Ip: "127.0.0.1", Port: 21, Protocol: "ftp", Username: "ftp", Password: "ftp"} t.Log(plugins.ScanFtp(s)) }
测试结果满足预期,说明我们这个零件不是次品,可以继续再造其他零件了。
$ go test -v plugins/ftp_test.go
=== RUN TestScanFtp
--- PASS: TestScanFtp (0.00s)
ftp_test.go:36: dial tcp 127.0.0.1:21: getsockopt: connection refused {{127.0.0.1 21 ftp ftp ftp} false}
PASS
ok command-line-arguments 0.025s
SSH扫描模块
go的标准库中自带了ssh包,直接调用即可,完整代码如下:
package plugins import ( "golang.org/x/crypto/ssh" "x-crack/models" "x-crack/vars" "fmt" "net" ) func ScanSsh(s models.Service) (err error, result models.ScanResult) { result.Service = s config := &ssh.ClientConfig{ User: s.Username, Auth: []ssh.AuthMethod{ ssh.Password(s.Password), }, Timeout: vars.TimeOut, HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error { return nil }, } client, err := ssh.Dial("tcp", fmt.Sprintf("%v:%v", s.Ip, s.Port), config) if err == nil { defer client.Close() session, err := client.NewSession() errRet := session.Run("echo xsec") if err == nil && errRet == nil { defer session.Close() result.Result = true } } return err, result }
同样,每个子模块写好后都需要先用go test跑一下看是否满足预期,测试代码如下:
package plugins_test
import (
"x-crack/models"
"x-crack/plugins"
"testing"
)
func TestScanSsh(t *testing.T) {
s := models.Service{Ip: "127.0.0.1", Port: 22, Username: "root", Password: "123456", Protocol: "ssh"}
t.Log(plugins.ScanSsh(s))
}
测试结果如下:
$ go test -v plugins/ssh_test.go
=== RUN TestScanSsh
--- PASS: TestScanSsh (0.00s)
ssh_test.go:36: dial tcp 127.0.0.1:22: getsockopt: connection refused {{127.0.0.1 22 ssh root 123456} false}
PASS
ok command-line-arguments 0.026s
SMB扫描模块
SMB弱口令的扫描插件,我们使用了github.com/stacktitan/smb/smb包,同样直接go get安装一下即可拿来使用。 代码如下:
package plugins
import (
"github.com/stacktitan/smb/smb"
"x-crack/models"
)
func ScanSmb(s models.Service) (err error, result models.ScanResult) {
result.Service = s
options := smb.Options{
Host: s.Ip,
Port: s.Port,
User: s.Username,
Password: s.Password,
Domain: "",
Workstation: "",
}
session, err := smb.NewSession(options, false)
if err == nil {
session.Close()
if session.IsAuthenticated {
result.Result = true
}
}
return err, result
}
同样也先写测试用例来测试一下,测试代码如下:
package plugins_test
import (
"x-crack/models"
"x-crack/plugins"
"testing"
)
func TestScanSmb(t *testing.T) {
s := models.Service{Ip: "share.xsec.io", Port: 445, Protocol: "smb", Username: "xsec", Password: "fsafffdsfdsa"}
t.Log(plugins.ScanSmb(s))
}
测试结果:
hartnett at hartnettdeMacBook-Pro in /data/code/golang/src/x-crack (master) $ go test -v plugins/smb_test.go === RUN TestScanSmb --- PASS: TestScanSmb (0.04s) smb_test.go:36: NT Status Error: Logon failed {{share.xsec.io 445 smb xsec fsafffdsfdsa} false} PASS ok command-line-arguments 0.069s
MYSQL、MSSQL和POSTGRESQL扫描模块
MYSQL、MSSQL和POSTGRESQL的扫描模块,我使用了第三方的ORM xorm,当然也可以直接使用原生的sql driver来实现,我们这里图方便用xorm一把梭了。 对于xorm来说,这3个扫描插件的实现方法大同小异,为了节约篇幅,咱们只看mysql扫描插件的实现,其他2个插件可以参考github中的完整源码。 首先还是先go get要用到的包:
go get github.com/netxfly/mysql go get github.com/go-xorm/xorm github.com/go-xorm/core
接下来我们把需要验证的IP、port、username、password组成datasource传递给xorm,完整代码如下:
package plugins
import (
_ "github.com/netxfly/mysql"
"github.com/go-xorm/xorm"
"github.com/go-xorm/core"
"x-crack/models"
"fmt"
)
func ScanMysql(service models.Service) (err error, result models.ScanResult) {
result.Service = service
dataSourceName := fmt.Sprintf("%v:%v@tcp(%v:%v)/%v?charset=utf8", service.Username,
service.Password, service.Ip, service.Port, "mysql")
Engine, err := xorm.NewEngine("mysql", dataSourceName)
if err == nil {
Engine.SetLogLevel(core.LOG_OFF)
// fix "[mysql] packets.go:33: unexpected EOF" error
Engine.SetMaxIdleConns(0)
// Engine.SetConnMaxLifetime(time.Second * 30)
defer Engine.Close()
err = Engine.Ping()
if err == nil {
result.Result = true
}
}
return err, result
}
眼尖的同学也许发现了,上面 github.com/netxfly/mysql 这个mysql包是放在笔者的github下的,这是为什么呢?
因为直接用mysql这个包的话,在扫描的过程中会遇到[mysql] packets.go:33: unexpected EOF" error的异常输出,影响了我们程序在扫描过程中输出UI的美观性,这对于帅气的我是无法接受的,通过设置参数的方法无法解决,最后只好直接fork了一份mysql的包,把打印这个异常的语句注释掉再提交上去直接使用了。
测试代码:
package plugins_test
import (
"testing"
"x-crack/plugins"
"x-crack/models"
)
func TestScanMysql(t *testing.T) {
service := models.Service{Ip: "10.10.10.10", Port: 3306, Protocol: "mysql", Username: "root", Password: "123456"}
t.Log(plugins.ScanMysql(service))
}
测试结果:
go test -v plugins/mysql_test.go
=== RUN TestScanMysql
--- PASS: TestScanMysql (0.02s)
mysql_test.go:36: Error 1045: Access denied for user 'root'@'10.10.10.100' (using password: YES) {{10.10.10.10 3306 mysql root 123456} false}
PASS
ok command-line-arguments 0.041s
Redis扫描模块
go get安装第三方包github.com/go-redis/redis,完整代码如下:
package plugins
import (
"github.com/go-redis/redis"
"x-crack/models"
"x-crack/vars"
"fmt"
)
func ScanRedis(s models.Service) (err error, result models.ScanResult) {
result.Service = s
opt := redis.Options{Addr: fmt.Sprintf("%v:%v", s.Ip, s.Port),
Password: s.Password, DB: 0, DialTimeout: vars.TimeOut}
client := redis.NewClient(&opt)
defer client.Close()
_, err = client.Ping().Result()
if err == nil {
result.Result = true
}
return err, result
}
测试代码:
package plugins_test
import (
"x-crack/models"
"x-crack/plugins"
"testing"
)
func TestScanRedis(t *testing.T) {
s := models.Service{Ip: "127.0.0.1", Port: 6379, Password: "test"}
t.Log(plugins.ScanRedis(s))
}
测试结果:
go test -v plugins/redis_test.go
=== RUN TestScanRedis
--- PASS: TestScanRedis (0.00s)
redis_test.go:36: dial tcp 127.0.0.1:6379: getsockopt: connection refused {{127.0.0.1 6379 test} false}
PASS
ok command-line-arguments 0.025s
MONGODB扫描模块
mongodb扫描模块依赖mgo包,可用go get合令直接安装。
go get gopkg.in/mgo.v2
完整代码:
package plugins
import (
"gopkg.in/mgo.v2"
"x-crack/models"
"x-crack/vars"
"fmt"
)
func ScanMongodb(s models.Service) (err error, result models.ScanResult) {
result.Service = s
url := fmt.Sprintf("mongodb://%v:%v@%v:%v/%v", s.Username, s.Password, s.Ip, s.Port, "test")
session, err := mgo.DialWithTimeout(url, vars.TimeOut)
if err == nil {
defer session.Close()
err = session.Ping()
if err == nil {
result.Result = true
}
}
return err, result
}
测试结果:
go test -v plugins/mongodb_test.go === RUN TestScanMongodb --- PASS: TestScanMongodb (3.53s) mongodb_test.go:36: no reachable servers {{127.0.0.1 27017 mongodb test test} false} PASS ok command-line-arguments 3.558s
ELASTICSEARCH扫描模块
ELASTICSEARCH扫描插件依赖第三方包gopkg.in/olivere/elastic.v3,同样也是直接go get安装。 完整代码如下:
package plugins
import (
"gopkg.in/olivere/elastic.v3"
"x-crack/models"
"fmt"
)
func ScanElastic(s models.Service) (err error, result models.ScanResult) {
result.Service = s
client, err := elastic.NewClient(elastic.SetURL(fmt.Sprintf("http://%v:%v", s.Ip, s.Port)),
elastic.SetMaxRetries(3),
elastic.SetBasicAuth(s.Username, s.Password),
)
if err == nil {
_, _, err = client.Ping(fmt.Sprintf("http://%v:%v", s.Ip, s.Port)).Do()
if err == nil {
result.Result = true
}
}
return err, result
}
测试代码:
package plugins_test
import (
"x-crack/models"
"x-crack/plugins"
"testing"
)
func TestScanElastic(t *testing.T) {
s := models.Service{Ip: "127.0.0.1", Port: 9200, Protocol: "elastic", Username: "root", Password: "123456"}
t.Log(plugins.ScanElastic(s))
}
测试结果如下:
go test -v plugins/elastic_test.go === RUN TestScanElastic --- PASS: TestScanElastic (5.02s) elastic_test.go:36: no Elasticsearch node available {{127.0.0.1 9200 elastic root 123456} false} PASS ok command-line-arguments 5.061s
扫描模块插件化
前面我们写好的扫描插件的函数原始是一致,我们可以将这组函数放到一个map中,在扫描的过程中自动化根据不同的协议调用不同的扫描插件。
以后新加的扫描插件,可以按这种方法直接注册。
package plugins
import (
"x-crack/models"
)
type ScanFunc func(service models.Service) (err error, result models.ScanResult)
var (
ScanFuncMap map[string]ScanFunc
)
func init() {
ScanFuncMap = make(map[string]ScanFunc)
ScanFuncMap["FTP"] = ScanFtp
ScanFuncMap["SSH"] = ScanSsh
ScanFuncMap["SMB"] = ScanSmb
ScanFuncMap["MSSQL"] = ScanMssql
ScanFuncMap["MYSQL"] = ScanMysql
ScanFuncMap["POSTGRESQL"] = ScanPostgres
ScanFuncMap["REDIS"] = ScanRedis
ScanFuncMap["ELASTICSEARCH"] = ScanElastic
ScanFuncMap["MONGODB"] = ScanMongodb
}
扫描任务调度
前面我们写好了一些常见服务的弱口令扫描插件,也测试通过了。 接下来我们需要实现从命令行参数传递iplist、用户名字典和密码字典进去,并读取相应的信息进行扫描调度的功能,细分一下,需要做以下几件事:
- 读取iplist列表
- 读取用户名字典
- 读取密码字典
- 生成扫描任务
- 扫描任务调度
- 扫描任务执行
- 扫描结果保存
- 命令行调用外壳
读取ip\用户名和密码字典
该模块主要用了标准库中的bufio包,逐行读取文件,进行过滤后直接生成相应的slice。其中iplist支持以下格式:
127.0.0.1:3306|mysql 8.8.8.8:22 9.9.9.9:6379 108.61.223.105:2222|ssh
对于标准的端口,程序可以自动判断其协议,对于非标准端口的协议,需要在后面加一个字段标注一下协议。
为了防止咱们的程序被脚本小子们滥用,老夫就不提供端口扫描、协议识别等功能了,安全工程师们可以把自己公司的端口扫描器产出的结果丢到这个里面来扫。
package util import ( "x-crack/models" "x-crack/logger" "x-crack/vars" "os" "bufio" "strings" "strconv" ) func ReadIpList(fileName string) (ipList []models.IpAddr) { ipListFile, err := os.Open(fileName) if err != nil { logger.Log.Fatalf("Open ip List file err, %v", err) } defer ipListFile.Close() scanner := bufio.NewScanner(ipListFile) scanner.Split(bufio.ScanLines) for scanner.Scan() { ipPort := strings.TrimSpace(scanner.Text()) t := strings.Split(ipPort, ":") ip := t[0] portProtocol := t[1] tmpPort := strings.Split(portProtocol, "|") // ip列表中指定了端口对应的服务 if len(tmpPort) == 2 { port, _ := strconv.Atoi(tmpPort[0]) protocol := strings.ToUpper(tmpPort[1]) if vars.SupportProtocols[protocol] { addr := models.IpAddr{Ip: ip, Port: port, Protocol: protocol} ipList = append(ipList, addr) } else { logger.Log.Infof("Not support %v, ignore: %v:%v", protocol, ip, port) } } else { // 通过端口查服务 port, err := strconv.Atoi(tmpPort[0]) if err == nil { protocol, ok := vars.PortNames[port] if ok && vars.SupportProtocols[protocol] { addr := models.IpAddr{Ip: ip, Port: port, Protocol: protocol} ipList = append(ipList, addr) } } } } return ipList } func ReadUserDict(userDict string) (users []string, err error) { file, err := os.Open(userDict) if err != nil { logger.Log.Fatalf("Open user dict file err, %v", err) } defer file.Close() scanner := bufio.NewScanner(file) scanner.Split(bufio.ScanLines) for scanner.Scan() { user := strings.TrimSpace(scanner.Text()) if user != "" { users = append(users, user) } } return users, err } func ReadPasswordDict(passDict string) (password []string, err error) { file, err := os.Open(passDict) if err != nil { logger.Log.Fatalf("Open password dict file err, %v", err) } defer file.Close() scanner := bufio.NewScanner(file) scanner.Split(bufio.ScanLines) for scanner.Scan() { passwd := strings.TrimSpace(scanner.Text()) if passwd != "" { password = append(password, passwd) } } password = append(password, "") return password, err }
IP列表、用户名字典与密码字典读取的测试代码:
package util_test
import (
"x-crack/util"
"testing"
)
func TestReadIpList(t *testing.T) {
ipList := "/tmp/iplist.txt"
t.Log(util.ReadIpList(ipList))
}
func TestReadUserDict(t *testing.T) {
userDict := "/tmp/user.dic"
t.Log(util.ReadUserDict(userDict))
}
func TestReadPasswordDict(t *testing.T) {
passDict := "/tmp/pass.dic"
t.Log(util.ReadPasswordDict(passDict))
}
这个模块的测试结果如下:
go test -v util/file_test.go
=== RUN TestReadIpList
--- PASS: TestReadIpList (0.00s)
file_test.go:35: [{127.0.0.1 3306 MYSQL} {8.8.8.8 22 SSH} {9.9.9.9 6379 REDIS} {108.61.223.105 2222 SSH}]
=== RUN TestReadUserDict
--- PASS: TestReadUserDict (0.00s)
file_test.go:40: [root admin test guest info adm mysql user administrator ftp sa]
=== RUN TestReadPasswordDict
--- PASS: TestReadPasswordDict (0.00s)
file_test.go:45: [1314520520 135246 135246789 135792468 1357924680 147258369 1472583690 1qaz2wsx 5201314 54321 55555 654321 789456123 88888 888888 88888888 987654321 9876543210 ^%$#@~! a123123 a123456 a12345678 a123456789 aa123456 aa123456789 aaa123456 aaaaa aaaaaa aaaaaaaa abc123 abc123456 abc123456789 abcd123 abcd1234 abcd123456 admin admin888 ]
PASS
ok command-line-arguments 0.022s
其中iplist在加载的过程中不是无脑全部读进去的,在正式扫描前会先过滤一次,把不通的ip和端口对剔除掉,以免影响扫描效率,代码如下:
package util
import (
"gopkg.in/cheggaaa/pb.v2"
"x-crack/models"
"x-crack/logger"
"x-crack/vars"
"net"
"sync"
"fmt"
)
var (
AliveAddr []models.IpAddr
mutex sync.Mutex
)
func init() {
AliveAddr = make([]models.IpAddr, 0)
}
func CheckAlive(ipList []models.IpAddr) ([]models.IpAddr) {
logger.Log.Infoln("checking ip active")
var wg sync.WaitGroup
wg.Add(len(ipList))
for _, addr := range ipList {
go func(addr models.IpAddr) {
defer wg.Done()
SaveAddr(check(addr))
}(addr)
}
wg.Wait()
vars.ProcessBarActive.Finish()
return AliveAddr
}
func check(ipAddr models.IpAddr) (bool, models.IpAddr) {
alive := false
_, err := net.DialTimeout("tcp", fmt.Sprintf("%v:%v", ipAddr.Ip, ipAddr.Port), vars.TimeOut)
if err == nil {
alive = true
}
vars.ProcessBarActive.Increment()
return alive, ipAddr
}
func SaveAddr(alive bool, ipAddr models.IpAddr) {
if alive {
mutex.Lock()
AliveAddr = append(AliveAddr, ipAddr)
mutex.Unlock()
}
}
通过标准端口查询对应服务的功能在vars包中定义了,为了避免多个包之间的循环导入,我们把所有的全局变量都集中到了一个独立的vars包中。
PortNamesmap为标准端口对应的服务,在加了新的扫描插件后,也需要更新这个map的内容。
package vars
import (
"github.com/patrickmn/go-cache"
"gopkg.in/cheggaaa/pb.v2"
"sync"
"time"
"strings"
)
var (
IpList = "iplist.txt"
ResultFile = "x_crack.txt"
UserDict = "user.dic"
PassDict = "pass.dic"
TimeOut = 3 * time.Second
ScanNum = 5000
DebugMode bool
StartTime time.Time
ProgressBar *pb.ProgressBar
ProcessBarActive *pb.ProgressBar
)
var (
CacheService *cache.Cache
Mutex sync.Mutex
PortNames = map[int]string{
21: "FTP",
22: "SSH",
445: "SMB",
1433: "MSSQL",
3306: "MYSQL",
5432: "POSTGRESQL",
6379: "REDIS",
9200: "ELASTICSEARCH",
27017: "MONGODB",
}
// 标记特定服务的特定用户是否破解成功,成功的话不再尝试破解该用户
SuccessHash map[string]bool
SupportProtocols map[string]bool
)
func init() {
SuccessHash = make(map[string]bool)
CacheService = cache.New(cache.NoExpiration, cache.DefaultExpiration)
SupportProtocols = make(map[string]bool)
for _, proto := range PortNames {
SupportProtocols[strings.ToUpper(proto)] = true
}
}
- TCA8424低压8x16键盘扫描器数据表
- Android Things I2C地址扫描器
- I2C扫描器开源硬件
- DSP电路板测试中的边界扫描技术研究综述 10次下载
- OTP动态口令的详细资料说明
- OS32C激光扫描器特点及应用 5次下载
- 基于OS32C激光扫描器软件配置及配线 18次下载
- HR3220的无线扫描器用户手册 14次下载
- NLS-HR15XX-30有线式扫描枪用户手册 27次下载
- 基于NLS-HR15XX-3E手持式条码扫描器使用方法 19次下载
- AD9_Crack软件下载 0次下载
- ADS2013.06 CRACK 1.9k次下载
- LS3408ER坚固耐用的扫描器
- netTAP网关在SICK条码扫描器通讯上的应用
- 新的口令认证密钥协商协议
- 如何更好选择二维码识别扫描器厂家? 699次阅读
- 固定式条码扫描器能在条码移动情况下扫描吗? 457次阅读
- 选购固定式二维影像扫描器需要注意什么?考虑哪些方面? 687次阅读
- 工业二维码条码扫描器流水线条码扫描 949次阅读
- 固定式工业级二维码扫描器选型方法 972次阅读
- 工业固定式扫描器怎样用?固定式工业条码扫描器解决方案 1.1k次阅读
- 固定式工业条码扫描器在mes系统中的各个环节应用 1.2k次阅读
- 介绍一款智能Web弱口令爆破工具 3k次阅读
- 基于C++的网络扫描器设计 1.4k次阅读
- NanoBeacon™ BLE扫描器教程(第四部分) 1.1k次阅读
- NanoBeacon™ BLE扫描器教程(第一部分) 1.6k次阅读
- TPS61376升压转换器助力更高集成度条码扫描器方案 1.5k次阅读
- 一款支持弱口令爆破的内网资产探测漏洞扫描工具SweetBabyScan 6.9k次阅读
- 常见服务弱口令爆破工具:crack 2.9k次阅读
- 条码扫描器四种技术工作原理解析 2.1w次阅读
下载排行
本周
- 1ZX8002D触摸无极调光LED集成IC
- 2.43 MB | 1次下载 | 免费
- 2SDDM 激光测距模块产品规格书
- 1.11 MB | 次下载 | 免费
- 3西曼传感SDM50激光测模组产品手册
- 0.65 MB | 次下载 | 免费
- 4STC8H 系列单片机技术参考手册
- 17.85 MB | 次下载 | 1 积分
- 5PC3303 高精度PWM调光LED背光驱动器数据手册
- 2.42 MB | 次下载 | 免费
- 6飞腾 FT2000A/2 核心板 天脉 3/VxWorks 机载实时嵌入式国产化开发板
- 843.50 KB | 次下载 | 免费
- 7AU-60_全功能AI语音处理模组规格书DY)
- 3.18 MB | 次下载 | 免费
- 8WT2003H4录变音芯片及模块说明书V1
- 3.61 MB | 次下载 | 免费
本月
- 1瑞芯微RK3572开发板-产品资料更新-2026.06
- 3.30 MB | 4次下载 | 免费
- 2四键电容式触摸按键IC FZH34产品手册
- 0.41 MB | 2次下载 | 免费
- 3矩形科技 CANopen 远程IO模块产品手册
- 7.93 MB | 2次下载 | 免费
- 4高性能非隔离交直流转换芯片 PC9403A数据手册
- 0.34 MB | 2次下载 | 免费
- 5OC5721欧创芯开关降压型LED恒流驱动器
- 404.39 KB | 2次下载 | 免费
- 6PC9830 18V-3A集成高低侧功率管同步降压转换器数据手册
- 9.01 MB | 1次下载 | 免费
- 7GL65P06A8产品光磊 60V 65A P沟道功率 MOSFET
- 1.07 MB | 1次下载 | 免费
- 8ZX8002D触摸无极调光LED集成IC
- 2.43 MB | 1次下载 | 免费
总榜
- 1matlab软件下载入口
- 未知 | 935137次下载 | 10 积分
- 2开源硬件-PMP21529.1-4 开关降压/升压双向直流/直流转换器 PCB layout 设计
- 1.48MB | 420064次下载 | 10 积分
- 3Altium DXP2002下载入口
- 未知 | 233095次下载 | 10 积分
- 4电路仿真软件multisim 10.0免费下载
- 340992 | 191476次下载 | 10 积分
- 5十天学会AVR单片机与C语言视频教程 下载
- 158M | 183362次下载 | 10 积分
- 6labview8.5下载
- 未知 | 81608次下载 | 10 积分
- 7Keil工具MDK-Arm免费下载
- 0.02 MB | 73836次下载 | 10 积分
- 8LabVIEW 8.6下载
- 未知 | 65992次下载 | 10 积分
电子发烧友App





创作
发文章
发帖
提问
发资料
发视频
上传资料赚积分
评论