pwnable 9번 문제인 BOF_PIE 이다.

 

보아하니 매번 실행할 때마다 출력해주는 주소의 위치는 바뀌고, 우리한테 무언가 값을 입력받는다.

 

32bit elf 파일, NX-bit와 PIE가 걸려있다.

 

main문에서는 welcome 함수를 실행 후 Nah를 출력한다.

 

welcome 함수에서는 welcome의 주소를 출력하고, v1에 scanf로 입력을 받는다.

 

그리고 함수들 중 j0n9hyun이라는 함수가 있는데, 보아하니 flag를 출력해주는 함수이다.

PIE가 걸려있는것을 고려해보았을 때, 매 함수는 실행 할때마다 주소가 바뀌지만, 각 함수들의 offset은 동일할 것이다.

우리는 프로그램을 실행하면서 welcome의 주소를 알 수 있다.

따라서 현재 바이너리에서 j0n9hyun의 주소가 welcome의 주소로부터 얼마나 차이가 나는지를 통해 offset 크기를 알 수 있다.

 

0x909 - 0x890 = 0x79, 즉 offset 크기는 0x79이다.

자 그러면 우리가 입력을 받는 v1은 ebp-12h에 있으니, v1(18) + sfp(4) = 22, 22개의 더미데이터를 입력하고, 주어진 welcome 함수 - 0x79를 한 값을 ret에 써주면 j0n9hyun이 실행될 것이다.

익스코드를 짜보자.

 

성공적으로 익스플로잇이 된다.

pwnable 8번 문제인 Offset 이다.

 

이런식으로 실행이 되는데, 입력을 받는 다는 것 빼고는 잘 모르겠으니 바이너리를 한 번 보자.

 

32비트 elf파일, NX-bit가 걸려있으니 shell코드를 못 쓰고, PIE가 걸려있으니 매 타임 실행할 때마다 변수, 함수들의 오프셋 위치가 달라질 것이다. FULL RELRO라 GOT Overwrite도 못한다.

 

s에 입력을 받고, select_func라는 함수에 s를 넘겨준다.

 

select_func에서는 v3라는 함수포인터에 two라는 값을 넣어주고, dest에 넘겨받은 우리가 입력해준 값을 받고, 그 값이 one이면 v3를 one으로 바꿔준다.

 

두 함수는 정말 별거 없다.

 

함수 포인터에 값을 넣어서 실행하는 방식이니 v3를 뭔가로 덮어야한다고 생각했다.

그래서 함수들을 보니, 함수 중에 print_flag라는 함수가 있다.

 

flag를 출력해준다.

그말은 즉 v3의 값을 print_flag함수의 주소로 덮어쓴다면 flag가 출력될 것이다.

main에서 s는 gets로 입력을 받으니 BOF가 일어날 것이다.

select_func에서의 dest는 ebp-2Ah, v3는 ebp-Ch에 있으니, 0x2A - 0xC = 0x1E = 30(10) 이 된다.

즉, 우리는 더미값을 30칸 채워주고, print_flag의 주소를 쓰면 될 것이다.

익스코드를 짜보자.

 

성공적으로 익스플로잇이 된다.

pwnable 7번 문제인 Simple_Overflw_ver2 이다.

 

입력을 받고 그대로 출력을 해주는데, 위치는 0xffcd43b0 으로 고정되어 있는 것을 확인할 수 있다.

 

32비트 ELF 파일, 적용된 보호기법은 없다.

 

NX-bit도 없고 쉘을 주는 함수도 없다.

그리고 scanf로 s를 입력받으니 BOF 취약점이 있다.

또, s의 주소를 제공해주므로 s에 쉘코드를 넣고 더미값을 채워 ret을 다시 s의 주소로 덮으면 될 것s의  같다.

s가 ebp-88h이니 쉘코드를 넣고, 0x88 + 4(sfp) - 쉘코드의 길이 만큼 더미 값을 채워넣고, ret을 다시 s의 주소로 덮어써보자.

 

자 정리를 해보자.

1. scanf로 입력받아 BOF 취약점이 일어난다.
2. 매타임 입력할 때 s의 주소를 알려주므로 쓰레기값을 하나 넣어주고 주소값을 먼저 받는다.

3. s에 쉘코드(25byte)를 넣고 136(0x88)+4-25 = 115의 만큼 더미데이터를 넣어준다.

4. s의 ret에 s의 주소를 다시 넣자. 

 

좋아, 익스코드를 짜보자.

 

엄..

 

성공적으로 익스플로잇이 된다.

pwnable 6번 문제인 x64 Simple_size_BOF 이다.

 

buf의 위치를 출력해준다.

그리고 뭔가 입력을 받는거 같은데 아무런 변화도 일어나지는 않는다.

 

64비트 elf, 그리고 적용된 보호기법은 없다.

 

v4의 주소를 출력하고, v4에 입력을 받는다.

뭔가 쉘을 주는 다른 함수는 보이지 않는다.

v4는 rbp-6D30h, 즉, v4에 쉘코드를 넣고, 0x6D30 + 8(sfp) - 쉘코드의 길이 만큼 더미값을 채워넣어서 ret을 처음 제공해주는 v4의 주소를 넣으면 될 것이다.

좋아, 익스코드를 짜보자.

 

payload에 쉘코드는 31byte 짜리, v4_addr에 처음 제공해주는 v4의 주소를 저장한다.

그리고 0x6D30에 쉘코드 길이를 빼주고 sfp를 더한 뒤 ret에 v4_addr을 넣는다.

실행을 해보면..

 

성공적으로 익스플로잇이 된다.

pwnable 5번 문제인 x64 Buffer Overflow 이다.

 

입력을 받고 Hello와 내가 입력한 내용을 그대로 출력해준다.

 

제목 그대로 64비트 elf 파일이고, NX-bit가 걸려있으니 쉘코드를 실행 못하고, RELRO도 걸려있으니 got overwrite 도 못한다.

scanf로 s에 문자열 입력을 받는다.

더미값으로 채워서 ret을 덮을 수 있을 것이다.

그럼 ret에 넣을 뭔가 주소를 찾아야하는데..

callMeMaybe 함수가 보였다.

보다시피 쉘을 준다.

callMeMaybe 함수의 주소를 확인했다.

64비트 환경에서 sfp는 8바이트다.

그리고 s의 위치는 rbp-110h이다.

즉, s에 0x110 + 8(sfp) 만큼 더미데이터를 입력하고, callMeMaybe 함수의 주소로 ret을 덮어쓰면 될 것이다.

0x110 = 272(10)

272 + 8 = 280

p callMeMaybe = 0x400606

익스코드를 짜보자.

 

성공적으로 익스플로잇이 된다.

pwnable 4번 문제인 내 버퍼가 흘러넘친다!!! 이다.

 

이름이랑 뭔가 입력을 받는다.

prob1를 한번 보자.

 

딱히 적용된 보호기법은 없다.

 

main문에서 name에 read로 0x32만큼 입력을 받는다.

그리고 다시 s에 gets로 입력을 받는다.

NX-bit가 적용되어 있지 않으니 name에 쉘코드를 입력하고, s에 BOF를 일으켜 name을 실행할 수 있을 것 같다.

name의 주소를 확인해보자.

 

0x0804A060이다.

즉 처음 입력에 0x32 크기보다 작은 쉘코드를 넣고, s에서 0x14 + 4(sfp)만큼 더미값으로 덮은 뒤 s의 ret을 name의 주소 0x0804A060로 덮어써서 BOF가 일어나도록 할 수 있을 것이다.

익스코드를 짜보자.

 

쉘코드는 25byte 짜리를 가져다 썼다.

실행을 해보면..

 

성공적으로 익스플로잇이 된다.

'HackCTF > Pwnable' 카테고리의 다른 글

[HackCTF] Pwnable - x64 Simple_size_BOF  (0) 2020.07.08
[HackCTF] Pwnable - x64 Buffer Overflow  (0) 2020.07.08
[HackCTF] Pwnable - Basic_FSB  (0) 2020.07.03
[HackCTF] Pwnable - Basic_BOF #2  (0) 2020.06.25
[HackCTF] Pwnable - Basic_BOF #1  (0) 2020.06.25

pwnable 3번 문제인 Basic_FSB 이다.

 

대충 입력받고 그 내용 그대로 출력하는 프로그램인가보다.

파일을 뜯어보자.

 

딱히 보호기법은 적용된게 없다.

 

main문에서 바로 vuln함수를 실행

 

흠..1024만큼 s에 입력을 때려박는다.

그리고 format에 1024만큼 s의 값을 출력하고, 그 값을 출력하는것을 리턴시킨다.

한번 서식문자를 입력에 때려박아봤다.

 

두번째 서식문자부터 출력되는 것을 볼 수 있다.

즉, 앞쪽 값으로 printf@got 주소를 쓰고, 더미값을 채우고 뭔가 쉘을 주는 함수를 넣고 %x로 출력..하면 될거라 생각했지만 값을 입력받는 사이즈를 보니 %n과 같은 입력값 사이즈를 출력하는 서식문자로 처리하는게 좋을 것 같았다.

자, 이제 쉘을 줄 다른 함수를 찾아봤다.

 

함수들을 보니 뭔가 flag가 있다.

 

쉘을 준다.

자 이제 우리는 printf@got함수와 flag의 함수가 필요합니다.

자 그러면 우리가 이제 해야할일

 

1. payload에 리틀엔디안으로 printf@got의 주소 0x804A00C을 넣는다.

2. 그리고 이제 아까 생각한대로 %n을 통해 flag의 주소를 넣을 건데, 그말은 즉 첫번째 인자로 인식되는 값이 0x80485B4이여야합니다.

3. 0x80485B4=134514100‬(10), 즉 첫번째 인자의 길이를 134514100‬로 주고 두번째 인자로 %n을 줘야한다.

4. 우리가 맨 처음에 printf@got의 주소를 넣었으니 4바이트를 빼주어야한다.

5. 134514100‬ - 4 = 134514096

6. 즉 payload는 "\x0C\xA0\x04\x08" + "%134514096x" + "%n"

 

좋아 익스코드를 짜보자.

 

처음 풀어보는 포맷 스트링 버그를 이용한 문제였다.

재밌고만

 

반찬이 마음에 든다.

성공적으로 익스플로잇이 된다.

Pwnable 2번 문제인 Basic_BOF #2 이다.

 

?

음 파일을 보자.

 

32bit ELF 파일

 

NX-bit가 적용되어 있다.

IDA로 한번 코드를 보자.

 

s에 133만큼 입력을 받고, v5를 함수로 실행할 수 있다.

쉘코드를 쓰지 못하니 내장되어있는 함수를 사용해야하는데, 함수 목록에 shell이라는것이 보인다.

 

쉘을 주는 함수가 정의되어 있다.

즉, s에서 BOF를 시켜, v5의 값을 shell함수의 주소로 덮어쓰면 될 것이다.

 

shell함수의 주소는 0x0804849b

 

s는  ebp-8Ch, v5는 ebp-Ch이므로 0x8C-0xC, 128만큼 더미값으로 덮어쓰면 v5에 값을 덮어쓸 수 있을 것이다.

128만큼 더미값을 쓰고, 리틀엔디안으로 shell함수의 주소를 써주면 될 것 같다.

p32와 p64라는 좋은 명령어를 알았다.

자동으로 리틀엔디안형태로 바꿔준다는 듯 하다.

 

성공적으로 익스플로잇이 된다.

Pwnable 1번 문제인 Basic_BOF #1 이다.

 

값을 입력받고, 그 값이 입력된 주소를 출력해주는 듯 하다.

 

파일은 32bit ELF 파일

 

checksec로 확인을 해보니 NX-bit가 적용되어 있다.

즉, 쉘코드를 사용할 수는 없다.

 

한번 IDA를 이용해 코드를 살펴보자.

 

s에 45의 길이만큼 값을 입력받고, v5의 값이 0xDEADBEEF면 쉘을 준다.

s ebp-34h, v5가 ebp-Ch이므로 s에 0x34-0xC, 40만큼 더미값으로 덮고 값을 넣으면 RET를 굳이 건드릴 필요 없이 v5에 값을 넣을 수 있다.

40개의 더미 값을 넣고, 0xDEADBEEF를 리틀엔디안형태로 넣어주면 될 것 같다.

 

성공적으로 익스플로잇이 된다.

+ Recent posts