[그림 01] level18 시작


level18에서는 SQL Injection이라고 합니다.

먼저 phps를 통해 php문을 확인해보도록 합시다.


[그림 02] php문


php에서는 union, select, from, 0x, (띄어쓰기), /, \(, \), \t, \|, &에 대한 필터링이 걸려 있는 것을 볼 수 있습니다.

그럼 우리는 어떤 것이 허용되었는지 확인해야할 필요가 있습니다.


처음 0 or no=1으로 or나 and를 확인해보기 위해 %20대신 %0a를 사용하였습니다.

0%0aor%0ano=1을 GET 으로 넘겨주니 or와 %0a가 먹히는 것으로 보입니다.


이제 %0a와 or를 활용하여 admin을 얻어와야 하는데...


[그림 02]에서 테이블에 있는 admin을 받아와야 하기 때문에 반환값을 조정하기 위해 limit을 이용하여 하는 방법이 가장 옳다고 생각됩니다.

(중간에 저도 깨달음을 얻었습니다.. 시간이 너무 소요가 되었어요..)


즉, q[0]에 반환되는 값을 admin으로 받으려면 Table 내에 있는 admin을 가져와야 한다는 의미입니다.

limit 0,1이 guest일 것이기에, 우리는 limit 1,1로 admin이 있는지 확인해봅시다.


[그림 03] 적중!


다행히 limit 1,1의 위치에 admin이 있었습니다.


'WARGAMES > webhacking.kr - old' 카테고리의 다른 글

Webhacking.kr_No.25(150) - old  (0) 2016.12.08
Webhacking.kr_No.24(100) - old  (0) 2016.06.28
Webhacking.kr_No.23(200) - old  (0) 2016.06.28
Webhacking.kr_No.20(200) - old  (0) 2016.06.28
Webhacking.kr_No.17(100) - old  (0) 2016.06.28
Webhacking.kr_No.16(100) - old  (0) 2016.06.28
Webhacking.kr_No.15(50) - old  (0) 2016.06.28
Webhacking.kr_No.14(100) - old  (0) 2016.06.28

[그림 01] level17 시작


개발자 도구를 봐야 뭘 알 수 있겠네요.

먼저 F12를 꾹 눌러줍시다.


[그림 02] 자바스크립트로 짜여진 코드


위의 소스를 해석해보면 unlock에는 숫자계산을 하도록 하게 하고, 만약 unlock에 들어간 값을 check에 넣게 되면,

Password를 뱉어내도록 하는 함수라는 걸 알 수 있습니다.


Password는 unlock의 0.1을 곱한 값이라고 합니다.

개발자 콘솔에서 unlock을 확인해보니 '9997809307'이라고 합니다.


[그림 03] 결과


패스워드는 999780930.7입니다.

이를 Auth에서 인증하면 답이 나오게 됩니다.






'WARGAMES > webhacking.kr - old' 카테고리의 다른 글

Webhacking.kr_No.24(100) - old  (0) 2016.06.28
Webhacking.kr_No.23(200) - old  (0) 2016.06.28
Webhacking.kr_No.20(200) - old  (0) 2016.06.28
Webhacking.kr_No.18(100) - old  (0) 2016.06.28
Webhacking.kr_No.16(100) - old  (0) 2016.06.28
Webhacking.kr_No.15(50) - old  (0) 2016.06.28
Webhacking.kr_No.14(100) - old  (0) 2016.06.28
Webhacking.kr_No.12(250) - old  (0) 2016.06.28

[그림 01] level16 시작


level16을 들어가면 [그림 01]처럼 별 몇개만 보여줍니다.

개발자 도구를 통해 소스를 확인해봅시다.


[그림 02] 소스 함수


mv함수와 kk함수가 있는데, 함수들의 설명은 다음과 같습니다.

mv(cd) 함수는 cd에 따라 기능이 결정되는데, cd가 124일 때 password를 보여주는 page로 넘어가게 됩니다.

kk(x,y) 함수는 랜덤 색깔로 별을 그리는 함수입니다.


우리는 콘솔 창에서 mv(124)를 입력하고 [그림 03]처럼 답을 얻어봅시다.

[그림 03] 패스워드



'WARGAMES > webhacking.kr - old' 카테고리의 다른 글

Webhacking.kr_No.23(200) - old  (0) 2016.06.28
Webhacking.kr_No.20(200) - old  (0) 2016.06.28
Webhacking.kr_No.18(100) - old  (0) 2016.06.28
Webhacking.kr_No.17(100) - old  (0) 2016.06.28
Webhacking.kr_No.15(50) - old  (0) 2016.06.28
Webhacking.kr_No.14(100) - old  (0) 2016.06.28
Webhacking.kr_No.12(250) - old  (0) 2016.06.28
Webhacking.kr_No.10(250) - old  (0) 2016.06.28

[그림 01] level15 시작


시작하자마자 Access_Denied를 뱉어냅니다.

우리는 Fiddler로 캡처를 해보도록 합시다.

참고로 Fiddler는 Internet Explorer 혹은 Edge가 잘 캡처됩니다.

[그림 02] 얼레.. 해결됐당


document.write("password is off_script")라고 패스워드가 적혀 있네요.


'WARGAMES > webhacking.kr - old' 카테고리의 다른 글

Webhacking.kr_No.20(200) - old  (0) 2016.06.28
Webhacking.kr_No.18(100) - old  (0) 2016.06.28
Webhacking.kr_No.17(100) - old  (0) 2016.06.28
Webhacking.kr_No.16(100) - old  (0) 2016.06.28
Webhacking.kr_No.14(100) - old  (0) 2016.06.28
Webhacking.kr_No.12(250) - old  (0) 2016.06.28
Webhacking.kr_No.10(250) - old  (0) 2016.06.28
Webhacking.kr_No.06(100) - old  (0) 2016.06.28

[그림 01] level14 시작화면


level14에 들어가면 다짜고짜 아무거나 입력해서 check하라고 합니다.

우리는 사뿐히 admin을 입력하고 check를 시도한 후 wrong!!이라는 퇴짜를 맞아봅니다.

먼저 페이지 소스를 확인해야겠습니다.


[그림 02] 페이지 소스의 script


페이지에서 function ch()라는 함수가 스크립트로 정의가 되어 있는 것을 볼 수 있습니다.

document.URL 즉, 지금 입력된 URL을 ul에 저장한다는 의미이고,

ul.indexOf(".kr")은 .kr이 있는 위치를 숫자로 저장한다는 의미입니다.

그리고 이 위치(숫자)에 30을 곱한 값을 check에 넣게 되면 비밀번호를 뱉어낸다는 것을 알 수 있습니다.

alert에서도 (ul의 위치 * 30)*(ul의 위치 * 30)를 Password로 주는 것을 알 수 있습니다.

해보지 않고서도 이러한 공식을 얻을 수 있습니다.


(document.URL.indexOf(".kr") * 30)^2 == password

[그림 03] 콘솔을 이용한 풀이


콘솔을 이용하여 풀이를 진행하면 [그림 03]과 같이 진행할 수 있습니다.

510을 check에 넣고 submit하면 [그림 04]와 같은 값을 얻을 수 있습니다.


[그림 04] Password


이제 이 값을 Auth에서 인증하면 풀리게 됩니다.


'WARGAMES > webhacking.kr - old' 카테고리의 다른 글

Webhacking.kr_No.18(100) - old  (0) 2016.06.28
Webhacking.kr_No.17(100) - old  (0) 2016.06.28
Webhacking.kr_No.16(100) - old  (0) 2016.06.28
Webhacking.kr_No.15(50) - old  (0) 2016.06.28
Webhacking.kr_No.12(250) - old  (0) 2016.06.28
Webhacking.kr_No.10(250) - old  (0) 2016.06.28
Webhacking.kr_No.06(100) - old  (0) 2016.06.28
Webhacking.kr_No.05(300) - old  (0) 2016.06.26

[그림 01] level12 시작


단도직입적으로 javascript 문제라는 것을 말해줍니다.


[그림 02] javascript 난독화


자바 스크립트에서 [그림 02]와 같이 난독화가 되어 있는 모습을 볼 수 있습니다.

그렇다면 우리는 이를 다시 문자로 변환하여 어떤 script문인지 파악을 해야 할 필요가 있습니다.

Python으로 코드를 작성해보도록 합시다.

(Python 버전 2.7.12)

Worktime = """118,97,114,32,101,110,99,111,61,39,39,59,13,10,118,97,114,32,101,110,99,111,50,61,49,50,54,59,13,10,118,97,114,32,101,110,99,111,51,61,51,51,59,13,10,118,97,114,32,99,107,61,100,111,99,117,109,101,110,116,46,85,82,76,46,115,117,98,115,116,114,40,100,111,99,117,109,101,110,116,46,85,82,76,46,105,110,100,101,120,79,102,40,39,61,39,41,41,59,13,10,32,13,10,32,13,10,102,111,114,40,105,61,49,59,105,60,49,50,50,59,105,43,43,41,13,10,123,13,10,101,110,99,111,61,101,110,99,111,43,83,116,114,105,110,103,46,102,114,111,109,67,104,97,114,67,111,100,101,40,105,44,48,41,59,13,10,125,13,10,32,13,10,102,117,110,99,116,105,111,110,32,101,110,99,111,95,40,120,41,13,10,123,13,10,114,101,116,117,114,110,32,101,110,99,111,46,99,104,97,114,67,111,100,101,65,116,40,120,41,59,13,10,125,13,10,32,13,10,105,102,40,99,107,61,61,34,61,34,43,83,116,114,105,110,103,46,102,114,111,109,67,104,97,114,67,111,100,101,40,101,110,99,111,95,40,50,52,48,41,41,43,83,116,114,105,110,103,46,102,114,111,109,67,104,97,114,67,111,100,101,40,101,110,99,111,95,40,50,50,48,41,41,43,83,116,114,105,110,103,46,102,114,111,109,67,104,97,114,67,111,100,101,40,101,110,99,111,95,40,50,51,50,41,41,43,83,116,114,105,110,103,46,102,114,111,109,67,104,97,114,67,111,100,101,40,101,110,99,111,95,40,49,57,50,41,41,43,83,116,114,105,110,103,46,102,114,111,109,67,104,97,114,67,111,100,101,40,101,110,99,111,95,40,50,50,54,41,41,43,83,116,114,105,110,103,46,102,114,111,109,67,104,97,114,67,111,100,101,40,101,110,99,111,95,40,50,48,48,41,41,43,83,116,114,105,110,103,46,102,114,111,109,67,104,97,114,67,111,100,101,40,101,110,99,111,95,40,50,48,52,41,41,43,83,116,114,105,110,103,46,102,114,111,109,67,104,97,114,67,111,100,101,40,101,110,99,111,95,40,50,50,50,45,50,41,41,43,83,116,114,105,110,103,46,102,114,111,109,67,104,97,114,67,111,100,101,40,101,110,99,111,95,40,49,57,56,41,41,43,34,126,126,126,126,126,126,34,43,83,116,114,105,110,103,46,102,114,111,109,67,104,97,114,67,111,100,101,40,101,110,99,111,50,41,43,83,116,114,105,110,103,46,102,114,111,109,67,104,97,114,67,111,100,101,40,101,110,99,111,51,41,41,13,10,123,13,10,97,108,101,114,116,40,34,80,97,115,115,119,111,114,100,32,105,115,32,34,43,99,107,46,114,101,112,108,97,99,101,40,34,61,34,44,34,34,41,41,59,13,10,125,13,10"""
WorkList = list()
Worktime = Worktime.split(',')

for i in range(len(Worktime)):
	WorkList += chr(int(Worktime[i]))

print "".join(WorkList)

실행 결과는 [그림 03]과 같습니다.


[그림 03] 파이썬 소스 결과


위의 소스를 차근차근 해석해봅시다.

enco는 초기화 변수

enco2는 126이 저장

enco3는 33을 저장

ck는 document.URL.substr(document.URL.indexOf('='));을 저장함


첫번째 for문 : CharCode를 (1,0)~(121,0)Rkwl enco에 저장합니다.

enco_함수 : enco에 저장된 CharCode를 반환해주는 소스입니다.


if문에 enco와 enco_함수를 통해 만들어진 문자열이 ck와 같다면 패스워드를 뱉어내는 구조입니다.


if문 안의 String을 개발자 도구에서 붙여넣게 되면 [그림 04]와 같은 문자를 뱉어내게 됩니다.


[그림 04] if문 결과


ck에는 현재 아무런 값도 붙어 있지 않았기 때문에, 맨 뒤에 =youaregod~~~~~~~!를 넣게 되면 답을 얻을 수 있게 된다.


[그림 05] 해답 구하기


'WARGAMES > webhacking.kr - old' 카테고리의 다른 글

Webhacking.kr_No.17(100) - old  (0) 2016.06.28
Webhacking.kr_No.16(100) - old  (0) 2016.06.28
Webhacking.kr_No.15(50) - old  (0) 2016.06.28
Webhacking.kr_No.14(100) - old  (0) 2016.06.28
Webhacking.kr_No.10(250) - old  (0) 2016.06.28
Webhacking.kr_No.06(100) - old  (0) 2016.06.28
Webhacking.kr_No.05(300) - old  (0) 2016.06.26
Webhacking.kr_No.04(150) - old  (0) 2016.06.22

[그림 01] level10의 시작화면


level10을 들어가면 [그림 01]과 같이 시작화면에는 몇 가지 문자와 O로 보이는 문자가 있습니다.

'O'를 클릭해보면 한 칸씩 옆으로 이동하는 것을 확인할 수 있는데, 이를 F12(개발자 도구)로 확인해보면,

[그림 02]와 같이 확인할 수 있습니다.


[그림 02] hackme 영역


hackme 영역은 id="hackme" style="......"로 이루어진 영역인데, O를 클릭할 때마다 this.style.posLeft가 한 칸씩 옆으로 이동하는 것을 알 수 있습니다.

그렇다면 posLeft가 800이 될 때 this.href='?go=' 인 것으로 보아 아마 posLeft를 800까지 이동시켜야 하는 것을 의미하는가 봅니다.

우리는 800번의 클릭을 하는 것보다 값을 조정해보도록 합시다.


[그림 03] posLeft를 799까지 옮긴 모습


F12(개발자 도구)에서 hackme.style.posLeft = 799로 하게 되면 'O'는 799 좌표로 이동하게 됩니다.

800으로 이동시켰지만 href가 동작하지 않는 것으로 보아 799번째에서 클릭하면 동작하는 방식인 것 같습니다.

799로 옮긴 후 O를 클릭하면 링크가 클릭되며, Congratulation이 뜨게 됩니다.


<참고>


this.style.posLeft가 움직이는 것은 id가 hackme인 곳을 this로 가리키게 됩니다.

id="hackme" 안에서 style의 값을 this.style.posLeft라는 것은 hackme.style.posLeft와 동일하다는 것을 의미합니다.


'WARGAMES > webhacking.kr - old' 카테고리의 다른 글

Webhacking.kr_No.16(100) - old  (0) 2016.06.28
Webhacking.kr_No.15(50) - old  (0) 2016.06.28
Webhacking.kr_No.14(100) - old  (0) 2016.06.28
Webhacking.kr_No.12(250) - old  (0) 2016.06.28
Webhacking.kr_No.06(100) - old  (0) 2016.06.28
Webhacking.kr_No.05(300) - old  (0) 2016.06.26
Webhacking.kr_No.04(150) - old  (0) 2016.06.22
Webhacking.kr_No.03(350) - old  (0) 2016.06.16

[그림 01] Challenge 06번 시작 화면


ID와 PW가 보입니다. index.phps는 링크입니다.

index.phps 즉, index.php의 소스를 보여주는 곳입니다. 들어가봅시다.


소스를 들어가면 아래와 같이 나옵니다.▼

[그림 02] PHP소스 요약


소스를 간단히 해석해보면

01. id, pw에 있는 값을 20번 base64로 인코딩합니다.

02. 1,2,3,4,5,6,7,8을 각각 !,@,$,^,&,*,(,)로 바꿉니다.

03. 쿠키에 user, pasword를 추가하고 20번 인코딩 된 값을 각각 입력합니다.

04. 만약 user, password라는 쿠키값에 있는 !,@,$,^,&,*,(,)을 1,2,3,4,5,6,7,8로 replace하고 이를 20번 디코딩한 쿠키값(user, password)이 모두 admin이면 solve()라는 함수가 실행됩니다.


즉, user와 password 쿠키값에 admin을 20번 인코딩하고 replace까지 한 값을 입력하면 됩니다.


[그림 03] Chrome 브라우저 콘솔에서 user, password를 입력



참고 소스 (Python) - admin 문자열을 20번 인코딩 및 replace함 :

import base64

string_admin='admin'

for i in range(0,20):
       string_admin = base64.standard_b64encode(string_admin)

string_admin = string_admin.replace('1','!')
string_admin = string_admin.replace('2','@')
string_admin = string_admin.replace('3','$')
string_admin = string_admin.replace('4','^')
string_admin = string_admin.replace('5','&')
string_admin = string_admin.replace('6','*')
string_admin = string_admin.replace('7','(')
string_admin = string_admin.replace('8',')')

f = open('string_admin.txt', 'w')

print >> f, 'Set Cookie user value and password value : '
print >> f, string_admin


'WARGAMES > webhacking.kr - old' 카테고리의 다른 글

Webhacking.kr_No.15(50) - old  (0) 2016.06.28
Webhacking.kr_No.14(100) - old  (0) 2016.06.28
Webhacking.kr_No.12(250) - old  (0) 2016.06.28
Webhacking.kr_No.10(250) - old  (0) 2016.06.28
Webhacking.kr_No.05(300) - old  (0) 2016.06.26
Webhacking.kr_No.04(150) - old  (0) 2016.06.22
Webhacking.kr_No.03(350) - old  (0) 2016.06.16
Webhacking.kr_No.01(200) - old  (0) 2016.06.16


[그림 01] 시작 화면


[그림 01]과 같은 화면을 시작 화면으로 볼 수 있을 것입니다.

[그림 02]는 login, [그림 03]은 join을 눌렀을 때의 상태를 보여줍니다.

[그림 02] join을 눌렀을 때의 화면

[그림 03] join을 눌렀을 때의 화면


[그림 03]처럼 join을 눌렀을 때의 화면이 나오는 이유는 Javascript를 이용하여 그냥 alert('Access_Denied')로 돼 있어서 입니다.

즉, link가 따로 없습니다.

그렇다면 다른 방향으로 접근해야 합니다.

이 사이트에서 각 문제는 하위 디렉토리로 구성되는 것을 익히 아실거라 생각합니다. [그림 04]를 참고해주십시오.

[그림 04] 디렉토리 구성을 알려주는 주소


[Directory, web]->[Directory, web-05]->[Directory, mem]->[File, login.php]입니다.

web이라는 디렉토리 하위의 web-05 하위의 mem 하위의 login.php라는 PHP파일을 브라우저를 통해 보여주는 형식입니다.

그럼 우리는 login을 들어가면 login.php이니, join은 혹시 join.php가 아닐까 하는 느낌을 받을 수 있지 않을까 합니다.


이제 login.php를 바꿔 join.php로 들어가봅니다.


join.php로 들어가면 다음과 같이 난독화가 되어있는 것을 알 수 있습니다.


Challenge5


이와 같이 난독화 되어 있는 코드를 python 코드로 간단하게 작성하여 디코드해보았습니다.

아래와 같이 난독화가 풀어지는 것을 확인할 수 있습니다.


l1'b'1'b'1'b'1'b'1'b'1'b'1'b'1'b'1'b'1l='o'+'l'+'d'+'z'+'o'+'m'+'b'+'i'+'e'

l08l='d'+'o'+'c'+'u'+'m'+'e'+'n'+'t'+.+'c'+'o'+'o'+'k'+'i'+'e'
if(eval(l08l).indexOf(l1'b'1'b'1'b'1'b'1'b'1'b'1'b'1'b'1'b'1l)==-1)
    {
        bye;
    }
if(eval('d'+'o'+'c'+'u'+'m'+'e'+'n'+'t'+.+'U'+'R'+'L').indexOf('m'+'o'+'d'+'e'+'='+1)==-1)
    {
    alert('access_denied')
    history.go(-1);
    }
else
    {
    document.write('Join

'); document.write('.

.

.

.

.

'); document.write('

'); document.write(''); document.write(''); document.write('
id
pass
'); }

이 코드를 보니 document.write로 되어 있는 부분은 화면에 다른 소스를 입력하기 위한 창으로 볼 수 있고, 그 위에는 그 화면으로 접근하기 위한 방법으로 알 수 있습니다.

대충 요약하면 조건 두 가지가 나옵니다.▼


조건 1. 쿠키에 oldzombie 라는 이 있어야 합니다.

조건 2. URL에 ?mode=1이 있어야 합니다.


[그림 05] 완성된 화면


id에 admin이라고 입력하면 'admin is already exist'라는 문자가 뜨고, 나머지는 'Done! 뭐시기 뭐시기'가 뜹니다.

그런데, admin 이외의 다른 계정을 계속 생성해도 Done이 되는 걸 보니 DB에 INSERT가 허용되는 것으로 확인할 수 있습니다.


admin을 어떻게 덮어쓰기 위해서는 DataBase에서는 삭제되고, 쿼리는 admin이 아니게 전송할 수 있는 문자열이 필요합니다.


SQL에서는 trim()이라는 함수가 존재합니다. 구문에서 띄어쓰기를 삭제하는 함수입니다.

예를 들면 id 컬럼에 'admin   1', 'admin        1'이라는 값을 입력하여 차례대로 생성해보면,

1. admin1이 생성되었습니다.

2. admin1이 이미 있습니다.(중복 에러)

라고 뜹니다.


띄어쓰기는 삭제되는 것을 볼 수 있습니다.


id에 'admin '을 입력하고 원하는 비밀번호를 입력하면 Done이 뜨고, login.php로 들어가 로그인을 하게 되면 성공입니다.




참고 소스(Python) - 난독화를 대충이라도 디코딩 및 프린트 하기:

string_a = """

lIllIllIllIllIllIllIllIllIllIl=lllllllllllllll+llllllllllll+llll+llllllllllllllllllllllllll+lllllllllllllll+lllllllllllll+ll+lllllllll+lllll

lIIIIIIIIIIIIIIIIIIl=llll+lllllllllllllll+lll+lllllllllllllllllllll+lllllllllllll+lllll+llllllllllllll+llllllllllllllllllll+li+lll+lllllllllllllll+lllllllllllllll+lllllllllll+lllllllll+lllll
if(eval(lIIIIIIIIIIIIIIIIIIl).indexOf(lIllIllIllIllIllIllIllIllIllIl)==-1)
    {
        bye;
    }
if(eval(llll+lllllllllllllll+lll+lllllllllllllllllllll+lllllllllllll+lllll+llllllllllllll+llllllllllllllllllll+li+'U'+'R'+'L').indexOf(lllllllllllll+lllllllllllllll+llll+lllll+'='+I)==-1)
    {
    alert('access_denied')
    history.go(-1);
    }
else
    {
    document.write('Join

'); document.write('.

.

.

.

.

'); document.write('

'); document.write(''); document.write(''); document.write('
id
pass
'); }""" for i in range(26,1,-1): string_a = string_a.replace('l'*i,"'"+chr(ord('z')-(26-i))+"'") for i in range(10,0,-1): if i == 10: string_a = string_a.replace('I'*i,'0') else: string_a = string_a.replace('I'*i,str(i)) string_a = string_a.replace('li', '.') string_a = string_a.replace('ii', '<') string_a = string_a.replace('iii', '>') print string_a


'WARGAMES > webhacking.kr - old' 카테고리의 다른 글

Webhacking.kr_No.15(50) - old  (0) 2016.06.28
Webhacking.kr_No.14(100) - old  (0) 2016.06.28
Webhacking.kr_No.12(250) - old  (0) 2016.06.28
Webhacking.kr_No.10(250) - old  (0) 2016.06.28
Webhacking.kr_No.06(100) - old  (0) 2016.06.28
Webhacking.kr_No.04(150) - old  (0) 2016.06.22
Webhacking.kr_No.03(350) - old  (0) 2016.06.16
Webhacking.kr_No.01(200) - old  (0) 2016.06.16

+ Recent posts