rev/questionably-distributed
1
|
Distributed computing is the new tech on the horizon, so I decided to distribute the computer itself. Enjoy this horrendous simulation of a CPU running locally over TCP.
|
The attachment is a x64 executable file.

When you run the chal.exe, it appears following behavior:
-
Determine the following condition in sub_140002256()
- If argument a1 == 1 then enter main server mode
- If argument a1 == 2 then enter sub server mode
-
This are the following behavior that when the program enter main server mode. First, start several subprocesses chall.exe and pass arguments 5555,6666,7777 respectively
1
2
3
4
5
6
|
$ chal.exe
$ tasklist | findstr chal
chal.exe 66444 Console 9 3,432 K
chal.exe 5620 Console 9 3,432 K
chal.exe 28684 Console 9 3,432 K
|
-
Then, build connection with three TCP port.
1
2
3
|
mov [rbp+290h+var_14], eax
add [rbp+290h+var_8], 1
jmp loc_14000230E
|
-
After that, Sleep(500)
-
Enter a double for-loop
- Send coordinate to port 5555
1
2
3
|
sprintf(Str, "%d %d", k, m);
v3 = strlen(Str);
send(s, Str, v3 + 1, 0);
|
- Receive the result from port 6666
1
|
recv(s, &Command, 256, 0);
|
- And the result value is sent to port 7777 and execute
v40 ^ 66
1
2
3
4
|
sscanf(&Command, "%d", &v40);
sprintf(Str, "%d %d ^", v40, 66);
v4 = strlen(Str);
send(v43, Str, v4 + 1, 0);
|
- Receive the result from port 6666 and add
v40 by 1 and send it to port 7777
1
2
3
4
5
|
recv(v43, &Command, 256, 0);
sscanf(&Command, "%d", &v40);
sprintf(Str, "%d %d +", v40, 15);
v5 = strlen(Str);
send(v43, Str, v5 + 1, 0);
|
- Finally receive the result from port 7777 and pass to
v40
1
2
|
recv(v43, &Command, 256, 0);
sscanf(&Command, "%d", &v40);
|
- Et cetera
For the a1 == 2 sub server mode
- Parse the port number passed in
a2
- If 5555 then start byte matrix service at
sub_140001687
- If 6666 then start arithmetic operation service
sub_140001A42
- If 7777 then start comparison operation service
sub_140001E45
- Otherwise, return an error
Logic of sub services
-
sub_140001687 (Comparison Operation Service)
-
Port: 5555
-
Receive: "<a> <b> <op_code>"
-
Remark: opcode only accept "<", ">", "="
-
Return: the boolean of comparison
-
sub_140001A42 (Arithmetic Operation Service)
- Port: 6666
- Receive:
"<a> <b> <op_code>"
- Remark:
opcode only accept "+", "-", "^"
- Return: the result of arithmetic operation
-
sub_140001687 (Byte Matrix Service)
- Port: 5555
- Receive:
"<x> <y>"
- Remark: which x and y are integer coordinate
- Return:
byte_140010020[28 * x + y]
Solve
So, we our aim is to extract the data from byte_140010020 to restore the algorithm.
the final transformation is result[k][m] = ( M[k][m] ^ 66 ) + 15
solve script:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
def transform_matrix(data_bytes):
matrix = [[0] * 28 for _ in range(28)]
for k in range(28):
for m in range(28):
val = data_bytes[28 * k + m]
matrix[k][m] = (val ^ 66) + 15
return matrix
def print_matrix_as_ascii(matrix):
for row in matrix:
line = ''.join(chr(x) if 32 <= x <= 126 else '.' for x in row)
print(line)
if __name__ == "__main__":
raw_data = bytes.fromhex('64429F81C37D3C077610F19F68E00B8785820CC794A484BF3497C11A09607A00BA1A817D97BD840ECD75AD3656B8BDDB3BCAA2CF6E278FA2BE501DC7C837C782514800E90684F7D3FAA409505CC72B9791CD67FFF4F6A11A465E7A0E964190E78A90D09015C7630F6B6D5FC8348A5FC557C6C44C1F65FE02C478105ABAA141443112D446D9375545A4B40DD83E6C9D963366E2EFC7E0F28B5902E513A32657D5382B1B12627157072564DF64D07D1203DEDCF3A5BCE53015E715288B3C7F6074AA7B860DECDD141241F376677070154F4C08F408ED251ED53A466076C6C0EB703B717D284F913A9003B0A2F520B8446CC03974AE5E928398D9E30F9FA3FA0FDE6B8D06BA1E034BA3F0ED9910A5DD7C6616F1147483970D5C7A1CFB1D160BFB81980212B642875A3374F3431AD0C080E7B1945B342B6891A5848CC29A97BD1C1CBF58E602DF40355333786D0338EDEAE981461EACAEAF51333B13CDD324E9029041E8922028C7745B40E15F78CF4962508F80FD3E2F4E716A621F3D332840C36928568A511DFEAC5DDF0BD6AE5538FFE4B8FC22E74A936AACD28FDFFACFA363F7F9ED4816EBF574CB004A795582783A3A745C2160F0726BC2014BBCD0EE1FC8E70D10FDF80571C306BB3D5B3DB595772A2398E9E20B54A40C9F60DD8D7FA5748CB57285BBE348C19F851CDC3BB21F65A4EC4E86F7A22A04428AE1CF098644963BB61BF69963B738E9D415668669892A55D7B04D79DA51BB64328B6DB8CF03F3851EEA1E82A1576B126C8FFBD518252AEFD57768AFC82413FAAF81B27E84A603A3902125316490A7E41FA2B937C8E4269D5B8E4D24B2601E61E1D1DF6677E209070466387CBEDF61DD821A144AFE3AE75AC8347E7B959CDC766DBCDCE49EE521A213241FD10380AE859AC2CF99FCB7F3C5EB7140800D1CF77BD8D35F25B94B19CC6F389E72B84CF8530FC7EC0B7EDFD06A5010EA5D2DE1D80560387C6E83963AF2CED86487255CDA3424C63FA2A5100CF520F7524DD816538D63CFFBE66536D8340E3CBB33999567BD5BA75F00B76CF5D76347663B7278C9D547C4BBADFA93E109D09C3C6931A4268C4B858C02F181D964')
matrix = transform_matrix(raw_data)
print_matrix_as_ascii(matrix)
|
Result:
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
|
5....N.TCa..9.X...]........g
Z1GQ.g.N...[.F..#.......;t..
.!n.....".Q.S.....Z!-.x...4.
...g.+G[........f.0\8>,...,.
$...l6.O.Ia'....._....&...^.
.=...3......*O.`.s$..xh_/B$T
v5.5.N_P.......f.fy..L1E.H.^
..e_..C4AAf..Y.Y.vk...1C...A
.BNy....P...q..=..E.+.....\.
..\.8.S.kP.....a..M3c.eE..^-
Gm.ncX...O_...'.E..g......(.
x9........mm.).O... .I>P....
..k..."..`..u.O....qy.E(..,I
../!....|.B7/l..y..:y#."n...
.X..&.....o...7.......0....c
..E.Q.J&.I..E-r1.?8.R....l..
^a..VB.S..(...Dwp...X%.].1..
L.E..?.......m...l6......wU.
...Z.....h..0....f3.:.w&...J
.".5..>..P..k.k..$8_=...ivw.
.D9..u`....K..P..rv.5...l...
..s.(..u.1k2...3D.ZTU3.M..2.
.ge....'..KH...C>.....r.`ul.
P............B..^m.H..,v..j.
<..?... \..XK..7!a..~..V1.M;
......5.v-..u....a].q....c .
0...6...[.....4.(.,Q.=..0.3.
?I.........Z...:..s....O...5
|
You can find suspicious strings on the diagonal lines
51ngl3_4PP_mul71pl3_53rv1c35