题目源码中省略了token的计算过程:
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
#define FAKEUID 1000
int main(int argc, char **argv, char **envp)
{
int c;
char token[256];
if(getuid() != FAKEUID) {
printf("Security failure detected. UID %d started us, we expect %d\n", getuid(), FAKEUID);
printf("The system administrators will be notified of this violation\n");
exit(EXIT_FAILURE);
}
// snip, sorry :)
printf("your token is %s\n", token);
}
可以看到,当运行程序的UID为1000时将打印token,否则提示错误退出。
cat /etc/passwd可以看到1000为用户nebula,而当前用户level13位1014.
该题目有两种利用方式:
1. gdb调试,在getuid()后作比较的时候,将getuid返回值,即EAX的值改为1000.
x0x80484d9 <main+21> mov 0x10(%ebp),%eax x
x0x80484dc <main+24> mov %eax,0x18(%esp) x
x0x80484e0 <main+28> mov %gs:0x14,%eax x
x0x80484e6 <main+34> mov %eax,0x12c(%esp) x
x0x80484ed <main+41> xor %eax,%eax x
x0x80484ef <main+43> call 0x80483c0 <getuid@plt> x
x0x80484f4 <main+48> cmp $0x3e8,%eax x
x0x80484f9 <main+53> je 0x8048531 <main+109> x
x0x80484fb <main+55> call 0x80483c0 <getuid@plt> x
x0x8048500 <main+60> mov $0x80486d0,%edx x
x0x8048505 <main+65> movl $0x3e8,0x8(%esp) x
x0x804850d <main+73> mov %eax,0x4(%esp) x
x0x8048511 <main+77> mov %edx,(%esp) x
x0x8048514 <main+80> call 0x80483a0 <printf@plt> x
x0x8048519 <main+85> movl $0x804870c,(%esp) x
x0x8048520 <main+92> call 0x80483d0 <puts@plt> x
x0x8048525 <main+97> movl $0x1,(%esp) x
x0x804852c <main+104> call 0x80483f0 <exit@plt> x
x0x8048531 <main+109> lea 0x2c(%esp),%eax
set $eax = 1000
修改寄存器值后,继续执行,程序将打印出token:
b705702b-76a8-42b0-8844-3adabbe5ac58
然后使用token登陆flag13账号。
v17 = *MK_FP(__GS__, 20);
if ( getuid() != 1000 )
{
v3 = getuid();
printf("Security failure detected. UID %d started us, we expect %d\n", v3, 1000);
puts("The system administrators will be notified of this violation");
exit(1);
}
memset(&v7, 0, 0x100u);
v7 = *(_DWORD *)"8mjomjh8wml;bwnh8jwbbnnwi;>;88?o;9ob";
v8 = *(_DWORD *)"mjh8wml;bwnh8jwbbnnwi;>;88?o;9ob";
v9 = *(_DWORD *)"wml;bwnh8jwbbnnwi;>;88?o;9ob";
v10 = *(_DWORD *)"bwnh8jwbbnnwi;>;88?o;9ob";
v11 = *(_DWORD *)"8jwbbnnwi;>;88?o;9ob";
v12 = *(_DWORD *)"bnnwi;>;88?o;9ob";
v13 = *(_DWORD *)"i;>;88?o;9ob";
v14 = *(_DWORD *)"88?o;9ob";
v15 = *(_DWORD *)";9ob";
v16 = a8mjomjh8wmlBwn[36];
for ( i = 0; *((_BYTE *)&v7 + i); ++i )
*((_BYTE *)&v7 + i) ^= 0x5Au;
result = printf("your token is %s\n", &v7);
v5 = *MK_FP(__GS__, 20) ^ v17;
return result;
}
编写如下python脚本解密得到token:
enc = '8mjomjh8wml;bwnh8jwbbnnwi;>;88?o;9ob'
dec = ''
for i in range(len(enc)):
dec += chr(ord(enc[i]) ^ 0x5a)
print dec
level13@nebula:~$ python dec.py
b705702b-76a8-42b0-8844-3adabbe5ac58