您的位置:首页 > 编程语言

黑客攻防技术宝典web实战篇:查找源代码中的漏洞习题

2019-05-19 11:36 495 查看

猫宁!!!

参考链接:http://www.ituring.com.cn/book/885

 

随书答案。

1. 列出 3 种可在源代码中找到明确签名的常见漏洞。


(a) 跨站点脚本
(b) SQL 注入
(c) 路径遍历
(d) 任意重定向
(e) 操作系统命令注入
(f) 后门密码
(g) 某些本地代码漏洞


2. 当审查 PHP 应用程序时,为什么有时很难确定用户输入的所有来源?


PHP 使用一系列内置数组来存在用户提交的数据。如果启用了
register_globals,则 PHP 会为每个请求参数创建一个全局变量,并且应用程序
会通过引用一个同名变量来访问参数——没有任何语法现象表明此变量表示用
户输入,而不是在其他位置定义的任何其他变量。


3. 以下两个执行 SQL 查询的方法都使用了用户提交的输入:
// method 1
String artist = request.getParameter(“artist”).replaceAll(“’”,“’’”);
String genre = request.getParameter(“genre”).replaceAll(“’”, “’’”);
String album = request.getParameter(“album”).replaceAll(“’”, “’’”);
Statement s = connection.createStatement();
s.executeQuery(“SELECT * FROM music WHERE artist = ‘” + artist +
‘” AND genre = ‘” + genre + ‘” AND album = ‘” + album + “’”);
// method 2
String artist = request.getParameter(“artist”);
String genre = request.getParameter(“genre”);
String album = request.getParameter(“album”);
Statement s = connection.prepareStatement(
“SELECT * FROM music WHERE artist = ‘” + artist +
“’ AND genre = ? AND album = ?”);
s.setString(1, genre);
s.setString(2, album);
s.executeQuery();
哪一个方法更加安全,为什么?


方法 1 更加安全。
虽然方法 1 从用户输入动态构建 SQL 查询,但它将输入中出现的所有单引号全部
配对,并将所有用户提交的参数视为字符串数据。虽然这并非安全处理 SQL 查询
的最佳方法,但目前似乎并没有任何 SQL 注入风险。
方法 2 使用一个参数化查询,这是在 SQL 语句中安全合并用户提交的输入的首选
方法。但是,在三个用户输入中,只有两个输入被正确参数化。其中一个输入被
错误地直接放置到指定查询结构的字符串中,因此应用程序肯定易于受到 SQL
注入攻击。


4. 在审查一个 Java 应用程序代码时,首先要检查
HttpServletRequest.getParameter API 的所有用法。下列代码引起了你的注意:
private void setWelcomeMessage(HttpServletRequest request) throws
ServletException
{
String name = request.getParameter(“name”);
if (name == null)
name = “”;
m_welcomeMessage = “Welcome “ + name +”!”;
}
这段代码表示应用程序中可能存在什么漏洞?还需要进行哪些代码分析才能确
定应用程序是否确实易于受到攻击?


该应用程序可能易于受到反射型 XSS 攻击,因为它似乎正从请求参数直接构建在
屏幕上显示的欢迎消息。
仅仅从这个代码片段无法最终确认应用程序是否易于受到攻击。为此,还需要进
行以下调查:
(a) 是否对其他位置的 name 参数执行了任何输入确认;以及
(b) 在将 m_welcomeMessage 复制到应用程序的响应中之前,是否对它执行了任
何输出确认。


5. 假设渗透测试员正在审查一个应用程序用于生成会话令牌的机制。相关代码
如下:
public class TokenGenerator
{
private java.util.Random r = new java.util.Random();
public synchronized long nextToken()
{
long l = r.nextInt();
long m = r.nextInt();
return l + (m << 32);
}
}
应用程序生成的会话令牌是否可以预测?请解释理由。


是。了解所使用的令牌创建算法后,就可以基于一个令牌示例进行前后推断,从
而确定应用程序创建的所有令牌。
Java API java.util.Random 实施一个线性同余发生器,可根据一个完全可预测
的算法生成伪随机数字。如果知道该发生器在任何迭代时的状态,就可以推断出
它接下来将生成的数字序列,以及它之前生成的序列(利用一点数论知识)。
但是,java.util.Random 发生器维持 48 位的状态,而 nextInt 方法仅返回 32
位的状态。因此,获取 nextInt 方法的一次输出并不足以确定该发生器的状态,
或者预测它的输出序列。
当前,我们可以轻松解决这个难题,因为应用程序使用的算法会连续两次调用
nextInt。创建的每个会话令牌均包含发生器的一次迭代的 32 位状态,以及下一
次迭代的 32 位状态。基于这些信息,就可以直接实施本地蛮力攻击,以查明第
一次迭代所缺少的 16 位状态(通过尝试缺少的 16 个位的每个可能的排列组合,
并测试发生器是否会输出从第二次迭代中获取的 32 个位)。确认缺少的 16 个位
后,就知道了发生器的完整状态,从而能够以标准的方法推断随后及以前的输出。
讽刺的是,开发者做出的两次调用 nextInt 并组合相关结果的决定却使令牌创建
算法比在其他情况下更易于受到攻击。
有关这类攻击的详情,请参阅以下由 Chris Anley 撰写的论文:
http://www.ngssoftware.com/research/papers/Randomness.pdf

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: