심심해서 써보는 리버싱 풀이 - 1단계 (난이도: 쉬움)

환경: Ubuntu 

이용한 프로그램: 아이다(hex-ray) 및 파이썬(의 gdb, string module)


문제: Unknown (rev)


ELF, 64비트 파일이다. 


아이다로 까보자..




이 부분이 main() 이다. 


main함수의 매개변수인 a1, a2, a3는 각각 

int argc, char *argv[], char *envp[] 겠지.


일단 argc가 2인것으로 보아 실행 시 인자의 개수가 1개 있어야 하는 것을 알 수 있다.

그리고 argv[1]의 길이가 56이어야 된다.


그리고 for문을 도는데, 


argv[1]과 i (for문의 count) 를 데리고 sub_401E90으로 가서, return 값이 1이면 deword_603084(전역변수)에 1을 집어넣는다.


그리고 dword_603084의 값이 1이면 NOPE이 뜨고,

아니면 원하는 값이 뜨겠지. 


대충 보니까 매개변수 값으로 알맞은 걸 주면 되는 것 같다. 

그럼, 문제의 저 함수로 가보자.



매개변수 a1은 아까 전해준 argv[1] 이고, a2는 for문의 count이다.


.. 상당히 루프가 복잡하다. 이걸 다 계산하다가는 미쳐 돌아버릴것 같다. 머리를 써보자.


결국, 문제는 올바른 인자값을 주지 않으면 위의 함수는 1을 리턴한다는 점이다. 그렇다면 올바른 값을 주면 0을 리턴하겠지?


그리고, 아까 main()문에서 총 56번 루프를 돈다고 했고, 길이 56byte의 인자값을 요구했다.


그럼, 56바이트 하나 하나 검사를 실행해서 맞는 값이면 0을, 틀린 값이면 1을 리턴한다는 것이겠지?


무차별 대입공격(brute-force)이 가능하겠다!


linux용 디버거인 gdb에 python을 attach 해서 자동으로 리턴값이 1인지, 0인지 알아보는 코드만 짜면 될듯하다! 




처음 6글자를 알아내고, 나머지 글자를 알아내는 코드이다. gdb로 인자값을 줄 때 '{' 을 인식 못해서 불가피하게 저렇게 짰다. 

함수가 리턴값을 rax에 주기 때문에 rax의 값이 0이면 그 때의 문자를 하나씩 저장하여 더하기로 했다.


실행해 보자..






음. 잘나왔네! 


flag: TUCTF{w3lc0m3_70_7uc7f_4nd_7h4nk_y0u_f0r_p4r71c1p471n6!}