티스토리 뷰

LOS 포스팅에 앞서 내용이 틀릴 수도 있으며, 해당 부분 지적은 감사히 받겠습니다.

19단계 소스코드이다.

이번 문제는 난이도가 급감한 느낌이다.

하지만 pw에 regex와 like를 필터링 중이다.

regexp_like(stringa, '조건식', c) // stringa에서 조건식에 해당하는 값을 출력함. ※c면 대소문자 구분 i면 무시한다.※

     ㄴex) select regex_like(pw, 'a|b|c') // a 또는 b 또는 c 가 포함된 pw 값을 출력한다.

     ㄴex) select regex_like(pw, 'a$') // a로 끝나는 pw값을 출력한다. ($는 뒤에 붙임)

     ㄴex) select regex_like(pw, '^a') // a로 시작하는 pw값을 시작한다. (^는 앞에 붙임)

     ㄴex) select regex_like(pw, '^[a-f]. g') //a-f로 시작하며 한문자 건너뛰고 다음 문자가 g인 값 출력 ex) dsg

              ㄴ[] 대괄호 안에 문자를 넣으면 or 효과가 적용된다.

     ㄴex) select regex_like(pw, 'a {2}') // a문자가 2번 반복되는 값을 찾는다.

     ㄴex) select regex_like(pw, '{[abc]}\1') // \1은 앞 패턴을 한 번 더 반복한다. ex) aa

참고한 블로그

https://jack-of-all-trades.tistory.com/382

 

오라클 like 구문 업그레이드 regexp_like 샘플예제 (정규표현식 기본 응용)

오라클에서 제공하는 정규표현식 지원 함수 regexp_like 를 이용하면 기존 like 구문에서 할 수 없었거나 아주 어렵게 구현했던 부분들을 아주 쉽게 구현할 수 있습니다. regexp_like 기본 구문(Syntax) 는

jack-of-all-trades.tistory.com

일단 blind sql이 사용 가능한지 확인해본다.

참과 거짓의 값이 다르므로 blind sql 사용이 가능하다. 바로 비밀번호의 길이를 알아낸다.

비밀번호는 12자리이다. 바로 인젝션 하여 pw값을 알아내면 된다.

하지만 pw의 첫 번째 자릿수는 ascii값 1을 넘지 않는다.... 여기서부터 문제의 난이도가 급상승했다.

pw의 첫자리 아스키 값이 0이고 12번째 자리까지 모두 0이었다... 0은 null값인데 비밀번호 자릿수는 12자리이다.

그렇다면 pw는 대체 뭘까... 인터넷의 힘을 조금 빌렸다. 

pw의 첫자리 길이를 추출해보았다.

첫자리 길이가 4다. 이게 뭘까..? 확실한 건 0-9, a-z, A-Z의 값은 아니다.

마찬가지로 2번째 3번째 또한 길이가 4이다. 아마 길이가 4인 문자열 3개로 이루어진 것 같다.

도저히 모르겠어서 인터넷의 힘을 더 많이 빌렸다. 그리고 이건.. 내 수준으로 계속 붙잡고 있는다고 해결되는 문제가 아니었다...

일단 문제를 풀기전에 조금 더 자세히 알아둬야 할 게 있다.

 

ascii()    // a의 ascii 값을 출력해주며 2byte 이상 값은 작동하지 않는다

ord()     // 하나의 문자를 인자로 받고 해당 문자의 유니코드 정수를 반환한다. ※2byte※ 이상에서도 작동한다.

chr()     //하나의 정수를 인자로 받고 해당 정수에 해당하는 유니코드 문자를 반환한다.

ord()와 chr() 인자의 유효 범위는 0~1,114,111 (16진수 0x10 FFFF 까지다.)이며 이는 유니코드 범위다.

 

length()        // 바이트 수를 읽어온다.

char_length() // 문자, 칼럼의 문자 개수를 출력한다.

 

나는 문제를 이렇게 풀었다.

ord()가 사용해서 유니코드 값을 구하고 chr()로 값을 변환하는 코드를 만들었다.

문제는 해결했다.

하지만 이 방법은 

시행착오

1. ord() ascii()의 차이점을 알게 되었다. ascii < ord byte 수

2. 유니코드의 정수 범위는 0~1,114,111이다.

3. length(pw)의 값은 12이고 ord(length(pw))의 값은 5이고 substr(pw,1,1)의 값은 4다. 너무 복잡하다.......

 

인터넷에서 정말 놀라운 풀이를 하나 찾았다.

https://dorahee.tistory.com/132

 

los - xavis

문제 소스코드 이때까지 풀었던 los 문제 중 가장 까다롭고 짜증 나는 문제이다. 1. 별다른 필터링은 존재 하지 않다. regex, like를 필터링하고 있는대 일단 저 2개는 안 쓸 거니까 무시 일단 admin pw

dorahee.tistory.com

문제풀이를 보자마자 기본기의 중요성을 다시 한번 강하게 느꼈다..

sql에서의 사용자 정의 변수를 사용하는 방법인데

select @변수:=pw from table_name 쿼리를 만들었을 때

변수에 table_name 테이블에 있는 pw 칼럼을 변수에 넣는 쿼리이다.

 

하지만 변수 안에 값을 넣는 건 false를 의미한다고 한다.

하지만 결괏값이 출력된다고 함...

이후 union select를 통해 변수 값을 출력해 낼 수 있다고 한다.

ex)? pw='||(select+@a:=pw+where+id='admin') union select @a--+-

얼마나 황당하고 놀라웠는지.. 고수의 길은 멀고 험하구나.......

추후에 hex로 푸는 방법도 시도해봐야겠다.

hex로는 못 풀어서 굉장히 답답하다.

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++hex 방식으로 풀어냈다.

일단 문제는 굉장히 간단했고 덕분에 파이썬 배열에 대해서 다시 배웠다.

일단 blind injection에서는 무조건 인젝터로 돌릴 쿼리를 웹페이지에 수동적으로 쿼리가 잘 작동하는지 확인해야 한다..

하지만 정상 작동하는지 확인하고 파이썬에서 새로 작성한 쿼리도 제대로 되는지 확인해야 한다.

나는 쿼리를 파이썬으로 옮길 때 실수를 계속한다.. 당연히 인젝터가 제대로 작동할 리 없고, 또 오류를 찾기 위해 오랜 시간을 투자해야 한다. 

일단 문제가 해결되지 않았던 이유이다.

두 쿼리의 차이점에서 인젝터의 오류를 파악하는데 3시간+@가 걸렸다..

바로 substr()= 와 substr()='' 차이이다.

substr()로 추출된 문자는 싱글쿼터 or 더블 쿼터로 감싸주어야 숫자가 아닌 문자가 왔을 때 정상적으로 작동한다.

24자리의 hex 값이 나왔다.

첫번째 비밀번호의 hex 자릿수는 8자리이고 두세 번째도 모두 같다.

따라서 0000c6b00000c6550000ad73를 8자리씩 끊으면 각 자리의 비밀번호가 나온다. 바로 십진수로 바꾼다.

0000c6b0    ->50864

0000c655    ->50773

0000ad73    ->44403

익숙한 숫자다.

우왕굳.

https://ls-altr.tistory.com/11

 

숫자 진법 계산기(10진수/16진수/2진수/문자로 변환)

top -p pid 등으로 확인한 pid에 해당하는 각 프로세스별 쓰레드 덤프 사용시, nid에 매치하기 위해서는 10진수 16진수 변환이 필요하다. 다음의 계산기를 사용하면 10 진수를 16진수 변환이 가능하다.

ls-altr.tistory.com

굳...

시행착오

1. 파이썬에서 hex비교를 위해 배열을 사용할 때 a="01234566789 abcdef"를 선언하고 hex_l=list(a)로 넣어준 뒤

hex_l [j]로 추출하여 사용한다.

2. substr()로 문자를 추출하고 비교할 문자는 반드시 싱글 쿼터 or 더블 쿼터를 씌워야 한다.

   그러지 않을 경우 숫자는 제대로 비교가 되지만 문자열은 0으로 비교되어서 제대로 작동하지 않는다.

댓글