Analyzing overall source code with peek, the java program get a single main function argument input called 'var0'
We can simply guess, printing "Nah" means invalid input.
The number of argument (var1_1) should be 1,
The length of first argument (var4_4) should be 927739485 ^ 927739456 => 28
With similar pattern, the first character of argument (v0[0]) shoudl be 189074585 ^ 189074673
The second character of argument (v0[1]) should be -227215135 ^ -227215214
Proceeding this work, we can easily find not only the header of flag "hsctf{", but also the rest part of the flag.
You can do it manualy one by one, or write a python script to extract the source code line contains the pattern like "v0[index] ^ A - B != 0" and evaluate the each letter on flag.
process class를 정의해서 사용하고 있는데, 생성자인 __init__ 부분을 확인해보니, subprocess.Popen()을 이용해서 프로세스를 생성하는 것을 확인할 수 있었다.
그런데 어떤 차이가 있길래 NULL Byte Argument를 넘겨주어도 잘 실행이 되는가 싶어서, Popen 실행하기 직전의 Argument 리스트를 찍어보니, "\x00"인 NULL Character included string을 ""인 Empty String으로 치환되어 Popen API 인자로 넘어가는 것을 확인할 수 있었다.
확인해보니 _validate 함수에서 해당 처리를 하는데, 각각인자의 rstrip("\x00")를 하는 과정에서 사라진 것이다.
뭐 다시 생각을 해 보면, C로 작성한 바이너리에서 main 함수의 argc, argv중 argv는 NULL terminated string들이고,
if (strcmp(argv['A'], "\x00")) return 0;
위 코드를 Pass하기에 단지 Empty string이기만 해도 strcmp 리턴값이 0이 될 것이긴 하다.
어쨋거나 이러한 삽질을 통해서 뭔가 잊고 있떤 사실을 하나 알게 되긴 하였다.
고로 subprocess.Popen과 같은 파이썬 API로 호출해서 pkr input 문제를 풀려면 'A' 번째 인자는 Empty string만 넣어도 된다는 것.