iT邦幫忙

0

Pwnable.kr - simple login writeup(上)

  • 分享至 

  • twitterImage
  •  

資安新手,
把自己的解題過程記錄下來避免失憶症發作 lol
有錯誤的地方請大佬用力的噴我,想學到更多。
.
今天要來玩的是以二進制為取向的pwnable.kr
由於非本科,組合語言自學的關係
接觸跟組合語言有關的每次都要跟腦子大戰
如果有觀念錯誤的地方也煩請糾正我,謝謝!


前言

對於pwn系列我想要以思考的過程為主,
因為我對二進制很生疏,
不想直接按F5生原始碼直接點出此題要怎麼解,
並且把追蹤程式碼的過程也記錄下來,
預計整篇篇幅會很大,分成上下篇。
上篇注重於程式分析,
下篇注重於漏洞利用。

正文開始!!

題目網址:https://pwnable.kr/play.php
首先看看題目頁面
https://ithelp.ithome.com.tw/upload/images/20190927/20121620ZFibbF45lZ.png

看來這次沒有給原始碼,但是有給檔案可以讓我們在自己的電腦上進行分析。

main程式架構分析:

首先上IDA進行靜態分析(我沒有Pro QQ)
看main架構圖(之後會分頭進行詳細探討)
https://ithelp.ithome.com.tw/upload/images/20190927/20121620guxtCDr9D7.png

  • 上半部:
    https://ithelp.ithome.com.tw/upload/images/20190927/20121620koLOYAo2g8.jpg
    .

分析:

push ebp
mov esp, esp
and esp, 0FFFFFFF0h
sub esp, 40h

很基本的函數起始,對齊,跟分配local空間,不多說。


mov     dword ptr [esp+8], 1Eh
mov     dword ptr [esp+4], 0
lea     eax, [esp+1Eh]
mov     [esp], eax
call    _memset

按照老標準,參數由右往左依序入棧。
在這裡注意到lea eax, [esp+1Eh]
我們把[esp+1Eh]的值設成 var1
五行下來得到 ↓

變數var1宣告; (有大神能告訴我IDA pro怎麼知道此變數型態的嗎)
memset( &var1, 0, 30 );


mov     eax, stdout
mov     dword ptr [esp+0Ch], 0
mov     dword ptr [esp+8], 2
mov     dword ptr [esp+4], 0
mov     [esp], eax
call    setvbuf

得到 ↓

setbuf( stdout, 0, 2, 0 );


mov     eax, stdin
mov     dword ptr [esp+0Ch], 0
mov     dword ptr [esp+8], 1
mov     dword ptr [esp+4], 0
mov     [esp], eax
call    setvbuf

得到 ↓

setbuf( stdin, 0, 1, 0 );


mov     dword ptr [esp], offset aAuthenticate ; "Authenticate : "
call    printf

得到 ↓

printf( "Authenticate :" );


lea     eax, [esp+1Eh]
mov     [esp+4], eax
mov     dword ptr [esp], offset a30s ; "%30s"
call    __isoc99_scanf

注意到[esp+1Eh]了嗎?正是上面宣告過的變數!
得到 ↓

scanf( "%30s", &var1 );


mov     dword ptr [esp+8], 0Ch
mov     dword ptr [esp+4], 0
mov     dword ptr [esp], offset input
call    _memset

這裡的input就是程式要我們鍵盤輸入的地方
得到 ↓

memset( &input, 0, 12 );


mov     dword ptr [esp+18h], 0

設[esp+18h]為變數var2 ↓

變數var2宣告;


lea     eax, [esp+18h]
mov     [esp+4], eax
lea     eax, [esp+1Eh]
mov     [esp], eax
call    Base64Decode

得到 ↓

Base64Decode( &var1, &var2 );


mov     [esp+3Ch], eax
cmp     dword ptr [esp+3Ch], 0Ch
ja      short loc_8049413

eax為Base64Decode解碼後返回的長度
若長度大於12的話則跳轉到Wrong Length
否則會進到main下半部的左方這裡
https://ithelp.ithome.com.tw/upload/images/20190927/201216208p4kfWtcM9.jpg

mov     eax, [esp+18h]
mov     edx, [esp+3Ch]
mov     [esp+8], edx
mov     [esp+4], eax
mov     dword ptr [esp], offset input
call    memcpy

這裡[esp+3Ch]也同之前的變數一樣
設為 var3
得到 ↓

宣告var3
memcpy( &input, var1, var3 )


mov     eax, [esp+3Ch]
mov     [esp], eax
call    auth
cmp     eax, 1
jnz     short loc_804941F

把var3 當作auth()的參數傳入
如果返回值(eax)等於就不跳轉

if( auth(var3) == 1 ) correct();

main()函數分析結束


auth()架構分析:

https://ithelp.ithome.com.tw/upload/images/20190927/20121620Lp998Yi0Nc.jpg

mov     eax, [ebp+arg_0]
mov     [esp+8], eax
mov     dword ptr [esp+4], offset input
lea     eax, [ebp+var_14]
add     eax, 0Ch
mov     [esp], eax
call    memcpy

開頭基本略過,
宣告變數:

local1 ( [ebp-8] )
memcpy( &local1, &input, var3 ); # var3就是main傳過來的參數

等等!?var3 ,也就是input的長度最大不是可以等於12byte嗎?
local1距離ebp只有8byte欸?!
Um..........你想的跟我一樣嗎?
/images/emoticon/emoticon14.gif


mov     dword ptr [esp+4], 0Ch
lea     eax, [ebp+var_14]
mov     [esp], eax
call    calc_md5
mov     [ebp+var_C], eax

得到 ↓

變數宣告 local2 ( ebp-14h )
變數宣告 local3 ( ebp-0Ch )
local3 = calc_md5( &local2, 12 )


mov     [ebp+var_C], eax
mov     eax, [ebp+var_C]
mov     [esp+4], eax
mov     dword ptr [esp], offset aHashS ; "hash : %s\n"
call    printf

得到 ↓

printf( "hash %s", local3 );


https://ithelp.ithome.com.tw/upload/images/20190927/20121620MphYZo0aQ9.png

這裡合在一起講比較妥當:
得到如下 ↓

> if( strcmp( "f87cd601aa7fedca99018a8be88eda34", local3 ) == 0 ){
>   return 1;
> } // if
> else return 0;

至此auth()分析結束......

給大家完整分析後的程式碼,也就是神器IDA pro F5後的樣子:

int  main(int argc, const char **argv, const char **envp)
{
  int var2; 
  int16 var1; 
  unsigned int var3; 

  memset(&var1, 0, 30);
  setvbuf(stdout, 0, 2, 0);
  setvbuf(stdin, 0, 1, 0);
  printf("Authenticate : ");
  _isoc99_scanf("%30s", &var1);
  memset(&input, 0, 12);
  var2 = 0;
  var3 = Base64Decode(&var1, &var2); 
  if ( var3 > 12 )
  {
    puts("Wrong Length");
  }
  else
  {
    memcpy(&input, var2, var3);     
    if ( auth(var3) == 1 )
      correct();
  }
  return 0;
}

bool  auth(int var3)
{
  char local2; 
  char *local3; 
  int local1;

  memcpy(&local1, &input, local3);        
  var3 = calc_md5(&local2, 12);
  printf("hash : %s\n", local1);
  return strcmp("f87cd601aa7fedca99018a8be88eda34", local3) == 0;
}

至於此程式的漏洞在哪裡,我想很清楚了。
我們下回來探討怎麼epxloit這個漏洞,取得控制權!


下集已經做好囉!

熱騰騰端上:

https://ithelp.ithome.com.tw/articles/10221639

更多文章:https://ithelp.ithome.com.tw/users/20121620/articles


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言