article thumbnail image
Published 2021. 2. 2. 23:43

이번에는 goblin에서 orc로 가는 password를 획득해보자.

goblin에는 orc와 orc.c 파일이 있다. 이중 orc.c 파일을 열어봤다.

 

orc.c 파일에 //egghunter 부분이 생겼다. 환경변수 메모리를 초기화 시켜주는 코드다. 이 코드 때문에 환경변수를 이용한 공격은 못 할 것 같다. 그 다음 if 문을 보니 argv[1]의 48번째 문자가 \xbf여야 하는 것 같다. main의 지역변수가 buffer[40]와 i이고, buffer[40]가 i위에 있는 것으로 보아 메모리 구조는 buffer(40)+sfp(4)+ret(4)이다. ret까지 덮으려면 총 48바이트 코드가 필요한데 buffer로 복사되는 argv[1]의 48번째 문자가 \xbf여야 하기 때문에 return address는 스택영역의 주소여야 할 것 같다.

 

이번엔 스택 영역에 쉘코드를 넣고, 그 주소를 ret영역에 덮는 방식으로 문제를 풀어보겠다. 다만, buffer의 공간이 40+4 바이트이라 셀코드와 nop를 넣기엔 공간이 넉넉하지 않기 때문에 argv[2]를 사용하겠다.

 

공격에 필요한 argv[2]의 주소를 알아보자.

orc파일을 따로 복사하고 gdb로 실행시킨다. 그 후 main을 dump해서 $ebp가 옮겨지는 부분을 확인하고, <main+3>에 브레이크포인트를 걸었다. 그런 다음 argv[1]에 buffer와 ret영역을 채울 48바이트의 더미와 argv[2]에 "\x90"*1000을 전달하고 프로그램을 실행시켰다. 

 

브레이크포인트에서 종료 후 스택 포인터를 살펴보자. <main+3>에 브레이크포인트를 걸어줬기 때문에 현재 esp는 ret 영역 아래에 있는 ebp를 가리키고 있다. 따라서 화면에 출력된 데이터는 차례대로 이전 ebp, ret, argc, argv다.

 

그 다음 0xbffff734부터 3개의 메모리를 출력했다. 0xbffff734가 argv를 가리키는 주소이기 때문에 차례대로 argv[0], argv[1], argv[2]이다.

argv[1]부터 인자가 제대로 전달됐는지 확인하기 위해 0xbffff875부터 48개의 메모리를 출력했다. A 44개와 \xbf\xbf\xbf\xbf 다음에 \x90가 연속적으로 들어있는 것으로 보아 인자는 잘 전달된 것 같다.

 

이렇게 argv[2]의 주소를 알아냈다.  argv[2]: 0xbffff876

 

프로그램 실제 실행 시 메모리의 주소는 조금 달라질 수 있기 때문에 return address는 nop 중간 지점으로 잡겠다. payload는 다음과 같이 구성할 수 있다.

$(python -c 'print("A"*44+"\x85\xf8\xff\xbf")') $(python -c 'print("\x90"*1000+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80")')

 

쉘 실행 성공!

orc로 가는 password는 cantata이다.

'Study > System Hacking' 카테고리의 다른 글

[LOB] wolfman -> darkelf  (0) 2021.02.09
[LOB] orc -> wolfman  (0) 2021.02.03
[lazenca] Protection Tech / NX bit(MS: DEP)  (0) 2021.02.02
[dreamhack] Linux Exploitation & Mitigation Part 1 / NX bit  (0) 2021.02.02
[LOB] cobolt -> goblin  (0) 2021.01.28
복사했습니다!