728x90
반응형

해당 문제는 netcat으로 접속하여 제공되는 S/W를 이용하는 방식의 챌린지이며,

힌트로는 smt slover가 제공된다

 

SMT(Satisfiability Modulo Theories) : 술어논리 기반의 논리식(방정식을 포함하는 개념)

SMT solver : SMT를 풀어 정답을 도출하는 S/W

중근(Multiple root) : 2차 이상의 방정식에서, 2개 이상의 같은 값인, 중복되는 근(해)

 

netcat을 이용해 해당 주소 및 포트로 접속하면 다음과 같은 화면이 뜬다.

제한시간은 500초이고 300문제를 풀게되면 쉘을 획득할 수 있게 된다, 코딩을 이용해 문제를 풀어보자.

 

SMT solver 파이썬 모듈인 sympy를 사용할 것이며, 해당 모듈은 중근 존재 여부를 확인해주지 않으므로 코딩 중 별도 반영이 필요하다.

 

먼저 pip install sympy 명령어를 이용해 설치 후, 코드를 작성해보자.

from sympy import Symbol, solve
import telnetlib
import socket

def main():

  HOST='192.168.83.129'
  PORT=8231 
  s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  s.connect((HOST,PORT))
  s.settimeout(5)

  x=Symbol('x')
  equation = ""
  rData = ""
  while True:
    try:
      rData=s.recv(1024).decode()
    except socket.timeout:
      t = telnetlib.Telnet()
      t.sock = s
      t.interact()
      s.close()      
      return 0;
      
      
    print(rData)
    if ("No. " in rData):
    
      # x=Symbol('x')
      # 1. (x-1)(x-2)(x-2)
      # 2. (x-1)(x^2 - 4x + 4)
      # 3. x^3 - 5x^2 + 8x - 4
      # equation = "x**3 - 5*x**2 + 8*x - 4"
      
      rData = "".join(rData.split(" ")[2:-4])
      rData = rData.replace("x", "*x")
      equation = rData.replace("^", "**")
      print("[Parsed][ " + equation + " ]")
      
      ansArr = solve(equation)
      lenArr = len(ansArr)
      rst = ""
      
      if (lenArr == 1):
        rst = repr(ansArr[0]) + ", " + repr(ansArr[0]) + ", " + repr(ansArr[0]) + "\n"
        s.send(rst.encode())
        print("[Sended] " + rst)
        
      elif (lenArr == 2):
        prifix = int(equation.split("*x**3")[0])
        emt1 = ansArr[0]
        emt2 = ansArr[1]
        eCase1 = prifix*(x -1*emt1)**2 * (x -1*emt2)
        eCase2 = prifix*(x -1*emt2)**2 * (x -1*emt1)
        # print(eCase1)
        # print(eCase2)
        if (eCase1.equals(equation)):
          rst = repr(emt1) + ", " + repr(emt1) + ", " + repr(emt2) + "\n"
          s.send(rst.encode())
          print("[Sended] " + rst)
        elif (eCase2.equals(equation)):
          rst = repr(emt1) + ", " + repr(emt2) + ", " + repr(emt2) + "\n"
          s.send(rst.encode())
          print("[Sended] " + rst)
        else:
          rst = repr(emt1) + ", " + repr(emt2) + "\n"
          s.send(rst.encode())
          print("[Sended] " + rst)
      elif (lenArr == 3):
        rst = repr(ansArr[0]) + ", " + repr(ansArr[1]) + ", " + repr(ansArr[2]) + "\n"
        s.send(rst.encode())
        print("[Sended] " + rst)
  
if __name__ == "__main__":
  main()

300문제를 모두 풀게되면, 쉘을 획득할 수 있게 된다.

728x90
반응형

'CTF & WarGame > DIMICTF' 카테고리의 다른 글

[DIMICTF] DIMICTF와 CTF를 위한 환경설정  (0) 2020.04.16

+ Recent posts