목록System/pwnable.kr (11)
Un_Woo
asm 플래그의 이름이 매우 긴 것을 확인 할 수 있다. 이 프로그램은 seccomp때문에 입력할 때 시스템콜로 open, write, read만을 사용하는 코드를 넣어줘야 한다. 그래서 그 이외의 것을 입력하면 세그멘테이션 폴트가 뜬다. 이 문제를 풀기 위해서 pwntools에 포함된 shellcraft를 이용하여 open, write, read를 사용해 플래그를 읽을 것이다. 다음과 같은 코드로 플래그를 읽는 코드를 얻을 수 있다. 이것을 asm 파일에 입력해주면 된다.
cmd2 코드를 보면 환경변수를 사용하지만 모르므로 넘어간다… 인자로 받은 것을 system함수로 실행한다. 하지만 그 인자에서 =, PATH, export, /, `, flag가 있으면 실행되지 않는다. 그래서 저 문자들을 우회하기 위해서 노력했다. 이전 명령어를 실행하는 !!을 사용하거나…(!!을 system 명령으로 사용하려면 /bin을 붙여야 했다.) history 명령어로 /bin/cat flag인 3으로 실행을 한다던가…(/bin을 붙여야 했다.) 그래서 쉘 스크립트를 사용하여 명령어를 실행하기로 했다. /를 우회하기 위해서 /를 아스키코드 8진수로 변환한 \57로 입력했다. 16진수와 10진수는 되지 않았다. flag는 우회하기 위해서 *을 사용했다.
cmd1 환경변수를 사용하는 것 같은데 환경변수는 아는 것이 없기 때문에 다른 방법으로 풀었다. 아마 환경변수를 이용해서 푸는 방법도 있을 것 같다. 코드를 살펴보면 인자를 받는다. 그 인자를 filter함수에 넣어서 flag, sh, tmp가 들어가 있으면 프로그램을 종료시킨다. 그러므로 flag, sh, tmp를 인자로 넣지 않고 flag의 값을 확인해야 한다. 그래서 fla*을 해서 fla로 시작하는 모든 파일을 cat했다.
lotto 이 문제는 1~45의 숫자 6개로 조합된 랜덤한 값을 맞추는 문제이다. 하지만 이 부분을 보면 로또 1개의 값을 제출한 모든 숫자와 비교한다. 그러므로 제출한 6개의 숫자 중 하나라도 로또 번호 1개와 같다면 match변수가 6이 된다. ascii코드에섯 1~45 중 입력 가능한 것은 32~45 부분의 특수문자들이라고 생각했다. 물론 lotto값은 랜덤이므로 성공할 때까지 여러 번 해줘야 한다.
mistake 문제를 보면 무엇인가 실수를 했고 연산자 우선순위를 힌트로 줬다. 일단 실행을 해보니 두 번 입력을 받는 것을 알 수가 있다. 그리고 gdb에서도 실행시켜 봤는데 open 함수가 실패하여 -1을 리턴한 것으로 보인다. 그런데 can't open password 뒤에 1이 있는 것이 이해가 되지 않았다. 코드를 보면 그 뒤에 있어야 하는 것은 fd의 값인 -1이라고 생각했기 때문이다. 하지만 왜 1이 나오는지 이해를 못 하고 있었던 중 힌트였던 연산자 우선순위가 생각나 구글링을 해봤다. 그리고 코드에서 문자가 있는 부분은if(fd=open("/home/mistake/password",O_RDONLY,0400) < 0)이라고 생각했으므로 이 코드에 쓰인 =과
random random변수에 랜덤값을 받고 key에 값을 입력받아 두 개의 값을 ^연산자로 처리한 값이 0xdeadbeef면 flag를 열 수 있다. ^연산자는 XOR연산자이다. XOR연산자는 2진수로 봤을 때 두 값이 다르면 1, 같으면 0이 된다. 근데 여기서 rand()를 아무리 써봤자 값이 변하지 않는다. 시드값이 없기 때문이다. 값이 변하게 하려면 srand()를 써야한다. key은 rbp-0x8에 random은 rbp-0x4에 있다. 일단 random값을 알아보자. 어셈블리 코드를 보면 random값이 들어가 있는 레지스터가 eax인 것을 알 수 있다. 그러므로 eax에 값이 들어간 후에 break를 걸어보면... rax(eax)에 0x6b8b4567가 들어간 것을 알 수 있다. 0xdead..
passcode 이것이 전체적인 코드인데 이름을 입력받고 비밀번호를 2개 입력받아 비밀번호가 맞으면 flag가 열리는 프로그램이다. 그래서 그냥 비밀번호를 맞추면 되는 건가하고 생각했지만 ... 사진과 같이 segmentation fault가 뜬다. 그 이유는 무엇일까? 위 코드를 다시 자세히 보면 scanf를 사용할 때 변수들 앞에 &을 사용하지 않는 것을 볼 수 있다. &을 사용하지 않으면 scanf의 두 번째 인자를 주소로 인식한다고 한다. 예를 들면 scanf("%d",a)라고 하면 a를 변수로 인식하지 않고 주소로 인식하여 그 주소에 값을 넣는 것이다. 그리고 scanf를 사용한 것들을 보면 name은 ebp-70에 100만큼 입력, passcode1는 ebp-10에 4만큼 입력한다. 그러므로 ..
flag 이 프로그램을 IDA 프로그램을 사용해 분석해보면 이 프로그램이 UPX 파일인 것을 알 수 있다. UPX는 압축파일 중 하나이다. 이것을 언패킹 하기 위해서 UPX3.94라는 프로그램을 다운받았다. UPX프로그램에 -d 옵션을 주어 언패킹을 했다. flag를 실행시켜보면 다음과 같은 문장이 출력된다. 나는 malloc()과 strcpy를 이 flag에서 할 것이다. 잡아라. 대충 이런 의미인 것 같다. 그래서 코드를 까봤는데 오른쪽에 flag가 떡하니 보인다. 저것을 rdx에 mov를 했으니 rdx 레지스터에 flag가 들어갔다고 예상할 수 있다. 그래서 그 다음 줄인 main+39에 브레이크포인트를 걸고 실행시켜봤다. 그리고 info reg명령어로 rdx에 들어간 값을 확인하니 0x496628..
bof bof 문제의 코드다. key라는 변수에 0xdeadbeef가 저장되어 있는데 그 값을 0xcafebabe로 바꾸면 쉘이 따지는 코드다. 이것은 func함수의 어셈블리어다. 이것을 보면 ebp-0x2c에 입력을 한다. 그리고 key 변수는 ebp+0x8에 있다. 0x2c=44 이고 0x8=8 이므로 버퍼 주소와 key 변수가 있는 주소는 44+8=52 만큼의 차이가 있다. 그러므로 52만큼의 쓰레기값을 주고 0xcafebabe를 줘서 key 변수를 바꿨다. id 명령어를 사용하면 쉘을 딴 것을 확인할 수 있다.
collision argc는 인자의 개수, argv는 인자의 주소를 저장한다. 그러므로 첫 번째 if문을 탈출하기 위해서는 인자가 2개 이상이어야 한다. ./col ??? 이런 식으로 실행시키면 된다. 인자를 넣어주면 사진과 같이 passcode가 20바이트가 되어야만 한다고 출력된다. 그렇다면 20바이트로 넣어줘보자. 그러면 사진과 같이 passcode가 잘못됐다고 출력된다. flag를 보기 위해서는 사진에 있는 if문을 만족시켜야 한다. 그러면 check_password함수에서 hashcode와 같은 값이 리턴되어야 한다. 여기서 hashcode의 값은 0x21dd09ec=568134124이다. check_password함수를 보면 첫 번째 인자에 있는 값 5개를 더한 값을 리턴한다. 그러면 인자로 ..