[▒] 보안/FTZ
처음엔 BOF 문제라고 생각했지만, fgets를 통해 받는 문자의 개수(78)가 bleh 변수의 크기(80)보다 작았기에 'BOF 문제가 아니다'라고 생각했습니다. printf를 보면 보통의 개발자는 printf('format string', 'arg1', 'arg2', ...) 이런 식으로 작성했겠지만, 소스코드 상에는 변수만 들어가있습니다. 이럴 때 발생할 수 있는 취약점이 Format String(이하 FS)입니다. FS는 간단하게 말해서 '%'와 같은 포멧스트링이 첫번째 인자에 나타나게 되면, 포멧스트링 포인터가 문자열을 읽어나가면서 포멧스트링을 마주칠 때, 자신의 위치에서 높은 주소방향으로 알맞은 크기에 맞게 메모리에서 POP 하게 됩니다. 이때, 만약 원하는 주소에 POP을 통해 값을 저장할 ..
gets로 입력을 받은 뒤 출력만 하는 소스코드네요. 아무래도 다른게 없고 이용할만한거라면 RET밖에 안떠오르죠? 자, 그럼 RET 부분에 쉘코드가 담겨있는 환경변수 주소를 담아보겠습니다. 먼저 쉘코드를 만들어야하는데요, attackme 파일은 누구의 소유일까요? level20의 소유네요. 그러면 당연히 소스코드 상에는 level20으로 권한을 상승하는 부분이 없으니 쉘을 얻기 전에 권한 상승부터 해야겠죠? setreuid() 함수를 쓸겁니다. level20의 uid는 3100이네요. 이를 바탕으로 쉘코드를 만들어보겠습니다. 일단, 어셈블리어를 만듭니다. setreuid(3100, 3100), execve("/bin//sh")가 포함되어있습니다. 이후 objdump를 이용해 기계어를 추출해냅시다. ※ 기..
뭐야.. 길고 복잡하네.. 이런저런 생각이 오가고, FD에 대해서 알아보다가 시스템에 대한 지식이 별로 없어 매우 어렵다 느껴서 한 발 빠져서 보니, 일단 디버깅을 해봐야겠다고 생각했습니다. 그리고 한 가지 알 수 있는 점은 뭔가 string 변수를 통해서 check를 0xdeadbeef 값으로 변경해야한다는 것입니다. 음.. 음.. 좋네요. 눈 빠지기 좋아요 ㅋㅋ 자, 이걸 다 보기 싫다면 생각을 해봅시다. check 변수의 위치는 0xdeadbeef 값과 함께 나올겁니다. 그리고, string 변수의 위치는 위쪽에는 없었으니 맨 아래쪽에 'lea'라는 어셈블리어와 함께 등장하겠죠? 그러면 check는 $ebp-0x68, string은 $ebp-0x64이네요. 어라? string보다 check가 뒤에 ..
여러분은 힌트를 보고 뭘 떠올리셨나요? shell 함수도 없고... 저는 보자마자 문득 '아, 쉘코드가 있는 환경변수 주소를 printit 주소 부분 저장되는 곳에 넣으면 되겠네'라고 생각했습니다. 이걸 실행에 옮겨보겠습니다. 환경변수 만들고.. 소스코드 만들고..(환경변수 주소 알아내는 코드) 알아내고.. 위치값 알아내고.. buf는 $ebp-0x38, printit 저장 위치는 $ebp-0x10 둘의 차이는 40바이트. buf(20) + bufdummy(20) + egg 환경변수 주소(4) 끄읕ㅡ★
딱 봐도 문제가 printit의 주소를 call 하는 부분을 shell의 주소를 call 하는 부분으로 바꿔라~ 하는 것 같네요. 한 번 찾아봅시다. 수상한 주소가 보이네요. 0x8048500을 저장하고 call까지? 에이 이건 딱봐도 printit 주소겠죠? 그러면 shell의 주소는 뭘까요 0x80484d0 이라네요. 그러면, 주소를 담는 부분의 위치는 어디일까요? 아, $ebp-0x10이네요. 아래를 보면 fgets함수로 입력된 값이 $ebp-0x38부터 저장됩니다. 둘의 공백은 40, 답이 나왔죠? buf(20) + bufdummy(20) + shell() address(4) 쉘을 성공적으로 획득하였습니다.
전 문제와 거의 똑같지만, 한 가지 다른 점은 check 변수가 포인터 변수라는 점입니다. 따라서, check 변수에 0xdeadbeef를 넣는다고 해도 0xdeadbeef에 해당하는 위치의 메모리에 값을 가져오기 때문에 절대 if 문 조건을 만족시킬 수 없습니다. 하지만, 소스코드에서 아예 0xdeadbeef의 값을 써놓고 대놓고 비교하고 있기 때문에 우리는 0xdeadbeef의 값이 있는 곳을 가리키게만 하면 됩니다. 제 예상으로는 0xdeadbeef의 값을 가지고 있는 메모리 주소는 0x080484b0 ~ 0x080484b6 사이에 있을 것입니다. 2바이트 밀려서 나오네요. 자 이것으로 0xdeadbeef의 위치는 0x80484b2인걸 알았으니, check에 이 주소를 넣읍시다. buf는 $ebp-..
이번에는 검증값이 있는 문제군요. i에 들어있는 0x1234567이 바뀌면 BOF 공격을 감지하는 프로그램입니다. 이를 우회하는 문제인거 같네요. 처음에 0x418 == 1048 바이트의 공간을 할당하고, i변수는 $ebp-0xc에서 가져오네요. long이 4바이트의 크기를 가지고 있는 것을 감안하면 나머지 8바이트는 dummy 겠죠? 이를 idummy라고 칭하겠습니다. 또한 1048-12 == 1036인데, buf변수는 1024바이트였습니다. 따라서, 나머지 12바이트는 dummy라는 것을 알 수 있고 이를 bufdummy라고 칭하겠습니다. buf(1024) + bufdummy(12) + 0x1234567(4) + idummy(8) + SFP(4) + RET(4) 이제 argv[1]이 위치하는 곳이 어..
main 함수에 인자로 'void'가 들어갔다는 것은 아무것도 받지 않겠다는 뜻이죠. 그 외에 gets 함수 빼고는 level11과 똑같은 문제네요. 다른 점은 main 함수의 '인자'가 아닌 '변수'로 값을 받는다는 거겠죠? 그렇다면 여기서는 확실히 환경변수를 이용해야겠네요. 전에 말했다시피 ASLR로 인해 main 함수의 주소가 변하기 때문이에요!! 전에도 썼던 쉘코드를 사용하겠습니다. \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 출처 - https://xerxes-break.tistory.com/212 유용한 쉘코드(x86 Shellcode 로컬) 0x01. 가장..