Regex Injection

Regex Injection

πŸ” Introduction

Regex Injection은 κ³΅κ²©μžκ°€ Regexκ°€ compile 되기 μ „ regex νŒ¨ν„΄μ— 영ν–₯을 쀄 수 μžˆλŠ” Injection 곡격을 μ˜λ―Έν•©λ‹ˆλ‹€. Injection 곡격으둜 큰 영ν–₯λ ₯이 λ°œμƒν•˜λŠ”κ±΄ μ•„λ‹ˆμ§€λ§Œ, 이λ₯Ό 톡해 ReDOSλ₯Ό μ‰½κ²Œ λ°œμƒμ‹œν‚¬ 수 μžˆμŠ΅λ‹ˆλ‹€.

πŸ—‘ Offensive techniques

Detect

With Sourcecode

μ†ŒμŠ€μ½”λ“œκ°€ μžˆλ‹€λ©΄ μ‚¬μš©μž μž…λ ₯값이 μ •κ·œν‘œν˜„μ‹ 문법에 영ν–₯을 μ£ΌλŠ”μ§€ μ²΄ν¬ν•˜λ©΄ λ©λ‹ˆλ‹€. λŒ€ν‘œμ μœΌλ‘œ μ •κ·œν‘œν˜„μ‹ 문법을 μ™ΈλΆ€ νŒŒλΌλ―Έν„°λ‘œ μƒμ„±ν•˜λŠ” 경우 이에 ν•΄λ‹Ήλ©λ‹ˆλ‹€.

Code

data := c.Param("user_data")
body := c.Param("user_body")
r, _ := regexp.Compile(data)
r.FindString(body)

Request

GET /target?user_data=/[a-z]/g&user_body=abcd

Without Sourcecode

μ†ŒμŠ€μ½”λ“œκ°€ μ—†λ‹€λ©΄ ReDOS ꡬ문과 문자λ₯Ό ν¬ν•¨μ‹œμΌœ μ μœ μœ¨μ„ 높인 ν›„ Response, Response Time 등을 μ΄μš©ν•΄ μΆ”μΈ‘ν•˜λŠ” 것이 μ΅œμ„ μž…λ‹ˆλ‹€.

Exploitation

ReDOS

Regexp νŒ¨ν„΄μ„ μˆ˜μ •ν•  수 μžˆλŠ” 경우 μ•„λž˜ νŒ¨ν„΄κ³Ό 같이 큰 μ˜€λ²„ν—€λ“œλ₯Ό λ°œμƒμ‹œν‚€λŠ” ReDOS νŒ¨ν„΄μœΌλ‘œ 으둜 λ³€κ²½ν•©λ‹ˆλ‹€.

(a+)+
([a-zA-Z]+)*
(a|aa)+
(a|a?)+
(.*a){x} for x \> 10

ReDOS에 λŒ€ν•œ μžμ„Έν•œ λ‚΄μš©μ€ Cullinan > ReDOSλ₯Ό μ°Έκ³ ν•΄μ£Όμ„Έμš”!

Other

아직은 ReDOS 이외에 νŠΉλ³„ν•œ Exploting 방법이 μžˆλŠ”κ±΄ μ•„λ‹™λ‹ˆλ‹€. λ‹€λ§Œ μ–΄λ–»κ²Œ ν™œμš©λ μ§€λŠ” 아직 λͺ¨λ₯΄λŠ” 일이기 λ•Œλ¬Έμ— μ‹œνμ–΄μ½”λ”© κ΄€μ μ—μ„œλΌλ„ κ³ μΉ˜λŠ”κ²Œ μ’‹μ„κ±°λž€ 생각이 λ“œλ„€μš”. μ•„λž˜ daily-swig에도 λΉ„μŠ·ν•œ λ‚΄μš©μ˜ 글이 μžˆμœΌλ‹ˆ μ°Έκ³ ν•΄μ£Όμ„Έμš”!

  • https://portswigger.net/daily-swig/blind-regex-injection-theoretical-exploit-offers-new-way-to-force-web-apps-to-spill-secrets

πŸ›‘ Defensive techniques

μ •κ·œν‘œν˜„μ‹μ€ 가급적 μ‚¬μš©μž μž…λ ₯κ°’μœΌλ‘œ μƒμ„±λ˜μ§€ μ•Šλ„λ‘ μ£Όμ˜ν•΄μ•Όν•©λ‹ˆλ‹€. λ§Œμ•½ μ‚¬μš©μž μž…λ ₯κ°’μœΌλ‘œ λΆ€ν„° μ •κ·œν‘œν˜„μ‹ 생성이 ν•„μš”ν•˜λ‹€λ©΄ ν—ˆμš©ν•  수 μžˆλŠ” νŒ¨ν„΄μ˜ λ²”μœ„ λ“± ReDOSλ₯Ό μ™„ν™”ν•  수 μžˆλŠ” 검증 둜직이 ν•„μš”ν•©λ‹ˆλ‹€.

Worst-case

data := c.Param("user_data")
body := c.Param("user_body")
r, _ := regexp.Compile(data)
r.FindString(body)

Better-case

allowList := []string{
	"[a-z]",
	"[1-9]",
	"abcd",
}

data := c.Param("user_data")
body := c.Param("user_body")
if checkAllowList(data, allowList) {
	r, _ := regexp.Compile(data)
	r.FindString(body)
}

πŸ“Œ References

  • https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
  • https://portswigger.net/daily-swig/blind-regex-injection-theoretical-exploit-offers-new-way-to-force-web-apps-to-spill-secrets