杂类

2019 上海“嘉韦思杯”逆向 writeup

https://ws3.sinaimg.cn/large/005BYqpggy1g1lwdiva4dj30jv08q40c.jpg
### obfuse

32位ELF文件,无壳,载入中通过关键字符串查找关键代码
![]()
但是发现f5不好使,只能看汇编,首先输出“password:”,然后再从缓存区读取一串字符串,进入到sub\_8048580进行验证,若返回0,则输入的是错误的,若返回1则输入的是正确的
![]()

在sub\_8048580函数中是一位一位的check
```
_BOOL4 __cdecl sub_8048580(int a1, signed int a2)
{
signed int v2; // edx
char v3; // al
_BOOL4 result; // eax
char v5[33]; // [esp+Ch] [ebp-A0h]
char b20_1; // [esp+2Dh] [ebp-7Fh]
char b1f_1; // [esp+2Eh] [ebp-7Eh]
char b1e_1; // [esp+30h] [ebp-7Ch]
char b1d_1; // [esp+31h] [ebp-7Bh]
char b1c_1; // [esp+32h] [ebp-7Ah]
char b1b_1; // [esp+33h] [ebp-79h]
char b1a_1; // [esp+35h] [ebp-77h]
char b19_1; // [esp+36h] [ebp-76h]
char b18_1; // [esp+37h] [ebp-75h]
char b17_1; // [esp+38h] [ebp-74h]
char b16_1; // [esp+39h] [ebp-73h]
char b15_1; // [esp+3Ah] [ebp-72h]
char b14_1; // [esp+3Ch] [ebp-70h]
char b13_0; // [esp+3Dh] [ebp-6Fh]
char b12_0; // [esp+3Eh] [ebp-6Eh]
char b11_0; // [esp+3Fh] [ebp-6Dh]
char b10_0; // [esp+40h] [ebp-6Ch]
char bf_0; // [esp+41h] [ebp-6Bh]
char be_0; // [esp+42h] [ebp-6Ah]
char bd_0; // [esp+43h] [ebp-69h]
char bc_1; // [esp+44h] [ebp-68h]
char bb_1; // [esp+45h] [ebp-67h]
char ba_1; // [esp+56h] [ebp-56h]
char b9_0; // [esp+7Ch] [ebp-30h]
char b8_0; // [esp+7Dh] [ebp-2Fh]
char b7_0; // [esp+7Eh] [ebp-2Eh]
char b6_0; // [esp+7Fh] [ebp-2Dh]
char b5_1; // [esp+80h] [ebp-2Ch]
char b4_1; // [esp+81h] [ebp-2Bh]
char b3_1; // [esp+82h] [ebp-2Ah]
char b2_1; // [esp+83h] [ebp-29h]
char b1_1; // [esp+85h] [ebp-27h]
unsigned int v38; // [esp+8Ch] [ebp-20h]

v38 = __readgsdword(0x14u);
v2 = a2;
while ( 2 )
{
memset(v5, 0, 0x80u);
v3 = *(_BYTE *)(a1 + v2);
v5[(v3 + 64) % 128] = 1;
if ( (unsigned __int8)(v3 - 10) <= 0x70u )
{
switch ( v3 )
{
case '\n':
return v2 == 13 && ba_1 != 0;
case '0':
if ( v2 || !b9_0 )
return 0;
v2 = 1;
continue;
case '1':
if ( v2 == 14 && b8_0 )
goto LABEL_12;
return 0;
case '2':
if ( v2 == 20 && b7_0 )
goto LABEL_15;
return 0;
case '3':
if ( v2 != 89 || !b6_0 )
return 0;
v2 = 90;
continue;
case '4':
if ( v2 != 15 || !b5_1 )
return 0;
v2 = 16;
continue;
case '5':
if ( v2 != 14 || !b4_1 )
return 0;
LABEL_12:
v2 = 15;
continue;
case '6':
if ( v2 != 12 || !b3_1 )
return 0;
v2 = 13;
continue;
case '7':
if ( v2 != 5 || !b2_1 )
return 0;
v2 = 6;
continue;
case '8':
result = 0;
if ( b1_1 )
result = v2 == 33 || v2 == 2;
return result;
case '9':
if ( v2 != 1 || !b1_1 )
return 0;
v2 = 2;
continue;
case 'a':
if ( v2 != 35 || !b20_1 )
return 0;
v2 = 36;
continue;
case 'b':
if ( v2 != 11 || !b1f_1 )
return 0;
v2 = 12;
continue;
case 'c':
if ( v2 != 32 || !b20_1 )
return 0;
v2 = 33;
continue;
case 'd':
if ( v2 != 3 || !b1e_1 )
return 0;
v2 = 4;
continue;
case 'e':
if ( v2 != 7 || !b1d_1 )
return 0;
v2 = 8;
continue;
case 'f':
if ( !b1c_1 || v2 != 8 && v2 != 4 )
return 0;
goto LABEL_53;
case 'g':
return v2 == 12 && b10_0 != 0;
case 'h':
if ( v2 != 13 || !b1b_1 )
return 0;
v2 = 14;
continue;
case 'i':
if ( v2 != 9 || !b1a_1 )
return 0;
v2 = 10;
continue;
case 'j':
if ( v2 != 10 || !b19_1 )
return 0;
v2 = 11;
continue;
case 'k':
return v2 == 12 && b18_1 != 0;
case 'l':
if ( v2 != 19 || !b17_1 )
return 0;
v2 = 20;
continue;
case 'm':
if ( v2 != 17 || !b16_1 )
return 0;
v2 = 18;
continue;
case 'n':
return v2 == 18 && b16_1 != 0;
case 'o':
if ( !b15_1 || v2 != 6 && v2 != 28 )
return 0;
LABEL_53:
++v2;
continue;
case 'p':
if ( v2 != 30 || !b14_1 )
return 0;
v2 = 31;
continue;
case 'q':
if ( v2 != 29 || !b13_0 )
return 0;
v2 = 30;
continue;
case 'r':
if ( v2 != 20 || !b12_0 )
return 0;
LABEL_15:
v2 = 21;
continue;
case 's':
if ( v2 != 25 || !b11_0 )
return 0;
v2 = 26;
continue;
case 't':
return v2 == 24 && b12_0 != 0;
case 'u':
if ( v2 != 26 || !bf_0 )
return 0;
v2 = 27;
continue;
case 'v':
if ( v2 != 2 || !be_0 )
return 0;
v2 = 3;
continue;
case 'w':
if ( v2 != 6 || !bd_0 )
return 0;
v2 = 7;
continue;
case 'x':
if ( v2 != 22 || !bc_1 )
return 0;
v2 = 23;
continue;
case 'y':
if ( v2 != 23 || !bb_1 )
return 0;
v2 = 24;
continue;
case 'z':
return v2 == 21 && b20_1 != 0;
default:
return 0;
}
}
return 0;
}
}
```
根据switch中case的值和case中的if条件就可以反推出来正确的flag
#### flag:09vdf7wefijbk

### Auth.exe
32位的windows上可执行文件,无壳,先运行一下程序:
![]()

同样也是载入IDA中通过关键字符串查找关键代码(main函数),本函数前面定义了一大堆数据,最后经过sub_401500处理

```
int __cdecl main(int argc, const char **argv, const char **envp)
{
const CHAR *v3; // ebx
HMODULE v4; // eax
void (__stdcall *v5)(HMODULE, LPCSTR); // eax
char v7; // [esp+1h] [ebp-157h]
char v8[4]; // [esp+15h] [ebp-143h]
int v9; // [esp+20h] [ebp-138h]
int v10; // [esp+26h] [ebp-132h]
int v11; // [esp+2Ah] [ebp-12Eh]
int v12; // [esp+2Eh] [ebp-12Ah]
int v13; // [esp+32h] [ebp-126h]
int v14; // [esp+36h] [ebp-122h]
int v15; // [esp+3Ah] [ebp-11Eh]
__int16 v16; // [esp+3Eh] [ebp-11Ah]
int v17; // [esp+40h] [ebp-118h]
int v18; // [esp+44h] [ebp-114h]
int v19; // [esp+48h] [ebp-110h]
int v20; // [esp+4Ch] [ebp-10Ch]
int v21; // [esp+50h] [ebp-108h]
int v22; // [esp+54h] [ebp-104h]
int v23; // [esp+58h] [ebp-100h]
int v24; // [esp+5Ch] [ebp-FCh]
int v25; // [esp+60h] [ebp-F8h]
int v26; // [esp+64h] [ebp-F4h]
int v27; // [esp+68h] [ebp-F0h]
int v28; // [esp+6Ch] [ebp-ECh]
int v29; // [esp+70h] [ebp-E8h]
char v30; // [esp+74h] [ebp-E4h]
int a_2; // [esp+75h] [ebp-E3h]
int v32; // [esp+79h] [ebp-DFh]
int v33; // [esp+7Dh] [ebp-DBh]
int v34; // [esp+81h] [ebp-D7h]
int v35; // [esp+85h] [ebp-D3h]
int v36; // [esp+89h] [ebp-CFh]
int v37; // [esp+8Dh] [ebp-CBh]
int v38; // [esp+91h] [ebp-C7h]
__int16 v39; // [esp+95h] [ebp-C3h]
int a_1; // [esp+97h] [ebp-C1h]
int v41; // [esp+9Bh] [ebp-BDh]
int v42; // [esp+9Fh] [ebp-B9h]
int v43; // [esp+A3h] [ebp-B5h]
int v44; // [esp+A7h] [ebp-B1h]
int v45; // [esp+ABh] [ebp-ADh]
int v46; // [esp+AFh] [ebp-A9h]
int v47; // [esp+B3h] [ebp-A5h]
char v48; // [esp+B7h] [ebp-A1h]
int v49; // [esp+B8h] [ebp-A0h]
int v50; // [esp+BEh] [ebp-9Ah]
int v51; // [esp+C2h] [ebp-96h]
int v52; // [esp+C6h] [ebp-92h]
int v53; // [esp+CAh] [ebp-8Eh]
int v54; // [esp+CEh] [ebp-8Ah]
int v55; // [esp+D2h] [ebp-86h]
int v56; // [esp+D6h] [ebp-82h]
int v57; // [esp+DAh] [ebp-7Eh]
char v58; // [esp+DEh] [ebp-7Ah]
int v59; // [esp+DFh] [ebp-79h]
int v60; // [esp+E3h] [ebp-75h]
int v61; // [esp+E7h] [ebp-71h]
int v62; // [esp+EBh] [ebp-6Dh]
int v63; // [esp+EFh] [ebp-69h]
int v64; // [esp+F3h] [ebp-65h]
int v65; // [esp+F7h] [ebp-61h]
int v66; // [esp+FBh] [ebp-5Dh]
__int16 v67; // [esp+FFh] [ebp-59h]
int v68; // [esp+101h] [ebp-57h]
int v69; // [esp+105h] [ebp-53h]
char v70; // [esp+109h] [ebp-4Fh]
int v71; // [esp+10Ah] [ebp-4Eh]
int v72; // [esp+10Eh] [ebp-4Ah]
int v73; // [esp+112h] [ebp-46h]
int v74; // [esp+116h] [ebp-42h]
int v75; // [esp+11Ah] [ebp-3Eh]
int v76; // [esp+11Eh] [ebp-3Ah]
int v77; // [esp+122h] [ebp-36h]
int v78; // [esp+126h] [ebp-32h]
int v79; // [esp+12Ah] [ebp-2Eh]
int v80; // [esp+12Eh] [ebp-2Ah]
int v81; // [esp+132h] [ebp-26h]
int v82; // [esp+136h] [ebp-22h]
int v83; // [esp+13Ah] [ebp-1Eh]
int v84; // [esp+13Eh] [ebp-1Ah]
int v85; // [esp+142h] [ebp-16h]
int v86; // [esp+146h] [ebp-12h]
int v87; // [esp+14Ah] [ebp-Eh]
__int16 v88; // [esp+14Eh] [ebp-Ah]
int *v89; // [esp+150h] [ebp-8h]

v89 = &argc;
sub_402940();
puts(
"            .     \n"
"           _|_    ROBOTIC AUTHENTICATION SYSTEM\n"
"    /\\/\\  (. .)  /\n"
"    `||'   |#|  \n"
"     ||__.-\"-\"-.___   \n"
"     `---| . . |--.\\  \n"
"         | : : |  ,||,\n"
"         `..-..'  \\/\\/\n"
"          || ||   \n"
"          || ||    \n"
"         |__|__|  \n");
v49 = 0x539;
v50 = 0x60646D51;
v51 = 0x64216472;
v52 = 0x7364756F;
v53 = 0x64697521;
v54 = 0x73686721;
v55 = 0x51217572;
v56 = 0x76727260;
v57 = 0x3B65736E;
v58 = 1;
a_1 = 0x60646D51;
v41 = 0x64216472;
v42 = 0x7364756F;
v43 = 0x64697521;
v44 = 0x73686721;
v45 = 0x51217572;
v46 = 0x76727260;
v47 = 0x3B65736E;
v48 = 1;
v59 = 0x60646D51;
v60 = 0x64216472;
v61 = 0x7364756F;
v62 = 0x64697521;
v63 = 0x62647221;
v64 = 0x21656F6E;
v65 = 0x72726051;
v66 = 0x65736E76;
v67 = 315;
a_2 = 0x60646D51;                             // Please enter the second Password
v32 = 0x64216472;
v33 = 0x7364756F;
v34 = 0x64697521;
v35 = 0x62647221;
v36 = 0x21656F6E;
v37 = 0x72726051;
v38 = 0x65736E76;
v39 = 315;
v68 = 0x6F6F3074;
v69 = 0x666D3367;
v70 = 3;
v28 = 0x6F6F3074;
v29 = 0x666D3367;
v30 = 3;
v71 = 0x6F73646A;
v72 = 0x33326D64;
v73 = 0x6D6D652F;
v74 = 0x13F0101;
v24 = 0x6F73646A;
v25 = 0x33326D64;
v26 = 0x6D6D652F;
v27 = 0x13F0101;
v75 = 0x57656540;
v76 = 0x6E756264;
v77 = 0x44656473;
v78 = 0x71646279;
v79 = 0x6F6E6875;
v80 = 0x656F6049;
v81 = 0x173646D;
v17 = 0x57656540;
v18 = 0x6E756264;
v19 = 0x44656473;
v20 = 0x71646279;
v21 = 0x6F6E6875;
v22 = 0x656F6049;
v23 = 0x173646D;
v82 = 0x21746E58;
v83 = 0x2F6F6876;
v84 = 0x6F6E4221;
v85 = 0x75607366;
v86 = 0x75606D74;
v87 = 0x726F6E68;
v88 = 0x120;
v10 = 0x21746E58;
v11 = 0x2F6F6876;
v12 = 0x6F6E4221;
v13 = 0x75607366;
v14 = 0x75606D74;
v15 = 0x726F6E68;
v16 = 0x120;
v9 = 0x539;
strcpy(v8, "r0b0RUlez!");
dword_40AD94 = (int)&v9;
dword_40ADA0 = (int)&v49;
dword_40AD8C = (char *)&a_1;
dword_40AD90 = (char *)&a_2;
dword_40AD98 = (int)&v28;
lpProcName = (LPCSTR)&v17;
lpModuleName = (LPCSTR)&v24;
dword_40ADA4 = (char *)&v10;
sub_401500(0);
v3 = lpProcName;
v4 = GetModuleHandleA(lpModuleName);
v5 = (void (__stdcall *)(HMODULE, LPCSTR))GetProcAddress(v4, v3);
v5((HMODULE)1, (LPCSTR)sub_40157F);
puts(dword_40AD8C);
scanf("%20s", &v7);
if ( !strcmp(&v7, v8) )
{
puts("You passed level1!");
sub_4015EA(0);
}
return 0;
}
```
在sub\_401500函数中对刚刚定义的数据的每一位都和1异或
![]()
先把数据解密一下:
```
data1="516D6460726421646F756473217569642167687372752151607272766E73653B"
str1 =""
for x in range(0,len(data1),2):
str1 += chr(eval("0x"+data1[x:x+2])^1)
print str1

data2 = "516D6460726421646F75647321756964217264626E6F652151607272766E73653B"

str2 =""
for x in range(0,len(data2),2):
str2 += chr(eval("0x"+data2[x:x+2])^1)
print str2

data3 = "74306F6F67336D66"

str3 =""
for x in range(0,len(data3),2):
str3 += chr(eval("0x"+data3[x:x+2])^1)
print str3

data4 = "6A64736F646D32332F656D6D"
str4 = ""
for x in range(0,len(data4),2):
str4 += chr(eval("0x"+data4[x:x+2])^1)
print str4

data5 = "406565576462756E736465447962647175686E6F49606F656D6473"
str5 = ""
for x in range(0,len(data5),2):
str5 += chr(eval("0x"+data5[x:x+2])^1)
print str5

data6 = "586E742176686F2F21426E6F66736075746D6075686E6F7220"
str6 = ""
for x in range(0,len(data6),2):
str6 += chr(eval("0x"+data6[x:x+2])^1)
print str6
```
输出结果:
![]()
发现是一些需要输出的字符串

接下来程序接收一个字符串,与字符串“r0b0RUlez!”进行比较,这是第一层限制,然后来到函数sub\_4015EA,在这个里面构造了一个异常,当程序走到这里的时候,发生异常而进行跳转,在跳转之前改变了一个数据,第二跳是在这个函数中的,那么我们就跟进第一条
![]()

跟进之后来到一个函数中,再接收一个字符串,进入sub\_401547进行比较
![]()

在sub\_401547函数中对字符串“u1nnf2lg”每一位都与2异或
![]()

解密得到“w3lld0ne”
```
flag = "u1nnf2lg"
real_flag =""
for x in range(len(flag)):
real_flag+=chr(ord(flag[x])^2)
print real_flag
```

最后将字符串拼接起来
#### flag:r0b0RUlez!\_w3lld0ne

(4)

本文由 姬長信 创作,文章地址:https://blog.isoyu.com/archives/2019-shanghaijiaweisibeinixiang-writeup.html
采用知识共享署名4.0 国际许可协议进行许可。除注明转载/出处外,均为本站原创或翻译,转载前请务必署名。最后编辑时间为:3月 31, 2019 at 01:12 下午

热评文章

评论:

7 条评论,访客:0 条,博主:0 条
  1. 菜鸟头头
    菜鸟头头发布于: 

    怎么不能对你进行回复呀。学习没课了,在找实习没有。

    • 姬長信
      姬長信发布于: 

      是的正在进行中

  2. 菜鸟头头
    菜鸟头头发布于: 

    哈哈,是不是差点把你吓一跳

    • 姬長信
      姬長信发布于: 

      是啊,后背都发凉了,差一点就去恢复快照了

  3. 菜鸟头头
    菜鸟头头发布于: 

    这是大佬,这是真正的大佬。

    • 姬長信
      姬長信发布于: 

      刚猜测大佬的评论怎免审核了,还以为大佬侵入数据库呢,搜索评论发现大佬以前来过

  4. 姬長信
    姬長信发布于: 

    早啊

发表回复

[必填]

我是人?

提交后请等待三秒以免造成未提交成功和重复