이것저것 뒤적여 보다가, 설마를 외치며 DH{ 를 검색해 보았다...

주석으로 flag가 숨어 있다...

'0x40 Web Hacking' 카테고리의 다른 글

Dreamhack :: simple_sqli  (0) 2022.05.17
Dreamhack :: session-basic  (0) 2022.05.17
Dreamhack :: Carve Party  (0) 2022.05.17
Dreamhack :: simple-ssti  (0) 2022.05.17

문제에서 제공해주는 app.py 플라스크 코드를 보면 간단하게 DB를 생성하는 부분과 로그인 하는 부분으로 구분되어 있는 것을 알 수 있다.

DB를 생성하는 부분은 guest/guest 계정과 admin/os.urandom(16) 계정을 만들며,
로그인 부분에서는 사용자로부터 id와 password를 입력받아 쿼리를 보낸다. 하지만 사용자로부터 받은 입력 값에 대한 검증이 없기 때문에 sql injeciton을 허용한다.

해당 어플리케이션에서 사용한 DB는 sqlite3로 주석으로 -- 를 사용한다.
즉 사용자의 계정에 admin을 넣고 그 뒤를 주석 처리해 버리면 된다.

상세 과정

select * from users where userid="{userid}" and userpassword="{userpassword}"

쿼리는 사용자로부터 입력 받은 값들을 그대로 사용하게 된다.

admin” -- 를 id 부분에 넣고, 비밀번호 부분에는 아무것이나 넣어주면(e.g., 1234) 쿼리는 다음과 같이 된다.

select * from users where userid="admin" -- and userpassword="1234"

그러면 주석 뒤 부분은 무시가 되기 때문에 아래와 같은 쿼리가 된다.

select * from users where userid="admin"

즉 admin에 대한 계정을 조회하는 쿼리가 되는 것이다.
따라서 admin 계정의 비밀번호를 모르더라도 로그인 할 수 있게 된다.

'0x40 Web Hacking' 카테고리의 다른 글

Dreamhack :: devtools-sources  (0) 2022.05.17
Dreamhack :: session-basic  (0) 2022.05.17
Dreamhack :: Carve Party  (0) 2022.05.17
Dreamhack :: simple-ssti  (0) 2022.05.17

웹 어플리케이션은 크게 3부분('/', '/login', '/admin')으로 구성되어 있다.

우선 / 라우트를 보면, session_storage에서 session_id를 기반으로 username을 가져오고 이 username이 admin 일때 flag를 보여주도록 한다.
그렇기에 우리가 해야할 것은 쿠키의 sessionid 값을 admin의 것으로 바꾸면 될 것이다.

그렇기에 필요한 라우트가 /admin이다. /admin 라우트에서는 저장되어 있는 session_storage를 보여주는데 어플리케이션이 시작되기 전 session_storage에 username이 admin인 session_id를 저장해 두기 때문에, 해당 session_id를 가져와서 쿠키에 저장되어 있는 sessionid 값을 이로 바꿔주면, admin 계정이 로그인 한 것으로 인식할 것이다.

상세 과정

  • /login 라우트에서 guest/guest 로 로그인함
  • /admin 라우트에서 값이 adminsession_id를 확인함
  • 쿠키의 sessionid 값을 위의 adminsession_id로 수정함
  • / 라우트에서 플래그 확인함

'0x40 Web Hacking' 카테고리의 다른 글

Dreamhack :: devtools-sources  (0) 2022.05.17
Dreamhack :: simple_sqli  (0) 2022.05.17
Dreamhack :: Carve Party  (0) 2022.05.17
Dreamhack :: simple-ssti  (0) 2022.05.17

문제를 보면 특정 사이트에 연결된 것이 아닌 html 파일 하나를 준다. 즉 이는 서버에서 뭔가를 수행하는 것이 아닌 클라이언트에서 작업을 수행하는 것을 유추할 수 있다.

클릭에 따른 counter 값 감소, 특정 값에 도달할 때 뭔가를 수행함을 생각해 볼때, 제일 먼저 생각난 것은 onclick event에 따른 counter 값 증가였다.

하지만 onclick 은 사용되지 않았으며, script 부분을 살펴본 결과 click에 call back 함수를 정의한 것을 확인할 수 있다.

함수를 보면 pumpkin 리스트에 대하여 특정 연산을 수행하고, 이를 기반으로 canvas에 그리게 된다.

상세 과정

방법 1

이를 기반으로 python 코드를 작성해 보면 다음과 같으며, counter가 100번째마다 for문을 반복하기에 총 100번 수행됨을 알 수 있기에 해당 부분을 생략하고 100번 반복하는 것으로 하였다.

pumpkin, pie = [ 124, 112, 59, 73, 167, 100, 105, 75, 59, 23, 16, 181, 165, 104, 43, 49, 118, 71, 112, 169, 43, 53 ], 1

for j in range(100):
    for i in range(len(pumpkin)):
        pumpkin[i] ^= pie
        pie = ((pie ^ 0xff) + (i * 10)) & 0xff

print(list(map(chr, pumpkin)))

방법 2

그 결과 위와 같은 복호화 결과를 확인할 수 있으며, 이를 console에서 javascript를 이용하여 10000번 클릭 시켜도 동일한 결과를 확인할 수 있다.

while (counter <= 10000) $('#jack-target').click();

'0x40 Web Hacking' 카테고리의 다른 글

Dreamhack :: devtools-sources  (0) 2022.05.17
Dreamhack :: simple_sqli  (0) 2022.05.17
Dreamhack :: session-basic  (0) 2022.05.17
Dreamhack :: simple-ssti  (0) 2022.05.17

템플릿 구문을 넣어본 결과에 따라 SSTI(Server-Side Template Injection)가 되는지 여부를 판단할 수 있다.

본 문제는 flask로 구동되기 때문에 템플릿 구문으로 {{}}를 사용한다.

{{1*1}}을 넣어 봤을 때,
{{1*1}} 페이지를 찾을 수 없다면 SSTI가 안 되는 것이고,
1 페이지를 찾을 수 없다면 SSTI가 되는 것이다.

본 문제에서는 1 페이지를 찾을 수 없다고 하기에 SSTI에 취약한 것을 알 수 있다.
또한 플래그는 app.secret_key에 저장되어 있기 때문에 어플리케이션 설정 값({{config}})을 통해 확인할 수 있을 것이다.

{{config}} 를 넣어보면, SECRET_KEY 변수에 플래그가 저장되어 있는 것을 확인할 수 있다.

Reference

[1] https://me2nuk.com/SSTI-Vulnerability/
: SSTI에 대한 다양한 정보가 잘 정리되어 있다.

'0x40 Web Hacking' 카테고리의 다른 글

Dreamhack :: devtools-sources  (0) 2022.05.17
Dreamhack :: simple_sqli  (0) 2022.05.17
Dreamhack :: session-basic  (0) 2022.05.17
Dreamhack :: Carve Party  (0) 2022.05.17

+ Recent posts