当前位置:网站首页>[buuctf.reverse] 126-130
[buuctf.reverse] 126-130
2022-06-26 17:26:00 【Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi】
Catalog
126_[NPUCTF2020]EzObfus-Chapter2
126_[NPUCTF2020]EzObfus-Chapter2
The program first processes each character entered sub_41644A()( Character by character ) Then do a character by character bit processing , And then compare them , This is consistent with the characteristics of blasting
int __cdecl main(int argc, const char **argv, const char **envp)
{
int j; // [esp+18h] [ebp-10h]
int i; // [esp+1Ch] [ebp-Ch]
sub_416F80();
puts("Give Me Your Flag:\n");
scanf("%s", &Str);
if ( strlen(&Str) == 22 )
{
sub_41644A(); // str:0x426020 Nested functions are right (22 Characters +i)^i 13-14 With the exception of
for ( i = 1; i <= 21; ++i )
{
*(&Str + i) += (dword_424080[i % 6] >> 6) ^ (16 * dword_424080[(i - 1) % 6]);
*(&Str + i) = ((int)(unsigned __int8)*(&Str + i) >> 3) | (32 * *(&Str + i));
}
for ( j = 0; j <= 21; ++j )
{
if ( *(&Str + j) != byte_424040[j] )
goto LABEL_2;
}
puts("Good Job!\n");
}
else
{
LABEL_2:
puts("Error!\n");
}
return 0;
}
here sub_41644A() Extremely complex , Someone on the Internet guessed that it is to add serial number and then XOR serial number , But not exactly . However, it is certain that only one character is processed at a time without involving other characters , This can be exploded , First use program patch Compare the digits , Copy program bit by bit
data = list(open('attachment.exe', 'rb').read())
for i in range(22):
data[0x15a06] = i
filename = f"aaa{i}.exe"
open(filename, 'wb').write(bytes(data))
And then blow it up bit by bit
flag = ''
for i in range(1):
filename = f".\\aaa{i}.exe"
p = subprocess.Popen('.\\aaa0.exe', stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
print('pid', p.pid)
print('s', p.stdout.readline())
for j in range(0x21, 0x7f):
tmp = ((flag+chr(j)).ljust(22,'A')+'\n').encode()
print('tmp:', tmp)
p.stdin.write(tmp)
p.stdin.flush()
out = p.stdout.readline()
print("A:",out)
if b'Error' not in out:
flag += chr(j)
print(flag)
break
#npuctf{WDNMD_LJ_OBFU!}
127_[SUCTF2019]Akira Homework
128_[GKCTF 2021]app-debug
This is a apk file , First use jd Open to find Resources/AndroidManifest.xml Look inside <activity android:name="com.example.myapplication.MainActivity"> This is the starting point
Find... Here flag packaging
public class MainActivity extends AppCompatActivity {
......
protected void onCreate(Bundle savedInstanceState) {
......
this.mBtnLogin.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
MainActivity mainActivity = MainActivity.this;
if (mainActivity.check(mainActivity.mEtflag.getText().toString())) { // Call check
Toast.makeText(MainActivity.this, "You Are Right!flag is flag{md5(input)}", 0).show(); //flag Assembly method
} else {
Toast.makeText(MainActivity.this, "Sorry your flag is wrong!", 0).show();
}
}
});
}
}
I check the function , This function is in the lib in lib\arm64-v8a\libnative-lib.so
use IDA Open to find the corresponding function
bool __fastcall Java_com_example_myapplication_MainActivity_check(__int64 a1, __int64 a2, __int64 a3)
{
...
if ( sub_40040((__int64)v6) == 7 )
{
for ( i = 0; i <= 6; ++i )
byte_C80E0[i] = *(_BYTE *)sub_40064((__int64)v6, i);
v5 = sub_3ED8C((unsigned int *)byte_C80E0); // Encryption function
}
}
bool __fastcall sub_3ED8C(unsigned int *a1)
{
...
v5 = *a1;
v4 = a1[1];
v3 = 0;
for ( i = 0; i < 0x20; ++i )
{
v3 += dword_C8010;
v5 += (16 * v4 + dword_C8000) ^ (v4 + v3) ^ ((v4 >> 5) + dword_C8004);
v4 += (16 * v5 + dword_C8008) ^ (v5 + v3) ^ ((v5 >> 5) + dword_C800C);
}
*a1 = v5;
a1[1] = v4;
return *a1 == 0xF5A98FF3 && a1[1] == 0xA21873A3;
After processing, it is found that the operation is incorrect . It turns out that the opposite tone is also used here , stay .init_array There are functions
.init_array:00000000000C0F98 3C EF 03 00 00 00 00 00 off_C0F98 DCQ sub_3EF3C
Function on several key Changes have been made
__int64 sub_3EF3C()
{......
if ( !strcmp(s1, "0") )
sub_3EF18();
}
void sub_3EF18()
{
dword_C8004 = 7;
dword_C8008 = 8;
dword_C800C = 6;
}
According to the new key Write a program
c8010 = 0x458BCD42
c8000 = 9
c8004 = 7
c8008 = 8
c800c = 6
v3 = c8010 *0x20
v5 = 0xF5A98FF3
v4 = 0xA21873A3
for i in range(0x1f,-1,-1):
v4 -= (16 * v5 + c8008) ^ ( v5 + v3) ^ ((v5 >> 5) + c800c)
v4 &= 0xffffffff
v5 -= (16 * v4 + c8000) ^ ( v4 + v3) ^ ((v4 >> 5) + c8004)
v5 &= 0xffffffff
v3 -= c8010
v3 &= 0xffffffff
print(v5, v4,v3)
print(bytes.fromhex(hex(v5)[2:])[::-1]+bytes.fromhex(hex(v4)[2:])[::-1])
#GKcTFg0
m = b'GKcTFg0'
from hashlib import md5
print(md5(m).digest().hex())
#flag{77bca47fe645ca1bd1ac93733171c9c4}
129_[FlareOn2]YUSoMeta
Open the discovery is .net The program , use dnSpy Open and find confusion , use de4dot With the , Open one more , find main,
string text = Console.ReadLine().Trim(); // Read the entered password
string b = Class3.smethod_0(class1_, byte_2) + '_' + Class3.smethod_3();
if (text == b)
{
Console.WriteLine(Encoding.ASCII.GetString(bytes4)); //Thank you for providing the correct password.
Console.Write(Encoding.ASCII.GetString(bytes5)); //Use the following email address to proceed to the next challenge:
Console.WriteLine(Class3.smethod_1(text, byte_));
return;
}
Go back to the original program , At this point of comparison, the breakpoint , And then execute
After the breakpoint is reached, you can see the compared data
metaprogrammingisherd_DD9BE1704C690FB422F1509A46ABC988
Run the program and enter the password to get flag
C:\buuctf.reverse\129_[FlareOn2]YUSoMeta>YUSoMeta
Warning! This program is 100% tamper-proof!
Please enter the correct password: metaprogrammingisherd_DD9BE1704C690FB422F1509A46ABC988
Thank you for providing the correct password.
Use the following email address to proceed to the next challenge: [email protected]
#flag{[email protected]}
130_[GXYCTF2019]minecraft
ida After opening it, I found that what it handles is in the function String_t0_intDll in , open dll file ( Function in dll In file ), Open the main encryption logic
_BOOL8 __fastcall String_to_long(__int64 a1)
{
void *v2; // rax
char v3; // [rsp+30h] [rbp-138h]
int j; // [rsp+34h] [rbp-134h]
int v5; // [rsp+38h] [rbp-130h]
int i; // [rsp+3Ch] [rbp-12Ch]
_QWORD *v7; // [rsp+48h] [rbp-120h]
__int64 v8; // [rsp+50h] [rbp-118h]
_QWORD *v9; // [rsp+58h] [rbp-110h]
int v10[8]; // [rsp+60h] [rbp-108h]
char *v11; // [rsp+80h] [rbp-E8h]
const struct std::_Container_base0 *v12; // [rsp+88h] [rbp-E0h]
__int64 v13; // [rsp+90h] [rbp-D8h]
__int64 v14; // [rsp+98h] [rbp-D0h]
char *v15; // [rsp+A0h] [rbp-C8h]
const struct std::_Container_base0 *v16; // [rsp+A8h] [rbp-C0h]
char v17[32]; // [rsp+B0h] [rbp-B8h] BYREF
char v18[32]; // [rsp+D0h] [rbp-98h] BYREF
char v19[32]; // [rsp+F0h] [rbp-78h] BYREF
char v20[32]; // [rsp+110h] [rbp-58h] BYREF
char v21[32]; // [rsp+130h] [rbp-38h] BYREF
v7 = operator new(0x128ui64);
if ( v7 )
{
*v7 = 9i64;
`eh vector constructor iterator'(v7 + 1, 0x20ui64, 9ui64, sub_180003C90, (void (__stdcall *)(void *))sub_180003AF0);
v9 = v7 + 1;
}
else
{
v9 = 0i64;
}
sub_180003C90(v20);
v11 = v18;
v12 = sub_180003CE0((const struct std::_Container_base0 *)v18, a1);
v8 = sub_1800033E0(v12); // base64
if ( (unsigned __int64)unknown_libname_105(a1) >= 0xA )
{
sub_180003A60((__int64)v20, v8);
v5 = 0;
for ( i = 0; ; ++i )
{
v13 = v5;
if ( v5 >= (unsigned __int64)unknown_libname_105(v20) )
break;
v14 = sub_180003900(v20, v17, v5, 4i64);
sub_180003B20(&v9[4 * i], v14);
((void (__stdcall *)(void *))sub_180003AF0)(v17);
sub_1800039E0(&v9[4 * i], &unk_180034570);
v5 += 4; // Every time 4 In groups
}
sub_180003C90(v21);
for ( j = 0; j < 8; ++j )
{
sub_180003A90(v21, &v9[4 * j]);
v15 = v19;
v16 = sub_180003CE0((const struct std::_Container_base0 *)v19, (__int64)v21);
v10[j] = sub_180003390(v16); // hash
}
v3 = 0;
v2 = (void *)sub_180004B90(&qword_18003A200, "-------Checking-----");
_CallMemberFunction0(v2, sub_180004F60);
if ( v10[0] == 0x6C43B2A7
&& v10[1] == 0x7954FD91
&& v10[2] == 0xA3E9532
&& v10[3] == 0xB87B5156
&& v10[4] == 0xDA847742
&& v10[5] == 0x2395E7F3
&& v10[6] == 0xA679D954
&& v10[7] == 0xE1FAAFF7 )
{
v3 = 1;
}
sub_180003310(v9, v8);
((void (__stdcall *)(void *))sub_180003AF0)(v21);
((void (__stdcall *)(void *))sub_180003AF0)(v20);
return v3 != 0;
}
else
{
((void (__stdcall *)(void *))sub_180003AF0)(v20);
return 0i64;
}
}
First, base64 Every time 4 Make a custom one by one hash Compare again ,hash It's deeper
__int64 __fastcall sub_180003390(void *a1)
{
unsigned int v2; // [rsp+20h] [rbp-18h]
char v3[4]; // [rsp+24h] [rbp-14h] BYREF
v2 = unknown_libname_104(v3, a1); // hash
sub_180003AF0(a1);
return v2;
}
// Microsoft VisualC 64bit universal runtime
__int64 __fastcall unknown_libname_104(__int64 a1, __int64 a2)
{
return sub_180004B40(a2); // call hash
}
__int64 __fastcall sub_180004B40(__int64 a1)
{
__int64 *v1; // rax
__int64 *v3; // [rsp+20h] [rbp-28h]
char v4[8]; // [rsp+28h] [rbp-20h] BYREF
char v5[24]; // [rsp+30h] [rbp-18h] BYREF
v3 = (__int64 *)sub_1800059D0(a1, v4);
v1 = (__int64 *)sub_180005A30(a1, v5);
return sub_180005FB0(*v1, *v3); // call hash
}
__int64 __fastcall sub_180005FB0(__int64 a1, __int64 a2)
{
unsigned __int8 *v2; // rax
__int64 v4; // [rsp+20h] [rbp-18h] BYREF
__int64 v5; // [rsp+40h] [rbp+8h] BYREF
__int64 v6; // [rsp+48h] [rbp+10h] BYREF
v6 = a2;
v5 = a1;
v4 = 0i64;
while ( (unsigned __int8)sub_180006100(&v5, &v6) )
{
v2 = (unsigned __int8 *)unknown_libname_107(&v5);
sub_180006200(&v4, v2); // call hash
std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>>::operator++(&v5);
}
return v4;
}
__int64 __fastcall sub_180006200(__int64 *a1, unsigned __int8 *a2)
{
__int64 v2; // rax
char v4[8]; // [rsp+20h] [rbp-18h] BYREF
v2 = sub_180002E00(v4, *a2);
return hash_180002D30(a1, v2);
}
__int64 __fastcall sub_180002D30(__int64 *a1, __int64 a2)
{
__int64 result; // rax
*a1 ^= 0xC6A4A7935BD1E995ui64 * (((0xC6A4A7935BD1E995ui64 * a2) >> 47) ^ (0xC6A4A7935BD1E995ui64 * a2));
*a1 *= 0xC6A4A7935BD1E995ui64;
result = *a1 + 0xE6546B64i64;
*a1 = result;
return result;
}
Then according to this every 3 Blast in groups of characters
from itertools import product
import string
from base64 import b64encode
c = [0x6C43B2A7,0x7954FD91,0xA3E9532,0xB87B5156,0xDA847742,0x2395E7F3,0xA679D954,0xE1FAAFF7]
'''
String_t0_intDll.dll sub_180002D30
*a1 ^= 0xC6A4A7935BD1E995ui64 * (((0xC6A4A7935BD1E995ui64 * a2) >> 47) ^ (0xC6A4A7935BD1E995ui64 * a2));
*a1 *= 0xC6A4A7935BD1E995ui64;
result = *a1 + 0xE6546B64i64;
*a1 = result;
'''
def hash(v):
n = b64encode(''.join(v).encode())
delta = 0xC6A4A7935BD1E995
ret = 0
for i in range(4):
ret ^= delta * ((((delta * n[i])&0xffffffffffffffff)>>47) ^ (delta * n[i]))
ret *= delta
ret += 0xE6546B64
return ret&0xffffffff
chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ{}_-!?'
flag = ['']*8
def bp():
for v in product(chars, repeat=3): #
m = hash(v)
if m in c:
flag[c.index(m)]= ''.join(v)
print(c.index(m), v)
bp()
print(''.join(flag))
#GXY{I_have_no_gir1_frieN
#flag{I_have_no_gir1_frieNd}
边栏推荐
- 【推荐系统学习】推荐系统的技术栈
- Platform management background and merchant menu resource management: Design of platform management background data service
- 【万字总结】以终为始,详细分析高考志愿该怎么填
- Quantitative contract system development analysis case - detailed explanation of contract quantitative system development scheme
- 分布式架构概述
- Platform management background and merchant menu resource management: merchant registration management design
- When I was in the library, I thought of the yuan sharing mode
- Daily record 2
- Cache breakdown! Don't even know how to write code???
- mysql Add column 失败 因为之前有数据,不是默认null 不行
猜你喜欢
MySQL exports all table indexes in the database
SQL injection for Web Security (3)
Halcon's region: features of multiple regions (5)
Web3 decentralized storage ecological landscape
[recommendation system learning] technology stack of recommendation system
[ten thousand words summary] starting from the end, analyze in detail how to fill in the college entrance examination volunteers
Rich professional product lines, and Jiangling Ford Lingrui · Jijing version is listed
ACL 2022 | 基于神经标签搜索的零样本多语言抽取式文本摘要
牛客网:设计LRU缓存结构 设计LFU缓存结构
Basic requirements: 7 problems in singleton mode
随机推荐
Find all primes less than or equal to Lim, store them in AA array, and return the number of primes
MySql 导出数据库中的全部表索引
Microservice architecture practice: business management background and SSO design: SSO design
Treasure and niche CTA animation material website sharing
防火 疏散 自救…这场安全生产暨消防培训干货满满!
Viteconfigure project path alias
Kubernetes essential tools: 2021
[recommendation system learning] recommendation system architecture
Niuke network: Design LRU cache structure design LFU cache structure
[qt learning notes]qt inter thread data communication and data sharing
Implementation of MySQL master-slave architecture
Army chat -- registration of Registration Center
Uncover the secret of Agora lipsync Technology: driving portraits to simulate human speech through real-time voice
Fire evacuation and self rescue... This safety production and fire training is full!
SQL injection for Web Security (3)
What does the equals method compare? Who told you
20:第三章:开发通行证服务:3:在程序中,打通redis服务器;(仅仅是打通redis服务器,不涉及具体的业务开发)
Find out the maximum value of each column element of NxN matrix and store it in the one-dimensional array indicated by formal parameter B in order
Jouer avec Linux et installer et configurer MySQL facilement
Discover K8E: minimalist kubernetes distribution