upx2023
知识点:爆破时间seed,一种简单的映射应对方法,upx标志修改
第一步 脱upx壳
这道题脱壳只需要把exe拖到010里把upx标志由小写改成大写即可。
第二步 程序解读
输入
change
异或比较
第三步 逆向获得flag
std::operator<<<std::char_traits<char>>(&std::cout, Str);
std::operator>><char>(&std::cin, v7);
std::string::string(v9, v7);
change(v8, v9);
std::string::operator=(v7, v8);
std::string::~string(v8);
std::string::~string(v9);
std::string::operator 赋值
if ( std::string::length(v7) != 42 )
{
v3 = std::operator<<<std::char_traits<char>>(&std::cout, "len error");
长度42
for ( i = 0; i <= 41; ++i )
{
v10 = rand() % 255;
v4 = std::string::operator[](v7, i);
if ( (v10 ^ *v4) != v6[i] )
exit(0);
rand爆破解决
Seed = time(0i64);
srand(Seed);
应该是一个时间戳随机数 我们结合pe文件的时间直接爆破伪随机
Timestamp : 647AA837 (Sat Jun 03 02:40:55 2023)
结合
.rdata:000000000047F008 69 6E 70 75 74 20 79 6F 75 72+Str db 'input your flag' ; DATA XREF: main+41↑o
.rdata:000000000047F017 A3 db 0A3h
.rdata:000000000047F018 A8 db 0A8h
.rdata:000000000047F019 D3 db 0D3h
.rdata:000000000047F01A C3 db 0C3h
.rdata:000000000047F01B 66 db 66h ; f
.rdata:000000000047F01C 6C db 6Ch ; l
.rdata:000000000047F01D 61 db 61h ; a
.rdata:000000000047F01E 67 db 67h ; g
.rdata:000000000047F01F 7B db 7Bh ; {
.rdata:000000000047F020 7D db 7Dh ; }
.rdata:000000000047F021 B0 db 0B0h
.rdata:000000000047F022 FC db 0FCh
.rdata:000000000047F023 B9 db 0B9h
.rdata:000000000047F024 FC db 0FCh
.rdata:000000000047F025 A3 db 0A3h
.rdata:000000000047F026 A9 db 0A9h
.rdata:000000000047F027 3A db 3Ah ; :
.rdata:000000000047F028 20 db 20h
.rdata:000000000047F029 00 db 0
对flag{}进行爆破即可
exp如下
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(){
unsigned int seed;
int key=0;
int i =0;
//1662973302 # 正确的seed
for(seed = 1662973302;seed<1705929558;seed++){
srand(seed);
int right = 1;
for(i=0;i<=32;i++){
key = rand() % 255;
switch (i) {
case 0:
if(key!=0x6f){
right = 0;
}
break;
case 1:
if(key!=0x18){
right = 0;
}
break;
case 11:
if(key!=0xaa){
right = 0;
}
break;
case 12:
if(key!=0x2){
right = 0;
}
break;
case 32:
if(key!=0x9b){
right = 0;
}
break;
default:
break;
}
if(right == 0){
break;
}
}
if(right==1){
printf("%un",seed);
}
}
return 0;
}
结果:1682145110n
异或对比key直接取
0x09, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0xD9, 0x00, 0x00, 0x00, 0xF6, 0x00, 0x00, 0x00,
0x58, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x4C, 0x00, 0x00, 0x00,
0x0F, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0xC6, 0x00, 0x00, 0x00,
0x65, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0xED, 0x00, 0x00, 0x00,
0xC4, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x7B, 0x00, 0x00, 0x00,
0xE5, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x5D, 0x00, 0x00, 0x00, 0xA9, 0x00, 0x00, 0x00,
0x31, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0xD7, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00,
0x6C, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x00, 0x00,
0xFA, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0xDB, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00,
0xCD, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00,
0x13,0x00,0x00,0x00,0x08
EXP如下
unsigned char data[42] = {
0x09, 0x63, 0xD9, 0xF6, 0x58, 0xDD, 0x3F, 0x4C, 0x0F, 0x0B, 0x98, 0xC6, 0x65, 0x21, 0x41, 0xED,
0xC4, 0x0B, 0x3A, 0x7B, 0xE5, 0x75, 0x5D, 0xA9, 0x31, 0x41, 0xD7, 0x52, 0x6C, 0x0A, 0xFA, 0xFD,
0xFA, 0x84, 0xDB, 0x89, 0xCD, 0x7E, 0x27, 0x85, 0x13, 0x08
};#这个就是上面直接拿的
srand(1682145110);
for (int i = 0; i < 42; i++) {
c = rand() % 255;
printf("%c", data[i] ^ c);
}
//f{52bgb-281lg00ff-46f7-ca009c8e}a381-b7191
映射动调解决
假设一个char:flag{1234567890qwertyuiopAsdFGhjkLzxcvbnm}
动调结果:
得到映射关系
根据映射关系得到输入的flag
f{48wypFkcmlg13579qetuoAdGjLxvn}a260rishzb
exp如下
映射
a = 'flag{1234567890qwertyuiopAsdFGhjkLzxcvbnm}'
b = 'f{48wypFkcmlg13579qetuoAdGjLxvn}a260rishzb'
input_set = []
for i in b:
input_set.append(a.index(i))
print(input_set) # 得到换位的顺序
末初大佬队的exp更简便:
#include <stdio.h>
int main(){
char res[] = "f{52bgb-281lg00ff-46f7-ca009c8e}a381-b7191";
char s1[] = "flag{1234567890QWERTYUIOPASDFGHJKLZXCVBNM}";
char r1[] = "f{48WYPFKCMlg13579QETUOADGJLXVN}a260RISHZB";
for (int i = 0; i < 42; i++) {
for (int j = 0; j < 42; j++) {
if (s1[i] == r1[j]) {
printf("%c", res[j]);
}
}
}
}
flag{0305f8f2-14b6-fg7b-bc7a-010299c881e1}
动调演示视频
flag{1234567890qwertyuiopAsdFGhjkLzxcvbnm}