介绍
跨站点脚本(XSS)是当今Web应用程序中最普遍的漏洞之一。在没有源代码的情况下进行黑匣渗透时,我们通常会通过将有效负载插入到各处输入框中并等待弹框出现来证明漏洞存在当然还有盲插。如果我们能拿到源代码,则查找XSS漏洞可以更快,更轻松。
XSS基础
在搜索XSS漏洞时,该漏洞在所有编程语言中其实都差不多。如果某个应用程序将用户提供的输入放在浏览器中而不验证输入或清除该输入,则它们很可能会受到XSS攻击。
<code>
function(username)
welcome_message = "<h1>Welcome to the site " + username + "</h1>"
return welcome_message to browser
</code>
我们在上面的代码中所看到的,该应用程序正在使用人员用户名并将其返回给H1标头主体中的浏览器。那么我们可以轻松插入恶意javascript代码作为其用户名,从而导致应用程序执行它。
有多种技术可以防止此问题发生,例如使用内容安全策略(CSP)。在源代码中,防止XSS的最常见方法是先清理用户提供的输入,然后再将其返回给浏览器。大多数现代编程语言都带有一个库,可以为开发处理此逻辑。
<code>
function(username)
username = sanitize_input_xss(username)
welcome_message = "<h1>Welcome to the site " + username + "</h1>"
return welcome_message to browser
</code>
如上面的代码所示,我们使用预定义的函数(sanitize_input_xss)在将用户名返回浏览器之前对其进行清理。这样可以防止XSS发生。
例
善于发现源代码漏洞的唯一方法是获得一些实践经验。我们看一下下面的代码。
https://github.com/Learn-by-doing/xss/blob/master/public/index.html
<html>
<head>
<title>Cross-Site Scripting (XSS)</title>
</head>
<body>
<!-- A simple form that when submitted will navigate back to the same page -->
<form action="" method="GET">
<!-- Adds `?q=VALUE` to the URL when the form is submitted -->
<input type="text" name="q">
<input type="submit" value="Search">
</form>
<!-- The results of the search are inserted here -->
<div id="results"></div>
<script>
document.addEventListener('DOMContentLoaded', function() {
/*
Get the search query from the URL. For example:
http://xss-example-page.nowhere/?q=Searching+for+things
*/
var q = getQueryParameter('q');
if (q) {
search(q, function(error, results) {
showQueryAndResults(q, results);
});
}
});
function search(q, callback) {
// Fake results. We don't actually searching anything.
var results = [
'Result #1',
'Result #2',
'Result #3'
];
callback(null, results);
}
function showQueryAndResults(q, results) {
var resultsEl = document.querySelector('#results');
var html = '';
html += '<p>Your search query:</p>';
html += '<pre>' + q + '</pre>';
html += '<ul>';
for (var index = 0; index < results.length; index++) {
html += '<li>' + results[index] + '</li>';
}
html += '</ul>';
resultsEl.innerHTML = html;
}
function getQueryParameter(name) {
var pairs = window.location.search.substring(1).split('&');
var pair;
for (var index = 0; index < pairs.length; index++) {
pair = pairs[index].split('=');
if (decodeURIComponent(pair[0]) === name) {
return decodeURIComponent(pair[1]);
}
}
return false;
}
</script>
</body>
</html>
我们要做的第一件事就是寻找用户提供给定输入的任何地方。我们可以看到,提供GET参数“ q”将导致应用程序将其值保存在变量中,如下所示:
var q = getQueryParameter('q');
然后,应用程序将使用此代码。请注值并创建一些HTML意,用户提供的价值永远不会被恶意输入清除或以任何方式进行验证。
var html = '';
html += '<p>Your search query:</p>';
html += '<pre>' + q + '</pre>';
html += '<ul>';
然后,浏览器使用以下命令来呈现此代码:
resultsEl.innerHTML = html;
您应该时刻注意“ innerHTML” javascript函数。此功能使我们可以即时修改HTML代码,其实在许多基于DOM的XSS漏洞中都可以看到。
该漏洞在一段JavaScript代码中,但是在PHP,Python或任何其他应用程序时,其实也是差不多。
结论
绝大多数渗透都是黑盒测试的,但是如果我们能拿到有源代码,则应该进行代码审计。分析应用程序源代码可以让我们发现在进行黑盒测试时错过的漏洞。代码审计能够找到隐藏的功能和路径。使我们能够快速找到漏洞,并对如何绕过它们可能存在的任何过滤设置有更深入的了解。
代码审计SQL注入基础
自从网络开始,SQL注入就出现了。它一直排名在OWASP的前十名。几乎每个应用程序都以某种方式与后端数据库进行交互,因此,它是目前最流行的漏洞之一。当进行渗透测试时,我们应该在每个参数都尝试一下 ‘ 或“,查看页面是否出了错,是否存在SQL注入。我们本文从代码审计中查找SQL注入的漏洞。
字符串串联
很多漏洞是由字符串连接引起的。当我们把恶意的符串组合在一起时,可能出现缓冲区溢出,XSS,SQL注入和许多其他漏洞。
buffer_Overflow = string1 + user_supplied_string
XSS = string1 + user_supplied_string + string2
SQL_Injection = string1 + user_supplied_string + string2
当我们看到如上把用户提供的输入与字符串组合在一起,则我们应该重点检查是否存在漏洞。
SQL注入基础
当我们的恶意输入未过滤直接传递到后端数据库时,将发生SQL注入。我们进行代码审计时,我首先要寻找的是常见的SQL字符串,如下所示:
SELECT column_name from table_name where username = user_input
UPDATE column_name set column_name = "s" where username = user_input
可以看到“ SELECT”,它通常会向我们显示数据库的调用方法。从上面代码我们可以知道我们可以构建一个恶意的SQL语句来进行注入。
我们还可以搜索通用功能名称。每种程序语言都有特定的功能,用于与后端数据库进行通信。除了搜索公共数据库字符串,我们还可以搜索用于与数据库通信的公共函数。例如,PHP使用“ mysql_query”函数进行数据库调用。
Python下面的代码是用python编写的。我们要做的第一件事就是查找用户提供的输入在哪里。
def search():
code = request.args.get('code')
conn = sqlite3.connect("data.db")
c = conn.cursor()
try:
statement = "select * from data where data='" + code + "'"
c.execute(statement)
found = c.fetchall()
if found == []:
return f"Invalid Code<br>{statement}"
else:
return f"Wifi Connection Established<br>{statement}"
except sqlite3.Error as e:
return str(e) + f"<br>{statement}
我们可以传递一个称为“ code”的GET参数,该参数将保存到变量中。
code = request.args.get('code')
下一步是确定是否将该变量不正确地传递给数据库查询字符串,如下所示:
statement = "select * from data where data='" + code + "'"
您可以清楚地看到变量“ code”正在与查询字符串组合。没有检查或过滤等等。这表明了存在SQL注入。
PHP
对于PHP,我们将使用以下PHP代码了来讲解代码审计。
https://github.com/bchazalet/web-app-security-examples/tree/master/sql-injection-examples (php示例下载)
<html>
<head>
<title>PHP Test</title>
</head>
<body>
<?php echo '<p>SQL injection demo 1</p>'; ?>
<?php
$con = mysql_connect("localhost","sqli","sqli");
if (!$con) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db("sqliexample", $con);
$id = $_GET['id']; // No input validation!!
$result = mysql_query("SELECT name FROM user WHERE id=$id", $con);
mysql_close($con);
$num = mysql_num_rows($result);
$i=0;
while ($i < $num) {
$name = mysql_result($result, $i, "name");
echo "Hello " . $name;
echo "<br/>";
$i++;
}
?>
</body>
</html>
现在,我们从上面python中知道了如何寻找该漏洞。那么在PHP中也是同理。我们可以清楚地看到用户提供的输入正在传递到数据库字符串,如下所示:
$id = $_GET['id']; // 这里没有输入验证!!!!
$result = mysql_query("SELECT name FROM user WHERE id=$id"
这是一个PHP应用,但其实跟python示例相同。我们将用户提供的输入直接传递给未经验证的数据库查询字符串。该应用程序显然容易受到sql注入的攻击。
结论
SQL注入是最古老和最受欢迎的漏洞之一。如果您可以访问应用程序源代码,则发现此漏洞非常容易。如果看到用户提供的输入与数据库查询字符串结合在一起,则很可能存在注入SQL。
文章来源于:黑白天
本文介绍了XSS和SQL注入的基础知识,强调在没有源代码时的黑盒渗透和有源代码时的代码审计的重要性。通过示例代码解释了如何在不同编程语言中寻找XSS和SQL注入漏洞,提醒开发者注意对用户输入的验证和清理。
1420

被折叠的 条评论
为什么被折叠?



