심심해서 써보는 리버싱 풀이 - 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!}
앵거로는 못푸냐?
저거 루프돌아서 못풀듯.