광팔이 보안이야기

[xcz.kr] 25번 XCZ Captcha! 본문

Wargame/xcz.kr

[xcz.kr] 25번 XCZ Captcha!

광팔2 2021. 1. 25. 21:00
반응형

문제

일단 힌트를 보면 1번은 최소공배수 / 2번은 시간제한이 15초이다.

 

사이트를 다시 방문하면 숫자가 바뀌는 것을 볼 수 있다.(15초 안에 이미지에 대한 답을 적어야 하는 것 같다.)

 

이미지를 다운로드하여보면 prob25_img.php 파일을 다운로드할 수 있다.

 

이제 코드를 짜야할 것 같은데 생각해보면 15초 안에 저렇게 긴 수를 적는다는 것은 불가능하다.

 

이미지의 위치를 잡고 두 개의 긴 수를 가져와 최소공배수를 구해야 할 것 같다.

 

코드를 짜서 결과물을 플레그를 얻을 수 있었다.

 

이제 코드를 간단히 설명하자면...

 

1. selenium을 이용해 크롬으로 xcz 페이지를 열고 로그인까지 한다.

2. PIL, cv2를 이용해 이미지를 저장, 회색 변경 등을 한다.

3. pytesseract를 이용해 OCR을 활용하여 이미지의 글자를 가져온다.

4. 값을 계산해 정답을 입력 후 플레그를 얻는다.

 

여러 가지가 많다 보니 코드에 대한 설명을 자세히 적어보자 다음에 볼 때 다시 기억하기 위해!!

 

이제 코드를 자세히 설명하자면...

 

import requests
from selenium import webdriver
from fractions import gcd
from PIL import Image

import cv2
import pytesseract

selenium - 크롬을 새롭게 열어 로그인

gcd - 최소 공배수 계산

PIL - 이미지 열기

cv2 - 이미지 회색 변경, 크기에 맞춰 따로 이미지 저장

pytesseract - OCR(이미지를 문자로)

 

php_url =  'http://xcz.kr/START/prob/prob_files/prob25_img.php'
xcz = 'http://xcz.kr/START/login.php'
driver = webdriver.Chrome(executable_path='(driver) chromedriver.exe')

driver.get(xcz)

1. 사용 주소들을 가져온다.

2. 로그인 페이지를 열어준다.

# ID를 입력한다
id=driver.find_element_by_name('id')
id.send_keys('개인 ID')
 
# PWD를 입력 한다
id=driver.find_element_by_name('pw')
id.send_keys('개인 PW')

1. name 태그의 id와 pw를 자동으로 넣어준다.(자동 클릭까지 하려고 했는데 오류 때문에 실패했다.)

def lcm(x, y):
    return x*y // gcd(x,y)

1. gcd를 이용하여 최소공배수 함수 lcm을 만든다.

driver.get(php_url)

screenshot_name = "my_screenshot_name.png"
driver.save_screenshot(screenshot_name)

1. 이미지가 담겨있는 php_url을 페이지를 가져오며 png 파일로 저장을 해준다.

img = cv2.imread('my_screenshot_name.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

1. OCR이 좀 더 자세히 문자를 알아볼 수 있게 회색으로 바꿔준다.(처음에 없이 했었는데 문자 인식을 잘 못했다.)

result = gray[381:498, 268:822]
cv2.imwrite('my_screenshot_name1.png',result)

1. 빈 공간을 다 지우며, 숫자들만 자세히 보이게 하며 회색으로 바꾼 이미지를 저장했다.(없이 했을 때, 인식을 잘하지 못했다.)

img_gray = Image.open("my_screenshot_name1.png")
text = pytesseract.image_to_string(img_gray)
print(text)

1. 회색으로 바꾼 이미지를 불러와 문자를 OCR을 이용해 문자를 뽑아냈다.(두 개의 큰 수)

data1 = text[:30]
data2 = text[31:]

print(data1)
print(data2)

lcm_data = lcm(int(data1),int(data2))
print(lcm_data)

1. data1에 앞 숫자를 저장한다.

2. data2에 뒤 숫자를 저장한다.

3. lcm 함수를 이용해 최소공배수를 구해줬다.

url = 'http://xcz.kr/START/prob/prob_files/prob25_ok.php?lcm=' + str(lcm_data)
driver.get(url)

 

1. 정답 페이지를 열며 플레그를 얻을 수 있다.

 

플레그 값 : Timepassesquickly..

반응형

'Wargame > xcz.kr' 카테고리의 다른 글

[xcz.kr] 27번 XCZ Company Hacking Incident  (0) 2021.01.26
[xcz.kr] 24번 Memoryyyyy Dumpppppp  (0) 2021.01.26
[xcz.kr] 23번 Zero & One  (0) 2021.01.21
[xcz.kr] 22번 Who's Notebook?  (0) 2021.01.21
[xcz.kr] 21번 PHP Obfuscation Crack  (0) 2021.01.20
Comments