Hackergame部分题解分析

Hackergame 2020比赛解题分析

1 前言

Hackergame 2020,中文名是:中国科学技术大学第七届信息安全大赛。

题目很多而且涉及方面极广,在这次比赛中学到了很多东西,虽然大部分题都没有做出来,但是锻炼了自己的同时涉及的方面也更宽广了,最后成绩不怎么样,但是好在锻炼了自己:

clip_image002

2 正文

2.1 签到

(1)题目分析:

要求给出整数倍的数值提交,但是页面上的滑条很灵敏,很难正好弄到整数。

(2)解题步骤:

直接点击提交,可以在url栏看到是以get方式提交的number变量值,直接修成1再次提交即可:

clip_image004

2.2 猫咪问答++

(1)题目分析:

一个表单,有各种各样的问题,分别需要你填出正确的答案:

(2)解题步骤:

解题思路就是利用网络搜索工具,考察我们的信息搜索能力,依次解决答案即可。

1.

问:以下编程语言、软件或组织对应标志是哺乳动物的有几个?

Docker,Golang,Python,Plan 9,PHP,GNU,LLVM,Swift,Perl,GitHub,TortoiseSVN,FireFox,MySQL,PostgreSQL,MariaDB,Linux,OpenBSD,FreeDOS,Apache Tomcat,Squid,openSUSE,Kali,Xfce.

提示:学术上一般认为龙不属于哺乳动物。

答:第一小题明显是最复杂的,可以最后一一尝试。

2.

问:第一个以信鸽为载体的 IP 网络标准的 RFC 文档中推荐使用的 MTU (Maximum Transmission Unit) 是多少毫克?

提示:咕咕咕,咕咕咕。

答:以关键词在搜索引擎搜索即可:

关键信息:

1990年4月1日,David Waitzman向互联网工程任务组的网络工作小组提交了一份名为《禽类载体IP数据报传输标准》的制订标准(简称RFC),如今简称为IPoAC。RFC 1149当中描述了“一种在禽类载体当中封装IP数据报的实验性方法”,以及一系列用于解决服务质量问题以及向IPv6过渡的更新建议(二者分别发布于1999年4月1日与2011年4月1日)。

RFC 1149:https://www.rfc-editor.org/rfc/rfc1149.txt

关键信息:

The MTU is variable, and

paradoxically, generally increases with increased carrier age. A

typical MTU is 256 milligrams.

答案:256

3.

问:USTC Linux 用户协会在 2019 年 9 月 21 日自由软件日活动中介绍的开源游戏的名称共有几个字母?

提示:活动记录会在哪里?

答:使用GoogleHaking的语法

GoogleHacking:site:lug.ustc.edu.cn intext:2019年9月21日+自由软件日

搜到的网址:https://lug.ustc.edu.cn/oldwiki/lug/events/sfd

Teeworlds

答案:9

4.

问:中国科学技术大学西校区图书馆正前方(西南方向) 50 米 L 型灌木处共有几个连通的划线停车位?

提示:建议身临其境。

答:搜索中国科学技术大学的全景3D图片

答案:9

5.

问:中国科学技术大学第六届信息安全大赛所有人合计提交了多少次 flag?

提示:是一个非负整数。

答:直接搜索相关信息

答案:17098

最后从尝试第一题的:16-12

答案:12

就可以了

(3)拓展:

本道题还可以使用burpsuit或者python等工具直接进行爆破解题,但是一一搜索也锻炼了信息搜集能力。

2.3 2048

(1)题目分析:

打开是一个简单的移动砖块小游戏,需要达到足够高的分数才能给flag,但是真的达到那个分数是很难的,此时我们应该找其他方法。

(2)解题步骤:

故意失败一次,利用F12中的Network捕捉发送包的定位:

clip_image008

选择然后定位本地传输的js代码位置,然后就会看到下面的代码:

分析代码即可得知,如果赢了就会发送如下url:

url = "/getflxg?my_favorite_fruit=" + ('b'+'a'+ +'a'+'a').toLowerCase();

直接在控制台看一下的('b'+'a'+ +'a'+'a').toLowerCase();值:

clip_image010

于是可以构建答案:

payload:

?my_favorite_fruit=banana

flag:

flxg{8G6so5g-FLXG-aa63af33cd}

2.4 一闪而过的 Flag

(1)题目分析:

下载下来是个可执行控制台程序,但是一执行就会直接消失。

(2)解题步骤:

打开cmd命令行,在cmd中执行程序:

clip_image012

此时显示的内容就不会再消失。

2.5 从零开始的记账工具人

(1)题目分析:

给出一个Excel表格,其中全部都是繁体文字写出的钱的数值,要求要将它们全部加起来计算出结果。

(2)解题步骤:

1.下载方方格子Excel插件,这个插件有将简体中文数值转化为数字的功能。

2.但是很明显题目中的数值全部都是繁体中文,方方格子并不能全部转换,而且其中还有许多小数,小数部分也是不能直接转换的。

3.我需要写python脚来讲繁体中文转化为简体中文,并且对小数部分和整数部分分别处理,以免方方格子在转化数字时发生错误:

#!/usr/bin/python

'''
区分元的代码
    c=s.split('元')
    print(c[0],c[1])
    f.write(c[1])
    f.write('\n')
'''

a=open('以元结尾.txt','r')
text=a.read()
a.close()

f=open('out.txt','w')

st=text.split('\n')
for s in st:
    ans=""
    for c in s:
        #print(c)
        if c=='壹':
            c='一'
        elif c=='贰':
            c='二'
        elif c=='叁':
            c='三'
        elif c == '肆':
            c = '四'
        elif c == '伍':
            c = '五'
        elif c == '陆':
            c = '六'
        elif c == '柒':
            c = '七'
        elif c == '捌':
            c = '八'
        elif c == '玖':
            c = '九'
        elif c=='佰':
            c='百'
        elif c == '拾':
            c = '十'
        elif c=='零':#对元部分的处理
            c='零'
        #elif c=='元':
        #    c='百'
        # elif c=='角':
        #     c='十'
        # elif c=='零' or c=='分':#对分部分的处理
        #     c=''
        # elif c=='整':
        #     c='零'
        else:
            print('error')
            exit(-1)
        ans+=c
    f.write(ans)
    f.write('\n')
f.close()

4.然后将它们含元的部分、不含元的部分还有以分结尾的部分,分别处理,最后相加。

clip_image014

5.最后得到和:17456.95

2.6 超简单的世界模拟器

(1)题目分析:

由题目提示了解到是一种数字游戏叫做:生命游戏(Conway's Game of Life)

需要我们在这个游戏中达到它想要的目的,即让细胞碰到右侧的两个砖块。

(2)解题步骤:

1.搜索和了解了生命游戏的基本原理和玩法。

2.在维基百科中得到了一些基本的细胞结构,比如太空船,就可以轻松解决第一小题:摧毁一个砖块。

payload1:

000000000000000 
000000000000000 
000000000000000 
000000000000000 
000000000000000 
000000000000000 
000000000000000 
000000000000000 
000000000000000 
000000000000000 
000000000000000 
000001001000000 
000000000100000 
000001000100000 
000000111100000

3.第二小题我在比赛中没有解出来,同时摧毁上下两个砖块太过困难,官方wp给出了一个可行的例子:

000000000000000 
000000000000000 
000000000000000 
000000000000000 
000000000000000 
000000000000000 
000000011000000 
000000001100000 
000000011000000 
000000010000000 
000000000000000 
000000000000000 
000000000000000 
000000000000000 
000000000000000 

(3)拓展:

官方指出,除了手工构建的方法以外,还能用暴力破解的方法,还是python学的不到家,需要继续努力。

2.7 自复读的复读机

(1)题目分析:

编写两个只有一行的 Python 代码:

其中一个要输出代码本身的逆序(即所有字符从后向前依次输出)

另一个是输出代码本身的 sha256 哈希值,十六进制小写(2)解题步骤:

(2)解题步骤:

1.通过关键词搜索相关信息,可以看到一些教程和结果:

#教程网址

#https://zhuanlan.zhihu.com/p/34882073

#https://tio.run/##K6gsycjPM/7/P95WPd5Wtci6oCgzr0QjXlU1XlMdzonX/P8fAA

#='=%r;print(%%)';print(%)

#这一行代码能输出本身

2.题目要求是输出字符串的逆序,所以需要自己进行修改构造:

好不容易构建出来一行代码:

_=")'_='+]1-::[_%%_(tnirp;%r";print(_%_[::-1]+'=_')

输出和原来的相反一毛一样,然后发现,人家题目连回车符也算上了。。。

这样提交之后有一个问题,就是输出比代码多了一个 \n,这是由于输入的代码结尾没有换行符而 print 输出的内容结尾会自带换行符,我们只需要让 print 不输出换行符,加一个 ,end="" 即可。

exp:

_=")''=dne,'_='+]1-::[_%%_(tnirp;%r";print(_%_[::-1]+'=_',end='')

(3)拓展:

官方的解法更加简洁:

第一问(每行都是一个可能的构造):

exec(s:='print(("exec(s:=%r)"%s)[::-1],end="")')
s='s=%r;print((s%%s)[::-1],end="")';print((s%s)[::-1],end="")

第二问(每行都是一个可能的构造):

exec(s:='print(__import__("hashlib").sha256(("exec(s:=%r)"%s).encode()).hexdigest(),end="")')
exec(s:='import hashlib;print(hashlib.sha256(("exec(s:=%r)"%s).encode()).hexdigest(),end="")')
import hashlib;s='import hashlib;s=%r;print(hashlib.sha256((s%%s).encode()).hexdigest(),end="")';print(hashlib.sha256((s%s).encode()).hexdigest(),end="")

2.8 来自一教的图片

(1)题目分析:

题目给了一张上面有奇怪的杂乱纹路的图片,然后给出提示是做傅里叶光学实验的图片:

clip_image016

(2)解题步骤:

根据提示搜索相关代码,搜索到可以进行傅里叶光学转码的代码,然后进行转码即可:

exp:

import numpy as np 
import cv2 as cv 
from matplotlib import pyplot as plt 
img = cv.imread('./4f_system_middle.bmp', 0) 
f = np.fft.fft2(img) 
logf = 20*np.log(np.abs(f)) 
plt.imshow(logf, 'gray') 

多次解析就可以看出来flag:

clip_image018

2.9 生活在博弈树上

(1)题目分析:

给一个可执行程序,要求逆向分析找出漏洞利用。

(2)解题步骤:

这是一个pwn题,直接放入ida中:

分析了好几次代码,最终确定,解题方法就是用gets函数覆盖success这个变量的值

首先可以看到临时变量的设定:

clip_image020

rbp没见过,但是只能当成ebx来看了啊,知识面还是太窄,可以看到是-90h,也就是-9*16=-144

clip_image022

找了半天没找到success变量的位置,注释原来是不会显示在反编译文件中的啊

根据代码输出可以大概找到定义位置,也看不太懂。。。

clip_image024

clip_image026

对照着源码看好像明白了一点,前面两个方框是代码中的定位光标的作用。

那么第三个方框就是处理变量了吧,估计succes应该就是rbp+var_1,var_1=-1,差距也就是-1-(-144)=143咯。

设计payload:

payload="(1,1)"+"A" * 138 + "\x01"

过了!!!

clip_image028

flag:

flag{easy_gamE_but_can_u_get_my_shel1}

这道题还有后面一道题,相当于我现在做了半道,但是没有新的源代码和服务端了,仔细看了看源代码,也不可能有第二个flag,所以猜测应该要拿到它的shell,但是源码中没有直接的函数可以拿到shell,也就是说可能是代码注入pwn。

难办,这方面我还没学,也就不能做了。

2.9 狗狗银行

(1)题目分析:

经过借钱还钱、开信用卡、储蓄卡等操作使净资产确实高于 2000 时才会给出 flag

(2)解题步骤:

刚开始我的思路就错了,一直在找包的漏洞,结果发现包中的参数都是不能利用的值,api也是非常简化的调用形式,所以根本找不到可利用处,也就是说辛苦的抓包白费了,人家就是一个全服务区的后端引用。

无奈之下,我从“狗狗银行”这个名字入手,找了一下类似的题,结果还真让我找到了,漏洞应该就是整形溢出了:

clip_image030

经检验,在信用卡转给储蓄卡极值之后,净资产会加1,原理还不太明白,但是一张信用卡最多给一张储蓄卡加2,那就需要最少500张信用卡和500张储蓄卡了。。。

想把注意打到bp的多线程上,但是太麻烦了,先看看有没有其他思路。

9007199254740991,查了一下,这个数字是js的最大精确整数Math.pow(2,53)-1

同时,我又看到了官方的一条公告:

公告 1:本题前端计算存在浮点数导致的计算误差,数字特别极端时显示可能不正确。但后端采用大整数精确计算,只有净资产确实高于 2000 时才会给出 flag。

额。。。那这条思路是不是没戏 了。。。

然后尝试了各种大数据、特殊数据:

clip_image032

167时,利息为1

利息为2的话最起码要500左右,也就是说,167是利率最大的时候

834,利息为3

本金1000,最多能分为167*5+165

连吃饭钱也赚不回来,那就借吧!

因为开始时,信用卡利息最小是10,利率为0.5%,也就是说,欠款达到2000时才会让利息更多。

2000/167=11.9,不够啊,没顿加利息是20块啊。。。

500,能弄4张,也就是8块,不够

3099/167=18.56,还是不够

思路一度十分僵化。。。。。

但是功夫不负有心银啊!突然想到,信用卡利率是0.5%,也就是说200币是1币的利息,而储蓄卡只要167就能挣到1币,也就是说我每转一张卡就有23币的抽成!这绝对是解题点!

官方给的限制是最多1000张卡,完全够用!

开始我手输了一段,,,太痛苦了,也完全不够用,还是乖乖回来用python了,也学习了一下requests模块的简单使用,这波不亏!

exp:

import requests

url='http://202.38.93.111:10100/api/create'
header={'Host':'202.38.93.111:10100'
,'Accept':'application/json, text/plain, */*'
,'Authorization':'*************'
,'Content-Type':'application/json;charset=UTF-8'
,'Accept-Encoding':'gzip, deflate'
,'Accept-Language':'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,zh-TW;q=0.6',
'Cookie': 'session=*****'
}

for i in range(83,800):
    data = '{"src":2,"dst":%d,"amount":167}'%i
    print(i)
    r=requests.post('http://202.38.93.111:10100/api/transfer',headers=header,data=data)
    r.encoding='utf-8'
    print(r.text)
    print(r.status_code)

结果:

clip_image034

图17 狗狗银行3

flag:

flag{W0W.So.R1ch.Much.Smart.52f2d579}

3 结尾

本次比赛我做出来的题只是一小部分,但是受益却是颇多,不断学习和不断成长的这个过程让我很是享受,这也正是网络安全这门课程的魅力之处。

同时Hackgame这个比赛也非常好,有意思的地方远远不止我写的这些东西,光是消化其中的知识就需要好久吧,我很高兴能在这次比赛中用到我在网络安全课中学到的知识,也希望自己能不忘初心,走的更高更远!

ps:这篇文章原是在word中写的,后来腾出来,导致这些图片都不太清晰,希望大家不要在意。

1 Like

看到2048,想起rwctf也有一道2048,哈哈你可以试试 :stuck_out_tongue:

okk,有时间我会试试的 :laughing:

图片异常了,能不论坛上传一份

按理说不应该啊,这是在gitee中自己搭的图床,你那里还是异常吗?


我没想到论坛中可以直接传输,抱歉,你看看还异常吗,还是的话我就重传一份。 :grimacing:

我这边显示还是异常

好的,感谢提出错误 :rofl:

Hackergame 2020比赛解题分析【论坛图片版】

1 前言

Hackergame 2020,中文名是:中国科学技术大学第七届信息安全大赛。

题目很多而且涉及方面极广,在这次比赛中学到了很多东西,虽然大部分题都没有做出来,但是锻炼了自己的同时涉及的方面也更宽广了,最后成绩不怎么样,但是好在锻炼了自己:

image

2 正文

2.1 签到

(1)题目分析:

要求给出整数倍的数值提交,但是页面上的滑条很灵敏,很难正好弄到整数。

(2)解题步骤:

直接点击提交,可以在url栏看到是以get方式提交的number变量值,直接修成1再次提交即可:

image

2.2 猫咪问答++

(1)题目分析:

一个表单,有各种各样的问题,分别需要你填出正确的答案:

(2)解题步骤:

解题思路就是利用网络搜索工具,考察我们的信息搜索能力,依次解决答案即可。

1.

问:以下编程语言、软件或组织对应标志是哺乳动物的有几个?

Docker,Golang,Python,Plan 9,PHP,GNU,LLVM,Swift,Perl,GitHub,TortoiseSVN,FireFox,MySQL,PostgreSQL,MariaDB,Linux,OpenBSD,FreeDOS,Apache Tomcat,Squid,openSUSE,Kali,Xfce.

提示:学术上一般认为龙不属于哺乳动物。

答:第一小题明显是最复杂的,可以最后一一尝试。

2.

问:第一个以信鸽为载体的 IP 网络标准的 RFC 文档中推荐使用的 MTU (Maximum Transmission Unit) 是多少毫克?

提示:咕咕咕,咕咕咕。

答:以关键词在搜索引擎搜索即可:

关键信息:

1990年4月1日,David Waitzman向互联网工程任务组的网络工作小组提交了一份名为《禽类载体IP数据报传输标准》的制订标准(简称RFC),如今简称为IPoAC。RFC 1149当中描述了“一种在禽类载体当中封装IP数据报的实验性方法”,以及一系列用于解决服务质量问题以及向IPv6过渡的更新建议(二者分别发布于1999年4月1日与2011年4月1日)。

RFC 1149:https://www.rfc-editor.org/rfc/rfc1149.txt

关键信息:

The MTU is variable, and

paradoxically, generally increases with increased carrier age. A

typical MTU is 256 milligrams.

答案:256

3.

问:USTC Linux 用户协会在 2019 年 9 月 21 日自由软件日活动中介绍的开源游戏的名称共有几个字母?

提示:活动记录会在哪里?

答:使用GoogleHaking的语法

GoogleHacking:site:lug.ustc.edu.cn intext:2019年9月21日+自由软件日

搜到的网址:https://lug.ustc.edu.cn/oldwiki/lug/events/sfd

Teeworlds

答案:9

4.

问:中国科学技术大学西校区图书馆正前方(西南方向) 50 米 L 型灌木处共有几个连通的划线停车位?

提示:建议身临其境。

答:搜索中国科学技术大学的全景3D图片

答案:9

5.

问:中国科学技术大学第六届信息安全大赛所有人合计提交了多少次 flag?

提示:是一个非负整数。

答:直接搜索相关信息

答案:17098

最后从尝试第一题的:16-12

答案:12

就可以了

(3)拓展:

本道题还可以使用burpsuit或者python等工具直接进行爆破解题,但是一一搜索也锻炼了信息搜集能力。

2.3 2048

(1)题目分析:

打开是一个简单的移动砖块小游戏,需要达到足够高的分数才能给flag,但是真的达到那个分数是很难的,此时我们应该找其他方法。

(2)解题步骤:

故意失败一次,利用F12中的Network捕捉发送包的定位:

选择然后定位本地传输的js代码位置,然后就会看到下面的代码:

分析代码即可得知,如果赢了就会发送如下url:

url = "/getflxg?my_favorite_fruit=" + ('b'+'a'+ +'a'+'a').toLowerCase();

直接在控制台看一下的('b'+'a'+ +'a'+'a').toLowerCase();值:

image

于是可以构建答案:

payload:

?my_favorite_fruit=banana

flag:

flxg{8G6so5g-FLXG-aa63af33cd}

2.4 一闪而过的 Flag

(1)题目分析:

下载下来是个可执行控制台程序,但是一执行就会直接消失。

(2)解题步骤:

打开cmd命令行,在cmd中执行程序:

image

此时显示的内容就不会再消失。

2.5 从零开始的记账工具人

(1)题目分析:

给出一个Excel表格,其中全部都是繁体文字写出的钱的数值,要求要将它们全部加起来计算出结果。

(2)解题步骤:

1.下载方方格子Excel插件,这个插件有将简体中文数值转化为数字的功能。

2.但是很明显题目中的数值全部都是繁体中文,方方格子并不能全部转换,而且其中还有许多小数,小数部分也是不能直接转换的。

3.我需要写python脚来讲繁体中文转化为简体中文,并且对小数部分和整数部分分别处理,以免方方格子在转化数字时发生错误:

#!/usr/bin/python

'''
区分元的代码
    c=s.split('元')
    print(c[0],c[1])
    f.write(c[1])
    f.write('\n')
'''

a=open('以元结尾.txt','r')
text=a.read()
a.close()

f=open('out.txt','w')

st=text.split('\n')
for s in st:
    ans=""
    for c in s:
        #print(c)
        if c=='壹':
            c='一'
        elif c=='贰':
            c='二'
        elif c=='叁':
            c='三'
        elif c == '肆':
            c = '四'
        elif c == '伍':
            c = '五'
        elif c == '陆':
            c = '六'
        elif c == '柒':
            c = '七'
        elif c == '捌':
            c = '八'
        elif c == '玖':
            c = '九'
        elif c=='佰':
            c='百'
        elif c == '拾':
            c = '十'
        elif c=='零':#对元部分的处理
            c='零'
        #elif c=='元':
        #    c='百'
        # elif c=='角':
        #     c='十'
        # elif c=='零' or c=='分':#对分部分的处理
        #     c=''
        # elif c=='整':
        #     c='零'
        else:
            print('error')
            exit(-1)
        ans+=c
    f.write(ans)
    f.write('\n')
f.close()

4.然后将它们含元的部分、不含元的部分还有以分结尾的部分,分别处理,最后相加。

5.最后得到和:17456.95

2.6 超简单的世界模拟器

(1)题目分析:

由题目提示了解到是一种数字游戏叫做:生命游戏(Conway's Game of Life)

需要我们在这个游戏中达到它想要的目的,即让细胞碰到右侧的两个砖块。

(2)解题步骤:

1.搜索和了解了生命游戏的基本原理和玩法。

2.在维基百科中得到了一些基本的细胞结构,比如太空船,就可以轻松解决第一小题:摧毁一个砖块。

payload1:

000000000000000 
000000000000000 
000000000000000 
000000000000000 
000000000000000 
000000000000000 
000000000000000 
000000000000000 
000000000000000 
000000000000000 
000000000000000 
000001001000000 
000000000100000 
000001000100000 
000000111100000

3.第二小题我在比赛中没有解出来,同时摧毁上下两个砖块太过困难,官方wp给出了一个可行的例子:

000000000000000 
000000000000000 
000000000000000 
000000000000000 
000000000000000 
000000000000000 
000000011000000 
000000001100000 
000000011000000 
000000010000000 
000000000000000 
000000000000000 
000000000000000 
000000000000000 
000000000000000 

(3)拓展:

官方指出,除了手工构建的方法以外,还能用暴力破解的方法,还是python学的不到家,需要继续努力。

2.7 自复读的复读机

(1)题目分析:

编写两个只有一行的 Python 代码:

其中一个要输出代码本身的逆序(即所有字符从后向前依次输出)

另一个是输出代码本身的 sha256 哈希值,十六进制小写(2)解题步骤:

(2)解题步骤:

1.通过关键词搜索相关信息,可以看到一些教程和结果:

#教程网址

#https://zhuanlan.zhihu.com/p/34882073

#https://tio.run/##K6gsycjPM/7/P95WPd5Wtci6oCgzr0QjXlU1XlMdzonX/P8fAA

#='=%r;print(%%)';print(%)

#这一行代码能输出本身

2.题目要求是输出字符串的逆序,所以需要自己进行修改构造:

好不容易构建出来一行代码:

_=")'_='+]1-::[_%%_(tnirp;%r";print(_%_[::-1]+'=_')

输出和原来的相反一毛一样,然后发现,人家题目连回车符也算上了。。。

这样提交之后有一个问题,就是输出比代码多了一个 \n,这是由于输入的代码结尾没有换行符而 print 输出的内容结尾会自带换行符,我们只需要让 print 不输出换行符,加一个 ,end="" 即可。

exp:

_=")''=dne,'_='+]1-::[_%%_(tnirp;%r";print(_%_[::-1]+'=_',end='')

(3)拓展:

官方的解法更加简洁:

第一问(每行都是一个可能的构造):

exec(s:='print(("exec(s:=%r)"%s)[::-1],end="")')
s='s=%r;print((s%%s)[::-1],end="")';print((s%s)[::-1],end="")

第二问(每行都是一个可能的构造):

exec(s:='print(__import__("hashlib").sha256(("exec(s:=%r)"%s).encode()).hexdigest(),end="")')
exec(s:='import hashlib;print(hashlib.sha256(("exec(s:=%r)"%s).encode()).hexdigest(),end="")')
import hashlib;s='import hashlib;s=%r;print(hashlib.sha256((s%%s).encode()).hexdigest(),end="")';print(hashlib.sha256((s%s).encode()).hexdigest(),end="")

2.8 来自一教的图片

(1)题目分析:

题目给了一张上面有奇怪的杂乱纹路的图片,然后给出提示是做傅里叶光学实验的图片:

(2)解题步骤:

根据提示搜索相关代码,搜索到可以进行傅里叶光学转码的代码,然后进行转码即可:

exp:

import numpy as np 
import cv2 as cv 
from matplotlib import pyplot as plt 
img = cv.imread('./4f_system_middle.bmp', 0) 
f = np.fft.fft2(img) 
logf = 20*np.log(np.abs(f)) 
plt.imshow(logf, 'gray') 

多次解析就可以看出来flag:

2.9 生活在博弈树上

(1)题目分析:

给一个可执行程序,要求逆向分析找出漏洞利用。

(2)解题步骤:

这是一个pwn题,直接放入ida中:

分析了好几次代码,最终确定,解题方法就是用gets函数覆盖success这个变量的值

首先可以看到临时变量的设定:

rbp没见过,但是只能当成ebx来看了啊,知识面还是太窄,可以看到是-90h,也就是-9*16=-144

找了半天没找到success变量的位置,注释原来是不会显示在反编译文件中的啊

根据代码输出可以大概找到定义位置,也看不太懂。。。

对照着源码看好像明白了一点,前面两个方框是代码中的定位光标的作用。

那么第三个方框就是处理变量了吧,估计succes应该就是rbp+var_1,var_1=-1,差距也就是-1-(-144)=143咯。

设计payload:

payload="(1,1)"+"A" * 138 + "\x01"

过了!!!

flag:

flag{easy_gamE_but_can_u_get_my_shel1}

这道题还有后面一道题,相当于我现在做了半道,但是没有新的源代码和服务端了,仔细看了看源代码,也不可能有第二个flag,所以猜测应该要拿到它的shell,但是源码中没有直接的函数可以拿到shell,也就是说可能是代码注入pwn。

难办,这方面我还没学,也就不能做了。

2.9 狗狗银行

(1)题目分析:

经过借钱还钱、开信用卡、储蓄卡等操作使净资产确实高于 2000 时才会给出 flag

(2)解题步骤:

刚开始我的思路就错了,一直在找包的漏洞,结果发现包中的参数都是不能利用的值,api也是非常简化的调用形式,所以根本找不到可利用处,也就是说辛苦的抓包白费了,人家就是一个全服务区的后端引用。

无奈之下,我从“狗狗银行”这个名字入手,找了一下类似的题,结果还真让我找到了,漏洞应该就是整形溢出了:

image

经检验,在信用卡转给储蓄卡极值之后,净资产会加1,原理还不太明白,但是一张信用卡最多给一张储蓄卡加2,那就需要最少500张信用卡和500张储蓄卡了。。。

想把注意打到bp的多线程上,但是太麻烦了,先看看有没有其他思路。

9007199254740991,查了一下,这个数字是js的最大精确整数Math.pow(2,53)-1

同时,我又看到了官方的一条公告:

公告 1:本题前端计算存在浮点数导致的计算误差,数字特别极端时显示可能不正确。但后端采用大整数精确计算,只有净资产确实高于 2000 时才会给出 flag。

额。。。那这条思路是不是没戏 了。。。

然后尝试了各种大数据、特殊数据:

167时,利息为1

利息为2的话最起码要500左右,也就是说,167是利率最大的时候

834,利息为3

本金1000,最多能分为167*5+165

连吃饭钱也赚不回来,那就借吧!

因为开始时,信用卡利息最小是10,利率为0.5%,也就是说,欠款达到2000时才会让利息更多。

2000/167=11.9,不够啊,没顿加利息是20块啊。。。

500,能弄4张,也就是8块,不够

3099/167=18.56,还是不够

思路一度十分僵化。。。。。

但是功夫不负有心银啊!突然想到,信用卡利率是0.5%,也就是说200币是1币的利息,而储蓄卡只要167就能挣到1币,也就是说我每转一张卡就有23币的抽成!这绝对是解题点!

官方给的限制是最多1000张卡,完全够用!

开始我手输了一段,,,太痛苦了,也完全不够用,还是乖乖回来用python了,也学习了一下requests模块的简单使用,这波不亏!

exp:

import requests

url='http://202.38.93.111:10100/api/create'
header={'Host':'202.38.93.111:10100'
,'Accept':'application/json, text/plain, */*'
,'Authorization':'*************'
,'Content-Type':'application/json;charset=UTF-8'
,'Accept-Encoding':'gzip, deflate'
,'Accept-Language':'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,zh-TW;q=0.6',
'Cookie': 'session=*****'
}

for i in range(83,800):
    data = '{"src":2,"dst":%d,"amount":167}'%i
    print(i)
    r=requests.post('http://202.38.93.111:10100/api/transfer',headers=header,data=data)
    r.encoding='utf-8'
    print(r.text)
    print(r.status_code)

结果:

flag:

flag{W0W.So.R1ch.Much.Smart.52f2d579}

3 结尾

本次比赛我做出来的题只是一小部分,但是受益却是颇多,不断学习和不断成长的这个过程让我很是享受,这也正是网络安全这门课程的魅力之处。

同时Hackgame这个比赛也非常好,有意思的地方远远不止我写的这些东西,光是消化其中的知识就需要好久吧,我很高兴能在这次比赛中用到我在网络安全课中学到的知识,也希望自己能不忘初心,走的更高更远!

ps:论坛好像没办法识别markdown图片上传,一个个输入的。。。