February 1, 2023

hgame2023


week1

第一周……题很简单,写得比较乱,就这样吧…………

1
2
3
4
5
6
7
In [1]: x = [0x5b,0x54,0x52,0x5e,0x56,0x48,0x44,0x56,0x5f,0x50,0x3,0x5e,0x56,0x6c,0x47,0x3,0x6c,0x41,0x56,0x6c,0x44,0x5
...: c,0x41,0x2,0x57,0x12,0x4e]

In [2]: for i in x:
...: print(chr(i^0x33),end='')
...:
hgame{welc0me_t0_re_wor1d!}
1
2
3
4
5
6
7
8
9
10
box = [8, 6, 7, 6, 1, 6, 0xD, 6, 5, 6, 0xB, 7, 5, 6, 0xE, 6,
3, 6, 0xF, 6, 4, 6, 5, 6, 0xF, 5, 9, 6, 3, 7, 0xF, 5, 5,
6, 1, 6, 3, 7, 9, 7, 0xF, 5, 6, 6, 0xF, 6, 2, 7,
0xF, 5, 1, 6, 0xF, 5, 2, 7, 5, 6, 6, 7, 5, 6, 2,
7, 3, 7, 5, 6, 0xF, 5, 5, 6, 0xE, 6, 7, 6, 9, 6,
0xE, 6, 5, 6, 5, 6, 2, 7, 0xD, 7]

for i in range(0, len(box), 2):
print(chr((box[i+1]<<4)+box[i]),end='')
#hgame{encode_is_easy_for_a_reverse_engineer}

本来以为是出题人的恶趣味,结果只是不小心出错了emmmm

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
#include <stdio.h>
#include <stdint.h>

void decrypt (unsigned int* v) {
unsigned int v0 = v[0], v1 = v[1];
uint32_t delta = 0x543210DD;
int sum = 0;
sum -= 0x543210DD * 32;

for (int i=0; i<32; i++) {
v1 -= (sum + v0) ^ ((v0 >> 5) + 0x45678901) ^ (16 * (v0 + 0x3456789));
v0 -= (sum + v1) ^ (16 * v1 + 0x12345678) ^ ((v1 >> 5) + 0x23456789);
sum += 0x543210DD;
}

v[0]=v0;
v[1]=v1;
}

int main()
{
int v[8] = {0x2E63829D, 0xC14E400F, 0x73495F40, 0x765F345F, 0x5F797265, 0x6C613368, 0x5F796874, 0x6E317264};
decrypt(v);

char *c ;
c = (char*)v;
for(int i = 0; i < 32; i++)
printf("%c",c[i]);
printf("%c%c",0x6b,0x7d);

return 0;
}
//hgame{Te@_Is_4_very_h3althy_dr1nk}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <stdint.h>

int main()
{
char c[] = {
0x04, 0xFF, 0xFD, 0x09, 0x01, 0xF3, 0xB0, 0x00, 0x00, 0x05,
0xF0, 0xAD, 0x07, 0x06, 0x17, 0x05, 0xEB, 0x17, 0xFD, 0x17,
0xEA, 0x01, 0xEE, 0x01, 0xEA, 0xB1, 0x05, 0xFA, 0x08, 0x01,
0x17, 0xAC, 0xEC, 0x01, 0xEA, 0xFD, 0xF0, 0x05, 0x07, 0x06};
for(int i = 0; i < 41; i++)
printf("%c",(c[i]+86)^0x32);

return 0;
}
//hgame{4ddit1on_is_a_rever5ible_0peration}
1
2
3
4
5
6
7
8
9
10
11
12
#在 http://factordb.com/ 分解n
from Crypto.Util.number import *
import gmpy2

p=11239134987804993586763559028187245057652550219515201768644770733869088185320740938450178816138394844329723311433549899499795775655921261664087997097294813
q=12022912661420941592569751731802639375088427463430162252113082619617837010913002515450223656942836378041122163833359097910935638423464006252814266959128953
c=110674792674017748243232351185896019660434718342001686906527789876264976328686134101972125493938434992787002915562500475480693297360867681000092725583284616353543422388489208114545007138606543678040798651836027433383282177081034151589935024292017207209056829250152219183518400364871109559825679273502274955582

e = 65537
i = gmpy2.invert(e,(p-1)*(q-1))
m = pow(c, i, p*q)
print(long_to_bytes(m))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import binascii
import struct

crcbp = open("图片路径", "rb").read() #打开图片
crc32frombp = int(crcbp[29:33].hex(),16) #读取图片中的CRC校验值
print(crc32frombp)

for i in range(4000): #宽度1-4000进行枚举
for j in range(4000): #高度1-4000进行枚举
data = crcbp[12:16] + \
struct.pack('>i', i)+struct.pack('>i', j)+crcbp[24:29]
crc32 = binascii.crc32(data) & 0xffffffff
#print(crc32)
if(crc32 == crc32frombp): #计算当图片大小为i:j时的CRC校验值,与图片中的CRC比较,当相同,则图片大小已经确定
print(i, j)
print('hex:', hex(i), hex(j))
exit(0)
#hex: 0x200 0x2c2
#hgame{e99p1ant_want_a_girlfriend_qq_524306184}

week2

before main

init函数换了base64的码表

1
2
3
4
5
6
7
8
9
import base64

str1 = "AMHo7dLxUEabf6Z3PdWr6cOy75i4fdfeUzL17kaV7rG="

string1 = "qaCpwYM2tO/RP0XeSZv8kLd6nfA7UHJ1No4gF5zr3VsBQbl9juhEGymc+WTxIiDK"
string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

print (base64.b64decode(str1.translate(str.maketrans(string1,string2))))
#hgame{s0meth1ng_run_befOre_m@in}

math

矩阵相乘,用输入矩阵乘以box1,得到box2,最终用box2乘以box1的逆矩阵即可还原输入矩阵。

1
2
3
4
box1 = matrix([[126,225,62,40,216],[253,20,124,232,122],[62,23,100,161,36],[118,21,184,26,142],[59,31,186,82,79]])
box2 = matrix([[63998,33111,67762,54789,61979],[69619,37190,70162,53110,68678],[63339,30687,66494,50936,60810],[48784,30188,60104,44599,52265],[43048,23660,43850,33646,44270]])
print(box2*box1.inverse())
#hgame{y0ur_m@th_1s_gO0d}

stream

md。。。这题做得我想鼠。。。
解包之后反编译,明显RC4+base64
但是直接写脚本是解不出来的……
这是为什么呢?哦~原来是encode的锅,只要把base解密之后的密文再decode回去就好了~……

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
import base64

enc = base64.b64decode(b'wr3ClVcSw7nCmMOcHcKgacOtMkvDjxZ6asKWw4nChMK8IsK7KMOOasOrdgbDlx3DqcKqwr0hw701Ly57w63CtcOl')
enc = enc.decode()

def crypt(data,key) :
s = [0] * 256
for i in range(256) :
s[i] = i
j = 0
for i in range(256) :
j = (j + s[i] + key[i % len(key)]) % 256
s[i], s[j] = s[j], s[i]
i = 0
j = 0
res = ""
for c in data :
i = (i + 1) % 256
j = (j + s[i]) % 256
s[i], s[j] = s[j], s[i]
res = res + chr(ord(c) ^ s[(s[i] + s[j]) % 256])
return res

key = b"As_we_do_as_you_know"
res = crypt(enc,key)
print(res)

最后一个安卓xtea,不写了,摆了。

week3

kunmusic

C#写的,直接看DLL,用dnspy
main函数里有:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private static void Main()
{
ApplicationConfiguration.Initialize();
byte[] data = Resources.data;
for (int i = 0; i < data.Length; i++)
{
byte[] array = data;
int num = i;
array[num] ^= 104;
}
Activator.CreateInstance(Assembly.Load(data).GetType("WinFormsLibrary1.Class1"), new object[]
{
Program.form1
});
Application.Run(Program.form1);
}

直接调试断到这里,自己把数据拖出来异或。数据太长就不放脚本了。
得到一个exe文件,还是C#写的,dnspy里看一个叫music的类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public void music(object sender, EventArgs e)
{
if (this.num[0] + 52296 + this.num[1] - 26211 + this.num[2] - 11754 + (this.num[3] ^ 41236) + this.num[4] * 63747 + this.num[5] - 52714 + this.num[6] - 10512 + this.num[7] * 12972 + this.num[8] + 45505 + this.num[9] - 21713 + this.num[10] - 59122 + this.num[11] - 12840 + (this.num[12] ^ 21087) == 12702282 && this.num[0] - 25228 + (this.num[1] ^ 20699) + (this.num[2] ^ 8158) + this.num[3] - 65307 + this.num[4] * 30701 + this.num[5] * 47555 + this.num[6] - 2557 + (this.num[7] ^ 49055) + this.num[8] - 7992 + (this.num[9] ^ 57465) + (this.num[10] ^ 57426) + this.num[11] + 13299 + this.num[12] - 50966 == 9946829 && this.num[0] - 64801 + this.num[1] - 60698 + this.num[2] - 40853 + this.num[3] - 54907 + this.num[4] + 29882 + (this.num[5] ^ 13574) + (this.num[6] ^ 21310) + this.num[7] + 47366 + this.num[8] + 41784 + (this.num[9] ^ 53690) + this.num[10] * 58436 + this.num[11] * 15590 + this.num[12] + 58225 == 2372055 && this.num[0] + 61538 + this.num[1] - 17121 + this.num[2] - 58124 + this.num[3] + 8186 + this.num[4] + 21253 + this.num[5] - 38524 + this.num[6] - 48323 + this.num[7] - 20556 + this.num[8] * 56056 + this.num[9] + 18568 + this.num[10] + 12995 + (this.num[11] ^ 39260) + this.num[12] + 25329 == 6732474 && this.num[0] - 42567 + this.num[1] - 17743 + this.num[2] * 47827 + this.num[3] - 10246 + (this.num[4] ^ 16284) + this.num[5] + 39390 + this.num[6] * 11803 + this.num[7] * 60332 + (this.num[8] ^ 18491) + (this.num[9] ^ 4795) + this.num[10] - 25636 + this.num[11] - 16780 + this.num[12] - 62345 == 14020739 && this.num[0] - 10968 + this.num[1] - 31780 + (this.num[2] ^ 31857) + this.num[3] - 61983 + this.num[4] * 31048 + this.num[5] * 20189 + this.num[6] + 12337 + this.num[7] * 25945 + (this.num[8] ^ 7064) + this.num[9] - 25369 + this.num[10] - 54893 + this.num[11] * 59949 + (this.num[12] ^ 12441) == 14434062 && this.num[0] + 16689 + this.num[1] - 10279 + this.num[2] - 32918 + this.num[3] - 57155 + this.num[4] * 26571 + this.num[5] * 15086 + (this.num[6] ^ 22986) + (this.num[7] ^ 23349) + (this.num[8] ^ 16381) + (this.num[9] ^ 23173) + this.num[10] - 40224 + this.num[11] + 31751 + this.num[12] * 8421 == 7433598 && this.num[0] + 28740 + this.num[1] - 64696 + this.num[2] + 60470 + this.num[3] - 14752 + (this.num[4] ^ 1287) + (this.num[5] ^ 35272) + this.num[6] + 49467 + this.num[7] - 33788 + this.num[8] + 20606 + (this.num[9] ^ 44874) + this.num[10] * 19764 + this.num[11] + 48342 + this.num[12] * 56511 == 7989404 && (this.num[0] ^ 28978) + this.num[1] + 23120 + this.num[2] + 22802 + this.num[3] * 31533 + (this.num[4] ^ 39287) + this.num[5] - 48576 + (this.num[6] ^ 28542) + this.num[7] - 43265 + this.num[8] + 22365 + this.num[9] + 61108 + this.num[10] * 2823 + this.num[11] - 30343 + this.num[12] + 14780 == 3504803 && this.num[0] * 22466 + (this.num[1] ^ 55999) + this.num[2] - 53658 + (this.num[3] ^ 47160) + (this.num[4] ^ 12511) + this.num[5] * 59807 + this.num[6] + 46242 + this.num[7] + 3052 + (this.num[8] ^ 25279) + this.num[9] + 30202 + this.num[10] * 22698 + this.num[11] + 33480 + (this.num[12] ^ 16757) == 11003580 && this.num[0] * 57492 + (this.num[1] ^ 13421) + this.num[2] - 13941 + (this.num[3] ^ 48092) + this.num[4] * 38310 + this.num[5] + 9884 + this.num[6] - 45500 + this.num[7] - 19233 + this.num[8] + 58274 + this.num[9] + 36175 + (this.num[10] ^ 18568) + this.num[11] * 49694 + (this.num[12] ^ 9473) == 25546210 && this.num[0] - 23355 + this.num[1] * 50164 + (this.num[2] ^ 34618) + this.num[3] + 52703 + this.num[4] + 36245 + this.num[5] * 46648 + (this.num[6] ^ 4858) + (this.num[7] ^ 41846) + this.num[8] * 27122 + (this.num[9] ^ 42058) + this.num[10] * 15676 + this.num[11] - 31863 + this.num[12] + 62510 == 11333836 && this.num[0] * 30523 + (this.num[1] ^ 7990) + this.num[2] + 39058 + this.num[3] * 57549 + (this.num[4] ^ 53440) + this.num[5] * 4275 + this.num[6] - 48863 + (this.num[7] ^ 55436) + (this.num[8] ^ 2624) + (this.num[9] ^ 13652) + this.num[10] + 62231 + this.num[11] + 19456 + this.num[12] - 13195 == 13863722)
{
int[] array = new int[]{132,47,180,7,216,45,68,6,39,246,124,2,243,137,58,172,53,200,99,91,83,13,171,80,108,235,179,58,176,28,216,36,11,80,39,162,97,58,236,130,123,176,24,212,56,89,72};
string text = "";
for (int i = 0; i < array.Length; i++)
{
text += ((char)(array[i] ^ this.num[i % this.num.Length])).ToString();
}
new SoundPlayer(Resources.过年鸡).Play();
MessageBox.Show(text);
}
}

z3解方程+异或,不过这个题有多解,需要自己根据flag看着限制一下z3的解 这一步真的好折磨……

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
from z3 import *

strlen=13

num=[BitVec("num[%d]"%i, 8) for i in range(strlen)]

s=Solver()

s.add(num[0] == 236)
s.add(num[2] == 213)
s.add(num[6] != 190)
s.add(num[12] != 5)
s.add(num[0] + 52296 + num[1] - 26211 + num[2] - 11754 + (num[3] ^ 41236) + num[4] * 63747 + num[5] - 52714 + num[6] - 10512 + num[7] * 12972 + num[8] + 45505 + num[9] - 21713 + num[10] - 59122 + num[11] - 12840 + (num[12] ^ 21087) == 12702282)
s.add(num[0] - 25228 + (num[1] ^ 20699) + (num[2] ^ 8158) + num[3] - 65307 + num[4] * 30701 + num[5] * 47555 + num[6] - 2557 + (num[7] ^ 49055) + num[8] - 7992 + (num[9] ^ 57465) + (num[10] ^ 57426) + num[11] + 13299 + num[12] - 50966 == 9946829)
s.add(num[0] - 64801 + num[1] - 60698 + num[2] - 40853 + num[3] - 54907 + num[4] + 29882 + (num[5] ^ 13574) + (num[6] ^ 21310) + num[7] + 47366 + num[8] + 41784 + (num[9] ^ 53690) + num[10] * 58436 + num[11] * 15590 + num[12] + 58225 == 2372055)
s.add(num[0] + 61538 + num[1] - 17121 + num[2] - 58124 + num[3] + 8186 + num[4] + 21253 + num[5] - 38524 + num[6] - 48323 + num[7] - 20556 + num[8] * 56056 + num[9] + 18568 + num[10] + 12995 + (num[11] ^ 39260) + num[12] + 25329 == 6732474)
s.add(num[0] - 42567 + num[1] - 17743 + num[2] * 47827 + num[3] - 10246 + (num[4] ^ 16284) + num[5] + 39390 + num[6] * 11803 + num[7] * 60332 + (num[8] ^ 18491) + (num[9] ^ 4795) + num[10] - 25636 + num[11] - 16780 + num[12] - 62345 == 14020739)
s.add(num[0] - 10968 + num[1] - 31780 + (num[2] ^ 31857) + num[3] - 61983 + num[4] * 31048 + num[5] * 20189 + num[6] + 12337 + num[7] * 25945 + (num[8] ^ 7064) + num[9] - 25369 + num[10] - 54893 + num[11] * 59949 + (num[12] ^ 12441) == 14434062)
s.add(num[0] + 16689 + num[1] - 10279 + num[2] - 32918 + num[3] - 57155 + num[4] * 26571 + num[5] * 15086 + (num[6] ^ 22986) + (num[7] ^ 23349) + (num[8] ^ 16381) + (num[9] ^ 23173) + num[10] - 40224 + num[11] + 31751 + num[12] * 8421 == 7433598)
s.add(num[0] + 28740 + num[1] - 64696 + num[2] + 60470 + num[3] - 14752 + (num[4] ^ 1287) + (num[5] ^ 35272) + num[6] + 49467 + num[7] - 33788 + num[8] + 20606 + (num[9] ^ 44874) + num[10] * 19764 + num[11] + 48342 + num[12] * 56511 == 7989404)
s.add((num[0] ^ 28978) + num[1] + 23120 + num[2] + 22802 + num[3] * 31533 + (num[4] ^ 39287) + num[5] - 48576 + (num[6] ^ 28542) + num[7] - 43265 + num[8] + 22365 + num[9] + 61108 + num[10] * 2823 + num[11] - 30343 + num[12] + 14780 == 3504803)
s.add(num[0] * 22466 + (num[1] ^ 55999) + num[2] - 53658 + (num[3] ^ 47160) + (num[4] ^ 12511) + num[5] * 59807 + num[6] + 46242 + num[7] + 3052 + (num[8] ^ 25279) + num[9] + 30202 + num[10] * 22698 + num[11] + 33480 + (num[12] ^ 16757) == 11003580)
s.add(num[0] * 57492 + (num[1] ^ 13421) + num[2] - 13941 + (num[3] ^ 48092) + num[4] * 38310 + num[5] + 9884 + num[6] - 45500 + num[7] - 19233 + num[8] + 58274 + num[9] + 36175 + (num[10] ^ 18568) + num[11] * 49694 + (num[12] ^ 9473) == 25546210)
s.add(num[0] - 23355 + num[1] * 50164 + (num[2] ^ 34618) + num[3] + 52703 + num[4] + 36245 + num[5] * 46648 + (num[6] ^ 4858) + (num[7] ^ 41846) + num[8] * 27122 + (num[9] ^ 42058) + num[10] * 15676 + num[11] - 31863 + num[12] + 62510 == 11333836)
s.add(num[0] * 30523 + (num[1] ^ 7990) + num[2] + 39058 + num[3] * 57549 + (num[4] ^ 53440) + num[5] * 4275 + num[6] - 48863 + (num[7] ^ 55436) + (num[8] ^ 2624) + (num[9] ^ 13652) + num[10] + 62231 + num[11] + 19456 + num[12] - 13195 == 13863722)


if s.check()==sat:
m=s.model()
print(m)

最终异或得flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
num = [0]*13
num[10] = 15
num[9] = 199
num[4] = 189
num[6] = 62
num[3] = 106
num[8] = 120
num[1] = 72
num[7] = 53
num[11] = 93
num[12] = 133
num[5] = 86
num[2] = 213
num[0] = 236

x = [132,47,180,7,216,45,68,6,39,246,124,2,243,137,58,172,53,200,99,91,83,13,171,80,108,235,179,58,176,28,216,36,11,80,39,162,97,58,236,130,123,176,24,212,56,89,72]
for i in range(len(x)):
print(chr(x[i]^num[i%len(num)]),end='')
#hgame{z3_1s_very_u5eful_1n_rever5e_engin3ering}

patchme

好折磨。。。最开始搜到系统调用就直接开始改,用的int 0x80,后来才发现那是32位的系统调用,64位要用syscall…… 对不起我是傻子
然后参数长度刚开始看的栈上是0x20(别问我咋看的,我也不知道),后来输入输出都没问题,确信是参数长度有问题,才看IDA的伪代码长度是24……

漏洞存在于主函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
__int64 __fastcall sub_13E8(int a1, __int64 a2)
{
__int64 v2; // rbp
char v4[24]; // [rsp-28h] [rbp-30h] BYREF
unsigned __int64 v5; // [rsp-10h] [rbp-18h]
__int64 v6; // [rsp-8h] [rbp-10h]

v6 = v2;
v5 = __readfsqword(0x28u);
dword_4028 = a1;
qword_4020 = a2;
gets(v4);
printf(v4);
return 0LL;
}

gets读取的输入长度无限制,可以通过gets布置payload以达到控制程序流程的目的,而printf存在格式化字符串漏洞。所以这里主要修复这两个函数。
可以将gets改为系统调用sys_read,printf改成系统调用sys_write,系统调用参数查询系统调用约定

1
2
3
4
5
6
7
8
.text:000000000000141F                 lea     rax, [rbp-20h]
.text:0000000000001423 mov rdi, rax
.text:0000000000001426 mov eax, 0
.text:000000000000142B call _gets
.text:0000000000001430 lea rax, [rbp-20h]
.text:0000000000001434 mov rdi, rax ; format
.text:0000000000001437 mov eax, 0
.text:000000000000143C call _printf

改成

1
2
3
4
5
6
7
8
9
10
11
12
13
.text:000000000000141F                 lea     rsi, [rbp-20h]  ; buf
.text:0000000000001423 xor rdi, rdi ; fd
.text:0000000000001426 nop
.text:0000000000001427 nop
.text:0000000000001428 nop
.text:0000000000001429 nop
.text:000000000000142A xor rax, rax
.text:000000000000142D mov rdx, 18h ; count
.text:0000000000001434 syscall ; LINUX - sys_read
.text:0000000000001436 xor rax, rax
.text:0000000000001439 inc rax
.text:000000000000143C inc rdi ; fd
.text:000000000000143F syscall

(我为了省地方,清零都用的xor)
保存运行,随便输点啥即可
hgame{You_4re_a_p@tch_master_0r_reverse_ma5ter}

cpp

究极折磨的题……调N年看不懂在干什么,后来发现应该是单字节加密,遂爆破

由于本人菜得不会hook库函数,遂决定patch输出爆破。具体而言就是把输出字符串patch成加密后的密文,和程序里原有的密文对比,对比正确的长度多一位则说明这一位正确。密文很好找,在sub_140003080。
关于具体怎么patch,先去找memcmp函数,也就是最终密文和输入加密后的密文对比的地方,固定基址之后在sub_140007D70。去看这个函数的汇编,调用memcmp前,我们需要的指针在rdx里,那么想办法保留rdx的值,我选择把它暂存在r15里,等到最后调用输出的时候直接用r15覆盖rdx即可。

具体而言就是改成下面这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
.text:0000000140007D9C 48 89 C2                                mov     rdx, rax        
.text:0000000140007D9F 90 nop
.text:0000000140007DA0 90 nop
.text:0000000140007DA1 48 8B 44 24 20 mov rax, [rsp+48h+Buf1]
.text:0000000140007DA6 48 8B 4C 24 28 mov rcx, [rsp+48h+var_20]
.text:0000000140007DAB 48 2B C8 sub rcx, rax
.text:0000000140007DAE 48 8B C1 mov rax, rcx
.text:0000000140007DB1 4C 8B C0 mov r8, rax ; Size
.text:0000000140007DB4 49 89 D7 mov r15, rdx ; Buf2
.text:0000000140007DB7 90 nop
.text:0000000140007DB8 90 nop

...

.text:000000014000334A 4C 89 FA mov rdx, r15 ; Keypatch modified
.text:000000014000334D 90 nop
.text:000000014000334E 90 nop
.text:000000014000334F 90 nop
.text:0000000140003350 90 nop
.text:0000000140003351 48 8B 0D B0 6D 00 00 mov rcx, cs:?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::ostream std::cout
.text:0000000140003358 E8 13 12 00 00 call sub_140004570

写交互脚本爆破:

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
import subprocess
flag = 'hgame{'
enc = [0x28,0x50,0xC1,0x23,0x98,0xA1,0x41,0x36,0x4C,0x31,0xCB,0x52,0x90,0xF1,0xAC,0xCC,0xF,0x6C,0x2A,0x89,0x7F,0xDF,0x11,0x84,0x7F,0xE6,0xA2,0xE0,0x59,0xC7,0xC5,0x46,0x5D,0x29,0x38,0x93,0xED,0x15,0x7A,0xFF]

def cmp(s1,s2):
for i in range(40):
try:
if s1[i]!=s2[i]:
return i
except:
return i
len = 6
for i in range(33):
for j in range(0x20,0x80):
p = subprocess.Popen(["week3-cpp.exe"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
tmp = flag + chr(j)*(33-i)+'}'
p.stdin.write(tmp.encode())
p.stdin.close()
out = p.stdout.read()[:40]
p.stdout.close()
if cmp(out, enc)>len:
flag += chr(j)
len += 1
print(flag)
break
if b'yes' in out:
print(tmp)
exit()
#hgame{Cpp_1s_much_m0r3_dlff1cult_th4n_C}

week4

好像很麻烦,经典go+vm,懒得写了,就这样吧……

关于本文

本文作者 云之君, 许可由 CC BY-NC 4.0.