- vừa được xem lúc

Security Risk - Timing attack. Khó nhưng hoàn toàn khả thi

0 0 23

Người đăng: Kha Leo

Theo Viblo Asia

Timing Attack là một trong những kĩ thuật mà hacker lợi dụng việc tính toán ở phía server để điều chỉnh payload attack cho phù hợp. Trong bài viết này mình sẽ nêu một ví dụ phổ biến nhất về cách tấn công này cũng như cách phòng chống với Golang

I. Timing Attack

  • Là một dạng tấn công thuộc loại side-channel mà hacker dựa vào thông tin phân tích được từ thời gian thực thi một đoạn logic từ hệ thống từ đó truy ra dần kết quả sau cùng, có thể xem Timing Attack là một dạng manual brute force cũng được, vì cùng một cách thức để truy ra kết quả, nhưng khác là hacker cần đầu tư nhiều hơn để phân tích dữ liệu đang có để cho ra input tiếp theo.
  • Hacker luôn cố gắng lợi dụng sơ sẩy của lập trình viên ở những đoạn code logic phổ biến mà thường bị tầm thường hoá (mình sẽ nêu ví dụ ở bên dưới) hoặc những library (open source) mà chúng ta thường dùng, cũng không thoát khỏi việc chứa lỗ hổng này

II. Ví dụ thực tế

Đối với lập trình viên, chúng ta sẽ phải gặp trường hợp cần xác thực request đến từ phía client, hay server to server. Có rất nhiều cách để triển khai, thông thường là sử dụng JWT, Oauth2, OpenID Connect hay sử dụng bên thứ 3 để authen như Google, Facebook, AWS Cognito...Một trong những cách phổ biến và dễ triển khai nhất là sử dụng API key.

Tuy nhiên APIKey vẫn có thể bị lộ bằng nhiều cách tấn công, một trong số đó là Timing attack

III. Cách phòng chống Timing Attack

Có một người Thầy ở trường của mình đã truyền bí kíp cho sinh viên cách chống hoàn toàn việc hệ thống, ứng dụng của mình bị hack. Bằng cách ngắt internet đi, hay ứng dụng đó "xịn" đến nỗi mà hacker không thèm tấn công hoặc.. cách cuối cùng là thắp nhang cầu xin 😂

Nói đùa một chút thôi, chúng ta không thể nào ngăn chặn hoàn toàn rủi ro hệ thống bị tấn công, nhưng khi hiểu về nó, chúng ta sẽ làm con đường mà hacker đang tìm trở nên khó khăn hơn.

Mình sẽ sử dụng Golang cho ví dụ ở trên, khi sử dụng API key, chắc chắn sẽ có đoạn logic cần thực hiện để thực hiện so sánh API key được gửi kèm từ request với key được lưu trữ ở phía server. Chúng ta thường sử dụng thuật toán mặc định (toán tử ==) để thực hiện so sánh, đơn giản như thế thôi, nhưng thực tế điều này có thể được hacker lợi dụng.


var ( a []byte length int = 1e8 bound int = length / 10
) func init() { a = make([]byte, length) rand.Read(a)
} func copyStr(changedIndex int) []byte { b := make([]byte, length) copy(b, a) if b[changedIndex] == 0 { b[changedIndex] = 1 } else { b[changedIndex] = 0 } return b
} func formatString(s int) string { str := strconv.Itoa(s) var result string for i := len(str) - 1; i >= 0; i-- { if (len(str)-1-i)%3 == 0 && i != len(str)-1 { result = "." + result } result = string(str[i]) + result } return result
} func execute(fn func(a, b []byte) bool) { for i := length - 1; i > 0; i -= bound { b := copyStr(i) startTime := time.Now() fn(a, b) endTime := time.Since(startTime) fmt.Printf("Differences at Index: %s, time execute: %s\n", formatString(i), endTime.String()) }
} func Compare(a, b []byte) bool { return string(a) == string(b)
} func CompareConstantTime(a, b []byte) bool { return subtle.ConstantTimeCompare(a, b) == 1
}
  • Đoạn code trên sẽ so sánh 2 chuỗi có độ dài như nhau nhưng tại một index nào đó sẽ khác nhau. Với toán tử ==, chương trình sẽ ngay lập tức dừng thực hiện so sánh phần còn lại và trả về kết quả..hmmm bạn hiểu rồi chứ 😄. Nếu API key của bạn là "abc", hacker sẽ thử với chuỗi "aaa" và "aba", dễ nhận thấy thời gian thực hiện chuỗi "aba" lâu hơn, nên có thể đoán được "aba" là chuỗi có độ chính xác cao hơn, và cứ thế tiếp tục...

Chính vì thế trong đoạn code trên mình có sử dụng subtle.ConstantTimeCompare, function trả về 1 nếu hai chuỗi bằng nhau,0 nếu khác nhau và ngay lập tức trả về 0 nếu độ dài hai chuỗi không giống nhau. Nhưng khác với so sánh chuỗi thông thường như thế nào thì chúng ta sẽ chạy đoạn code trên và quan sát kết quả:

func main() { fmt.Printf("Length of chars: %s\n\n", formatString(length)) fmt.Println("Normal comparison: using equal operator") execute(Compare) fmt.Println("\n" + strings.Repeat("*", 50) + "\n") fmt.Println("Constant time comparison: using subtle.ConstantTimeCompare") execute(CompareConstantTime)
}

  • Đối với so sánh thông thường, vị trí khác nhau của chuỗi càng về sau, thời gian thực thi sẽ càng lâu nhưng với ConstantTimeCompare, kết quả thực thi luôn đảm bảo gần như giống nhau

IV. Kết luận

  • Trên thực tế thời gian thực thi sẽ ảnh hưởng bởi rất nhiều yếu tố như network latency, thead khác,...có thể phải thực hiện rất nhiều mẫu thử để cho ra sai số nhỏ nhất. Cách tấn công này thực sự rất khó để đạt được mục đích nhưng hoàn toàn có thể xảy ra
  • Bên cạnh đó việc sử dụng ConstantTimeCompare sẽ tốn thời gian hơn, chúng ta hãy sử dụng khi thật sự cần thiết nhé ^^

    Cảm ơn các bạn đã xem bài viết.

Bình luận

Bài viết tương tự

- vừa được xem lúc

gRPC - Nó là gì và có nên sử dụng hay không?

Nhân một ngày rảnh rỗi, mình ngồi đọc lại RPC cũng như gRPC viết lại để nhớ lâu hơn. Vấn đề là gì và tại sao cần nó .

0 0 132

- vừa được xem lúc

Embedded Template in Go

Getting Start. Part of developing a web application usually revolves around working with HTML as user interface.

0 0 57

- vừa được xem lúc

Tạo Resful API đơn giản với Echo framework và MySQL

1. Giới thiệu.

0 0 61

- vừa được xem lúc

Sử dụng goquery trong golang để crawler thông tin các website Việt Nam bị deface trên mirror-h.org

. Trong bài viết này, mình sẽ cùng mọi người khám phá một package thu thập dữ liệu có tên là goquery của golang. Mục tiêu chính của chương trình crawler này sẽ là lấy thông tin các website Việt Nam bị deface (là tấn công, phá hoại website, làm thay đổi giao diện hiển thị của một trang web, khi người

0 0 237

- vừa được xem lúc

Tạo ứng dụng craw dữ liệu bing với Golang, Mysql driver

Chào mọi người . Lâu lâu ta lại gặp nhau 1 lần, để tiếp tục series chia sẻ kiến thức về tech, hôm nay mình sẽ tìm hiểu và chia sẻ về 1 ngôn ngữ đang khá hot trong cộng đồng IT đó là Golang.

0 0 76

- vừa được xem lúc

Golang: Rest api and routing using MUX

Routing with MUX. Let's create a simple CRUD api for a blog site. # All . GET articles/ .

0 0 55