목록펭귄's directory (180)
한땀한땀 정성들인 코딩

세그먼테이션은 왜 쓰고 페이징은 왜 쓸까? 보호모드에서는 왜 세그먼테이션, 페이징을 모두 쓰고 IA-32e 모드는 사실상 선형주소로 변경하는 과정인 세그먼테이션이 없다. 왜? WHY? 1. 물리 메모리를 물리주소 있는 그대로 사용하는 경우 만약 32bit의 레지스터 크기를 가지고 있으면 0000 0000 0000 0000 0000 0000 0000 0000 ~ 1111 1111 1111 1111 1111 1111 1111 1111 범위의 값을 가질 수 있다. 10진수로 0~4,294,967,295 16진수로 0~FFFF FFFF 이다. 즉, 32bit 레지스터는 2^32개의 숫자를 표현할 수 있다. 메모리의 주소는 위 그림처럼 byte단위로 접근한다. (주의 : bit 단위가 아니다.) 즉, 32bit ..

주제 LOB darkknight 1. argc는 2이상 2. 함수내의 버퍼에 bof 3. sfp주소의 맨 뒤 1byte를 변경가능 4. 즉 main함수내에서 ebp가 돌아오는 위치가 봐뀜 Leave mov esp, ebp pop ebp Ret pop eip jmp eip 즉 조작한 ebp+4byte위치가 jmp eip 하게 된다. 스택내의 범위에서 주소를 넣어주고 주소-4위치를 ebp에 넣고 주소가 쉘코드를 가리키면됨 어느 주소로든 점프가 가능하므로 쉘코드를 넣을곳은 많다. 1. buffer변수 2. argv[0] 혹은 argv[2] 이상 3. 공유라이브러리 버퍼는 작아서 nop를 타기에 적합하지 않으므로 argv[2]에 쉘코드를 넣어주겠다. 일단 대략적인 argv[2]주소와 char buffer[40]..

주제 LOB 스켈레톤 요넘 추가 환경변수도 못쓴다 참고로. 버퍼도 그렇고 길이 48제한이라 스택에서 할 수 있는게 없음. 이건 공유라이브러리를 활용한 rtl chain말곤 답이 없다. 혹은 gadget을 활용해볼 수도 있겠는데... 찾아보자. execve함수 찾음 레지스터에 "/bin/sh"의 주소를 넣어주고 0x400a9d48를 ret로 넣어주면 끝! gcc -o skeleton2 skeleton.c gdb skeleton2 break main r info functions

주제 LOB 뱀파이어 조건 -인자2개 이상 -[47] "\xbf"로 시작 -[46] "\xff"이면 안됨 ???????????? 여태까지 ret주소가 bfff로 시작 했는데.... ff가 아니면 fe가 제일 가까운데 이것은 16의 4승? 256*256??? 약 4만??바이트 \xbf니깐 스택안에서 해결해야 한다. 프로세스가 main을 시작하기전 스택에 담는 값을 확인해보자. 서치하다가 좋은 사이트가 있어서 .. http://slideplayer.com/slide/9114222/ 프로세스관련 스택위에 argv도 있고 envp도 있고 저것들은 포인터니깐 값으로 스택을 넓히진 않는다. 즉 인자를 무지 많이 넘겨주면 된다. 65536이상 늘려줘야 하므로 16384개(32bit기준 포인터 하나의 크기) ㄱㄱ re..

주제 LOB orge->troll 소스코드를 보면 argv[1]이 초기화 된다. 버퍼도 초기화 되버려서 쉘코드를 담을 만한곳을 찾아야 된다. argv[0]에 넣으면 되징 ㅋ ln으로 링크를 걸어서 argv[0]값에 쉘코드를 담는다. ? troll 파일을 못찾겠단다....모냥 이건 잘만되고.... 아씝 . 문자열이 아닌것에 대해 저항 쉘코드 어셈블리어에 저항? 각각 확인 하고 안되면 아스키로 쉘코드를 구성해야 한다. 문자열에 해당하는것은 잘 만들어진다. 쉘코드 때문인가? nop * 100한것도 잘 만 만들어지는데 ㅡ ,ㅡ 원인찾음! 0x2f의 경우 "/" 문자라 경로(path)가 들어가서 문제다. 딱봐도 0x2f를 지워서 만들자.. 00000000 : 0: 31 c0 xor eax,eax 2: 50 pus..

전 문제에서 모가 추가 되었나 했더니 if(strlen(argv[1])>48)로 인자 길이 필터링 하는것이 추가 되었다. 즉 최대 길이가 48이므로 전에 문제 처럼 풀면 안된다. nop(15byte)+shellcode(25byte)+sfp(4byte)+ret(4byte) 무조건 이 페이로드를 써야하는데 ret가 뒤죽박죽인게 관건 for문을 돌려 bruteforce공격을 해야한다. 복사한 프로그램 ret를 확인하자 0xbffffafc 대략 적으로 32byte ret를 앞댕겼는데 먹히지 않는다. for문을 2번써서 공격 시도 따는 데 성공!! ㅋㅋ( 성공한 소스좀 캡쳐할랬더니 커널이 엉망이 되있다. ㅡㅡ ) pass : kernel crashed

extern char **environ; ?? 함수 밖의 전역 범위 프로그램 전체에서 유효( 다른 파일간 참조 가능 ) 정적 데이터영역( data section ) int main(char **envp) 이나 extern char **environ은 같은 구문이다. extern 구문은 첨봄.. 중간에 보면 환경변수를 초기화 하는 코드가 있다. memset으로 환경변수를 못쓰게 하는거 같은데.. 난 여태 문제풀면서 환경변수 쓴적이 없어서 학습이나 하자. 리눅스 상에서 환경변수 설정 export PYTHON_HOME = /usr/lib/python 설정 env | grep PYTHON_HOME 확인 source /etc/bash.bashrc 적용 unset 환경변수명 -해제하기 if(argv[1][47] !..

고블린 잡으러 가자!! 소스코드 확인 gets함수? 전 문제들은 argv로 받아서 strcpy 하는 형태 였는데 .. 이번엔 프로그램 실행후 명령을 입력 받는다. 리눅스 환경에서는 파이프라인 | 명령어를 쓰면 손쉽게 해결 가능.! 프로세스1 번 | 프로세스 2번 1번 프로세스의 출력이 2번 프로세스 입력으로 들어간다. c언어의 경우 입력은 gets나 scanf, fgets 등등 , 출력은 printf 파이썬의 경우 input, print가 되겠다.! 버퍼가 작긴한데 작든 말든 그냥 ret 뒤에 넣어주고, nop적당히 넣어주고 전사공격 하는건 1,2 탄이랑 다를게 없다 . .... print dummy+ret+nop+shellcode 해주고 | 명령어로 넘기면 된다. 일단 ret주소를 파악하기 위해 gcc..

이야 코볼트 잡으러 가자!! 소스 확인 int main(int argc, char *argv[]){ char buffer[16]; if(argc < 2){ printf(“argv error\n”): exit(0); } strcpy(buffer, argv[1]); printf(“%s\n“, buffer); } buffer크기가 작네?? 그럼 그냥 ret 뒤에다 넣으면 되겠고만.. . payload 작성 dummy (20byte) + ret (4byte) + nop적당히 + shellcode ret 찾자!! 적당한 복귀주소 gcc –o cobolt2 cobolt.c 코볼트 짝퉁 컴파일 하고 gdb로 확인 근데 레드햇에서 set disassembly intel 지원안하네 .. ㅡㅡ 자 break *0x8048..

execve 함수 인자를 알아보자. #include int execve(const char *filename, char *const argv[], char *const envp[]); 1번째 filename -파일명 정확히 파일명 문자열의 주소값 2번째 argv -파일을 실행할때 넘겨줄 변수 배열 포인터 이니 문자열을 여러개 넘겨줄 수 있다. 3번쟤 envp -환경변수 문자열 위와 마찬가지 ebx, ecx, edx 모두 char형 포인터 커널 버젼 차이로 execve에 인자에 영향이 다른거 같은데 정확히 볼라면 어셈블리어를 봐야된다 .. 버전을 따져서 각 strcpy 함수호출에 대해서 어셈블리어 차이를 보면 명확해 지겠지만 . ㄷㄷ . 그전에 테스트로 차이를 보자. char *scode = "/bin/s..