Security || AI

[picoCTF2018 Writeup] script me -Points: 500 본문

CTF(해킹대회)/picoCTF 2018

[picoCTF2018 Writeup] script me -Points: 500

보안&인공지능 2018. 10. 19. 23:53



문제는 script me 라는 제목으로 nc에 접속해보면 아래의 그림과 같이 짜야할 알고리즘과 그 알고리즘에 대한 규칙이 나온다. 여기에 나온 모든 문제를 풀면 성공이다.


이제 이 문제를 풀기위해 파이썬으로 스크립트를 짜보았다.

알고리즘을 설명하자면 식 A + B + C = ??? 이러한 식의 문제라면 먼저 A, B, C로 이루어진 리스트를 만든다.

그 다음 pop(0)을 통해 리스트의 인덱스 0, 1번을 리스트에서 꺼내면서 각각 left, right에 넣는다.

그 다음 answer함수를 실행시키면 먼저 왼쪽과 오른쪽 중 문제의 RULE에 적힌 내용대로 하기 위해 combine을 할지 absorb-left 또는 absorb-right를 할지 검사한다.

()안에 ()가 중첩된것 ex. ((()))  이게 많으면 흡수를 하는 것이고 적으면 흡수되는 것이고 같으면 두 문자열을 그냥 합치는 것이다. compare함수가 이 기능을 나타낸 것이다.

그 다음 다시 answer함수로 돌아와 combine인 경우에는 left와 right의 문자열을 그냥 이으면 되고, left가 클 때(left-absorb인 경우)는 l[:-1]로 마지막 ) 바로 전에 right문자열을 넣어서 (()) + ()이면 (()()) 이런식으로 묶는다. 

그 다음 right-solve인 경우 r[0]인 (바로 뒤에 left문자열을 합친 후 나머지 right문자열을 합치면 된다.

합친 결과를 리스트안에 값들이 1개 보다 크면 left에 넣어 다시 비교를 하다가 최종적으로 리스트에 두개의 left, right가 남았을 때 마지막 연산을 하고 종료한다.


def compare(prob): cnt = 0 max = 0 for i in prob: if i is '(': cnt += 1 if i is ')': cnt -= 1 if cnt > max: max = cnt return max def answer(l,r): le = compare(l) ri = compare(r) if le == ri: return l+r elif le > ri: return l[:-1]+r+l[-1] elif le < ri: return r[0]+l+r[1:] def main(): while True: prob = str(input()) prob = prob[:prob.index('=')] p = prob.replace(' + ',' ').split() while len(p) > 1: left = p.pop(0) right = p.pop(0) p.insert(0,answer(left,right)) print(p) if __name__ == '__main__': main()

이렇게 짠 코드를 nc에서 돌리면 성공한다. 아래는 문제를 푸는 과정이므로 설명은 생략한다.



이렇게 하나하나 수작업으로 하는 것은 이번 경우에는 될지 몰라도 익스플로잇 코드를 짜기에는 부적절하다.

원래는 우분투로 pwn모듈을 사용해서 이 문제를 자동화 하려 했지만 계속 오류가 나서 수작업을 할 수 밖에 없었다.

이왕 pwn모듈이 오류가 나는거 윈도우에서도 사용할 수 있도록 나만의 pwn모듈을 만들 생각이다.

python 3.6.x버전으로

p.s) 요즘 프로그래밍 공부를 뜸하고 해킹 기법 공부를 하다보니 이 코드를 짜는데 생각보다 오래걸려 pwn 모듈을 구현해보는 겸 다시 프로그래밍 공부를 해야할 것 같다. 그래도 평소 같으면 그냥 스킵할 문제였지만 이런 문제의 스크립트를 짜서 푸는건 처음이라 의미가 있었던것 같다.


반응형