E-mail 포맷을 이용한 여러가지 Exploiting 기법들

Recently, the nahamcon2020 was in over. I difficult to watching it in my time zone, so I just looked at the documents after it’s over. They were all very interesting and I learned a lot of new things. Today I’m going to talk about the email attack that I saw the most interesting among them. Of course, if you using english, best document is original material, so refer to the link below, and I will write only in Korean today!

https://drive.google.com/file/d/1iKL6wbp3yYwOmxEtAg1jEmuOf8RM8ty9/view

서론이 길었군요. 정말 오랜만에 글을씁니다. COVID19 이후 벌써 반년정도 재택근무를 하고 있고, 출퇴근 시간을 아끼다보니 블로그 글을 쓰는 시간보다 개발하거나 개인적인 연구를 하는 시간이 좀 더 늘어난 것 같습니다. (글 쓸 시간이 없었다고 핑계를 대는중)

아무튼 최근에 Nahamcon2020이 진행됬고, 이 글을 읽는 여러분들과 동일하게 우리의 타임존에선 완전 새벽이기 때문에 직접 보기에는 조금 어렵습니다. 솔직히 진짜 내용 다 재미있고 놓쳤던 부분들을 다시 한번 체크하게 해주는 내용들이 꼭 읽어보시길 바랍니다.

오늘은 그중에선 Email에 대한 이야기를 할거구요. 가볍에 어떤 내용인지만 정리하려고 합니다. 실제 케이스들은 직접 발표자료 보셔서 확인하시는게 제일 좋을 것 같아요.

E-mail address

Email의 포맷은 local part + domain part 로 구성되어 있습니다.

Localpart

Local part는 계정 이름의 영역이며 영 대소문자 + 숫자, . 과 일부 특수문자 정도만 사용 가능합니다.

Latin letters A-Z and a-z
 - a@example.com

Digits 0 to 9
 - 1337@example.com

Dot . (Not first character, not last one, no consecutive dots
 - john..doe@example.com

Printable characters !#$%&'*+-/=?^_`{|}~
 - alice&john!@example.com

International characters (above U+007F, encoded as UTF-8)
 - jöhn.døê@gmail.com

다만 더블 쿼터(") 로 쌓여있다면 이야기가 달라집니다. " ( ) , : ; < > @ [ ] , space, tab, emoji 등 일반적인 상황의 local part에서 쓸 수 없는 문자들을 사용할 수 있어집니다.

Extra characters: "(),:;<>@[\]
- "\"@example.com (quotes and backslashes need a backslash)
- "@"@example.com

Spaces, tabs
- " "@example.com

Even emoji’s
- "�"@gmail.com

또한 괄호 ( , ) 를 통해 값을 주석처럼 무시할 수도 있습니다.

Domain part

Domain part는 이메일에서 @ 뒷 부분인 도메인을 의미하며 대소문자 +, 숫자, - 정도만 가능합니다. 이건 고정된 포맷이라 건드릴수가 없습니다.

Payloads

자 위에서 일부 특수문자를 보신순간 바로 몇가지 떠오르셨겠지만 결국 email의 local part, 즉 사용자 이름 부분에 특수문자를 사용할 수 있다는 의미고 특수문자를 기반으로 한 웹 공격에는 모두 사용될 수 있는 의미이기도 합니다.

Type Payload
XSS test+(<script>alert(0)</script>)@example.comtest@example(<script>alert(0)</script>).com"<script>alert(0)</script>"@example.com
SSTI "<%= 7 * 7 %>"@example.comtest+(${{7*7}})@example.com
SQLi "' OR 1=1 -- '"@example.com"mail'); DROP TABLE users;--"@example.com
SSRF (Era of ssrf) john.doe@abc123.burpcollaborator.netjohn.doe@[127.0.0.1]
Parameter pollution victim&email=[attacker@example.com](mailto:attacker@example.com)
Email header injection "%0d%0aContent-Length:%200%0d%0a%0d%0a"@example.com"%0d%0aContent-Length:%200%0d%0a%0d%0a"@example.com
Wildcard abuse %@example.com

예를들면, A라는 시스템이 사용자의 email 정보를 저장해서 어드민에 뿌려주는데, 이 떄 일반적인 email 검증 패턴으론 hahwul@gmail.com<svg/onload=alert(45) 같은 페이로드는 잘 걸러집니다. (왜냐면 도메인 파츠에선 특수문자를 사용할 수 없으니깐요) 또한 유저 이름 구간에 들어간다고 해도, 그 결과는 동일합니다. <> 등을 사용할 수 없는건 마찬가지죠.

이제 우리는 "( ) 등을 이용해서 사용자 이름 구간에 특수문자를 삽입하는 법을 알았으니, 이런 방식의 공격코드 구성이 가능해집니다.

"hahwul<svg/onload=alert(45)>"@gmail.com

다른 케이스도 비슷비슷합니다.

Bypassing verify logic

두번쨰, 이러한 규칙을 이용하면 bypassing을 위한 특별한 케이스를 만들어낼 수 있습니다. 아래 2가지 케이스를 보면 ..

john.doe+intigriti@example.com → john.doe@example.com
john.doe(intigriti)@example.com → john.doe@example.com

위에껀 + 가 붙은 경우인데, 이 때 + 뒤의 문자열은 무시되고 앞의 local part 를 기준으로 메일주소로 인식합니다. 두번째도 비슷한데, ( ) 안의 문자열은 무시됩니다.

이제 각종 검증 로직 우회를 위한 패턴을 만들어낼 수 있습니다.

inti(;inti@inti.io;)@whitelisted.com
 → inti(;
 → inti@inti.io → my inbox!
 → ;)@whitelisted.com

inti@inti.io(@whitelisted.com)
inti+(@whitelisted.com;)@inti.io

Conclusion

이게 단순히 email system에서만 사용되는거라면, 그냥 가볍게 볼 내용이지만 실제로 Email format은 다른 웹 서비스/환경에서도 굉장히 많이 사용되고 있는 패턴이라 잘 숙지해둬야할 것 같네요 :D