Write-up

[angr tutorial] ais3_crackme writeup

ch4rli3kop 2018. 1. 14. 19:00
반응형

angr 사용을 연습하도록 제공해주신 tutorial 문제 ais3_crackme에 관한 글입니다. 문제 링크는 다음과 같습니당.

https://github.com/angr/angr-doc/tree/master/examples/ais3_crackme


문제를 받았으니, 한 번 실행시켜 봅시다.

오잉? 뭔가를 입력하라고 하는 군요!

그래서 한 번 줘봤습니다.

사용자의 입력을 먼저 받아서 작동하는 프로그램인 겁니다. 그 입력 값이 뭔지를 찾아야겠습니다.

IDA는 너무 치트인거 같아서 일단 objdump 로 까봤습니다. 아 학습했듯이 objdump -M intel -d [file] 이런 식으로 사용해주시면 되겠습니다.

어라, 심볼들이 살아있을 줄 몰랐습니다. main 심볼이 지워지지 않았었네요. gdb 를 사용하면 더 편할 듯 합니다. 

코드를 보니 일단 puts() 세 개가 눈에 들어옵니다. 각 각의 puts() 가 뭐를 출력하는지 봐 보아야겠습니다. 프로그램이 64bit 환경이므로, 인자가 먼저 레지스터에 들어간다음 함수가 불리겠습니다. 각 각의 함수가 불리기 직전에 레지스터에 들어가는 주소들을 살펴보도록 하겠습니다. 

딱 보니, 각이 나옵니다. 0x4006f0 이 사용되는 puts() 쪽이 나아가야할 방향입니다. 그 밖의 다른 주소가 사용되는 puts() 들은 피해야 할 곳이네요.


얻은 정보들을 토대로 스크립트를 작성해봅시다.

1
2
3
4
5
6
7
8
9
10
11
12
13
import angr
import claripy
 
proj = angr.Project('./ais3_crackme', load_options={"auto_load_libs":False})
argv1 = claripy.BVS("argv1",8 * 23)
initial_state = proj.factory.entry_state(args=["./ais3_crackme",argv1])
 
sm = proj.factory.simulation_manager(initial_state)
sm.explore(avoid=0x000000000400613, find=0x0000000400607)
 
found = sm.found[0]
print found.solver.eval(argv1, cast_to=str)
 
cs

Project라는 이름으로 파일을 로드합니다. 저기 보이는 load_options 은 라이브러리와 관련된 옵션인데요. 자세한 사항은 아래를 보시면 되겠습니다.


https://github.com/angr/angr-doc/blob/master/docs/loading.md

뿐만 아니라, 여타 다른 사항도 참고하시면 좋을 것 같습니다.


우선 claripy 를 이용하여 입력받을 문자열의 크기를 지정해줍니다. 


사실 이 부근에서 문자열의 크기가 23바이트라는 힌트를 얻을 수 있습니다. 반복문에서 사용하는 인덱스를 23(0x17)과 비교를 함으로써 알 수 있는데, 사실 주는 문자열의 크기는 23바이트 이상이기만 하면 됩니다. 그냥 적당히 100바이트를 줘도 좋습니다. 왜 23바이트인지라는 설명이 부족한 것 같아, 치트의 힘을 빌립니다.


저 부분에서 문자열의 크기가 23바이트 임을 알 수 있을 것 같습니다.


여하튼, 다시 코드로 돌아갑시다. initial_state를 사용한 이유는 이 프로그램은 이미 사용자의 입력을 받고 시작하기 때문에, 사용자의 입력이 들어간 상태에서의 state를 angr 에게 주어야하기 때문입니다. 말이 조금 복잡하지만, 결론은 argv 인자로 입력 값을 받기때문입니다. 저렇게 초기 상태를 만들어주고, angr의 simulation manager에게 만든 상태를 줍니다. 인자로 입력 값을 받는 경우에는 이렇게 사용합니다! :ㅁ


simulation manager를 해줬으면, 옵션으로 목표로 삼을 가고 싶은 영역의 주소와 피하고 싶은 영역의 주소를 적어주어, explore 를 실행합니다!


찾았으면, 찾은 입력 값들을 출력합시다. eval을 이용하여 수행할 수 있고, cast to 를 이용해서 출력할 타입을 지정해 줄 수 있습니다.


이렇게 만든 스크립트를 실행하면,


짜잔~! 입니다.

flag : ais3{I_tak3_g00d_n0t3s}


반응형

'Write-up' 카테고리의 다른 글

[pwnable.kr] blackjack write-up  (0) 2018.01.22
[pwnable.kr] cmd1 write-up  (0) 2018.01.17
[SECCON 2017] Powerful_Shell writeup  (0) 2018.01.14
[reversing.kr] ImagePrc writeup  (0) 2018.01.09
[reversing.kr] Easy_CrackMe writeup  (0) 2018.01.08