Scythe17 Crackheads 150
crackheads scythe17 - 150
feignix and nazgul were fighting over a tide. reverse me.
I had fun solving this challenge and it improved my radare skill
file rev
rev: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2,
for GNU/Linux 2.6.24, BuildID[sha1]=deeb187ed41eed710a81bad92c2a723ea925690f, stripped
running the binary prints a tempting message
$ ./rev
[↑] Launching stage 1
[↑] Launching stage 2
[*] Key x is incorrect
[↑] Launching stage 3
[*] Key x is incorrect
[↑] Launching stage 4
Enter password: hello
[*] Key x is incorrect
[*] Key says it is not for you
Entering the last check:hello
Don't leave me with the rest of your unsolved task :(
So challenge accepted !
There are totally 5 constrains ,we need to find to success Strings in the binary
[0x00400f00]> izq
0x4023bf 30 29 FATAL: Cannot allocate memory
0x4023e0 61 60 \e[34mDon't try to fool me around by modifying the binary\e[0m
0x40241d 13 12 \e[33m%s\e[0m\n
0x40242a 8 7 ARCTYPE
0x402438 41 40 \e[31m[*] Key says it is not for you\e[0m\n
0x402461 6 5 amd64
0x402468 31 30 \e[32m[*] Key x is correct\e[0m\n
0x402488 33 32 \e[31m[*] Key x is incorrect\e[0m\n
0x4024a9 6 5 psscr
0x4024af 6 5 auwod
0x4024b5 6 5 snoli
0x4024bb 27 26 \e[35mEnter password: \e[33m
0x4024da 5 4 %02x
0x4024df 5 4 %lld
0x4024e8 34 31 \e[36m[↑] Launching stage 1\e[0m\n
0x40250a 17 16 creation failed\n
0x402520 34 31 \e[36m[↑] Launching stage 2\e[0m\n
0x402548 34 31 \e[36m[↑] Launching stage 3\e[0m\n
0x402570 34 31 \e[36m[↑] Launching stage 4\e[0m\n
0x402592 25 24 Entering the last check:
0x4025b0 34 33 \n\e[33mIt is not the time yet\e[0m\n
0x4025d8 61 60 \n\e[33mOnly way to get flag is to feed me a correct time\e[0m\n
0x402618 46 45 \n\e[33mDo not hesitate to give time to me\e[0m\n
0x402648 32 31 \n\e[32m[*] Key x is correct\e[0m\n
0x402668 64 63 \e[34mDon't leave me with the rest of your unsolved task :(\e[0m\n
Looking into the main we can see that the binary uses multi threading and all the stages are started on different thread
0x00402061 bfe8244000 mov edi, str._e_36m______Launching_stage_1_e_0m_n ; 0x4024e8
0x00402066 e882efffff call sub.printf_fed ; int printf(const char *format)
0x0040206b bfa0316000 mov edi, 0x6031a0
0x00402070 e84beeffff call sym.imp.pthread_mutex_unlock
0x00402075 488d75b0 lea rsi, [local_50h]
0x00402079 488d85e0feff. lea rax, [local_120h]
0x00402080 b900000000 mov ecx, 0
0x00402085 ba161b4000 mov edx, 0x401b16
0x0040208a 4889c7 mov rdi, rax
0x0040208d e83eedffff call sym.imp.pthread_create
0x00402092 85c0 test eax, eax
0x401b16
contains the code for the stage 1 radare did not identify this as a function and we can’t see this region in graph view so we tell radare to analyse the region and mark it as function
[0x00402044]> af @ 0x401b16
[0x00402044]> afl ~401b16
0x00401b16 10 1190 fcn.00401b16
[0x00402044]> s 0x401b16
[0x00401b16]> afn stage_1
Let’s analyse this function here
0x00401b1a]> pd 20 @ 0x00401b32
| 0x00401b32 488945e8 mov qword [local_18h], rax
| 0x00401b36 31c0 xor eax, eax
| 0x00401b38 e843f3ffff call sym.imp.getuid ; uid_t getuid(void)
| 0x00401b3d 898550ffffff mov dword [uid], eax
| 0x00401b43 e858f2ffff call sym.imp.geteuid ; uid_t geteuid(void)
| 0x00401b48 898554ffffff mov dword [euid], eax
| 0x00401b4e 48c745d00000. mov qword [local_30h], 0
| 0x00401b56 48c745d80000. mov qword [local_28h], 0
| 0x00401b5e c745e0000000. mov dword [local_20h], 0
| 0x00401b65 66c745e40000 mov word [local_1ch], 0
| 0x00401b6b 83bd50ffffff. cmp dword [uid], 0xffffffffffffffff
| ,=< 0x00401b72 0f85e0030000 jne 0x401f58
| | 0x00401b78 83bd54ffffff. cmp dword [euid], 0
| ,==< 0x00401b7f 0f85d3030000 jne 0x401f58
| || 0x00401b85 c705b1152000. mov dword [0x00603140], 0 ; [0x603140:4]=1
| || 0x00401b8f b8aaf6ffff mov eax, 0xfffff6aa ; 4294964906
| || 0x00401b94 2b8550ffffff sub eax, dword [uid]
| || 0x00401b9a 89c2 mov edx, eax
| || 0x00401b9c 8b8554ffffff mov eax, dword [euid]
| || 0x00401ba2 01d0 add eax, edx
getuid()
and geteuid
functions are called and the return values are checked with -1 and 0 respectively , if true then Some calculation are done and the sting ‘key is correct’ is printed , else some values are set in memory and incorrect key error is printed
.---------------------------------------------------.
| 0x401f58 ;[gc] |
| ; JMP XREF from 0x00401b72 (stage_1) |
| ; JMP XREF from 0x00401b7f (stage_1) |
| ; [0x603140:4]=1 |
| mov dword [0x00603140], 1 |
| ; [0x603144:4]=1 |
| mov dword [0x00603144], 1 |
| ; [0x603148:4]=1 |
| mov dword [0x00603148], 1 |
| ; [0x60314c:4]=1 |
| mov dword [0x0060314c], 1 |
| mov edi, 0x6031a0 |
| call sym.imp.pthread_mutex_lock;[go] |
| ; 0x402488 |
| mov edi, str._e_31m____Key_x_is_incorrect_e_0m_n |
| call sub.printf_fed;[gp] |
| mov edi, 0x6031a0 |
| call sym.imp.pthread_mutex_unlock;[gq] |
`---------------------------------------------------'
v
How can we satisfy this condition we can get uid and euid to be zero if it is running as root , can the uid value can be negative not in normal situation , so i created a evil shared object and tell to load this shared library first and our evil functions will be executed which returns the required value
int getuid()
{
return 0xffffffff;
}
int geteuid()
{
return 0;
}
gcc -shared -fPIC -o uid_evil.so uid_evil.c
The file which LD_PRELOAD
specify is loaded to before any other is loaded so we get our evil uid function
So One down and 4 to GO!
Stage 2 :
| mov edi, str._e_36m______Launching_stage_2_e_0m_n |
| call sub.printf_fed;[gg] |
| mov edi, 0x6031a0 |
| call sym.imp.pthread_mutex_unlock;[gh] |
| mov rax, qword [local_140h] |
| mov rdx, qword [rax] |
| lea rax, [local_50h] |
| lea rcx, [local_120h] |
| ; 8 |
| lea rdi, [rcx + 8] |
| mov rcx, rdx |
| mov edx, 0x401862 |
| mov rsi, rax |
| call sym.imp.pthread_create;[gi] |
[0x00401fbc]> af @ 0x401862
[0x00401fbc]> s 0x401862
[0x00401862]> afn stage_2
| 0x004018c5 8d9540ffffff lea edx, [local_c0h]
| 0x004018cb 488b85d8feff. mov rax, qword [local_128h]
| 0x004018d2 4889d6 mov rsi, rdx
| 0x004018d5 4889c7 mov rdi, rax
| 0x004018d8 e813f5ffff call sym.imp.statfs
| 0x004018dd 8985ccfeffff mov dword [local_134h], eax
| 0x004018e3 83bdccfeffff. cmp dword [local_134h], 0
| ,=< 0x004018ea 7405 je 0x4018f1
| ,==< 0x004018ec e9c1010000 jmp 0x401ab2
| || ; JMP XREF from 0x004018ea (stage_2)
| |`-> 0x004018f1 488b8540ffff. mov rax, qword [local_c0h]
| | 0x004018f8 483185d0feff. xor qword [local_130h], rax
| | 0x004018ff 488b8540ffff. mov rax, qword [local_c0h]
| | 0x00401906 483d60960000 cmp rax, 0x9660
| |,=< 0x0040190c 7405 je 0x401913
| ,===< 0x0040190e e99f010000 jmp 0x401ab2
| ||| ; JMP XREF from 0x0040190c (stage_2)
| ||`-> 0x00401913 488d9540ffff. lea rdx, [local_c0h]
| || 0x0040191a 488b85d8feff. mov rax, qword [local_128h]
| || 0x00401921 4889d6 mov rsi, rdx
| || 0x00401924 4889c7 mov rdi, rax
| || 0x00401927 e8c4f4ffff call sym.imp.statfs
| || 0x0040192c 8985ccfeffff mov dword [local_134h], eax
| || 0x00401932 83bdccfeffff. cmp dword [local_134h], 0
| ||,=< 0x00401939 7405 je 0x401940
| ,====< 0x0040193b e972010000 jmp 0x401ab2
| |||| ; JMP XREF from 0x00401939 (stage_2)
| |||`-> 0x00401940 488b8540ffff. mov rax, qword [local_c0h]
| ||| 0x00401947 483185d0feff. xor qword [local_130h], rax
| ||| 0x0040194e 488b8540ffff. mov rax, qword [local_c0h]
| ||| 0x00401955 483dea1dad0b cmp rax, 0xbad1dea
| |||,=< 0x0040195b 7405 je 0x401962
| ,=====< 0x0040195d e950010000 jmp 0x401ab2
| ||||| ; JMP XREF from 0x0040195b (stage_2)
| ||||`-> 0x00401962 488d9540ffff. lea rdx, [local_c0h]
| |||| 0x00401969 488b85d8feff. mov rax, qword [local_128h]
| |||| 0x00401970 4889d6 mov rsi, rdx
| |||| 0x00401973 4889c7 mov rdi, rax
| |||| 0x00401976 e875f4ffff call sym.imp.statfs
| |||| 0x0040197b 8985ccfeffff mov dword [local_134h], eax
| |||| 0x00401981 83bdccfeffff. cmp dword [local_134h], 0
| ||||,=< 0x00401988 7405 je 0x40198f
| ,======< 0x0040198a e923010000 jmp 0x401ab2
| |||||| ; JMP XREF from 0x00401988 (stage_2)
| |||||`-> 0x0040198f 488b8540ffff. mov rax, qword [local_c0h]
| ||||| 0x00401996 4883c001 add rax, 1
| ||||| 0x0040199a 483185d0feff. xor qword [local_130h], rax
| ||||| 0x004019a1 488b9540ffff. mov rdx, qword [local_c0h]
| ||||| 0x004019a8 b8114afeca mov eax, 0xcafe4a11
| ||||| 0x004019ad 4839c2 cmp rdx, rax
| |||||,=< 0x004019b0 0f85fc000000 jne 0x401ab2
| |||||| 0x004019b6 bf21000000 mov edi, 0x21 ; '!' ; 33
| |||||| 0x004019bb e860f6ffff call sub.malloc_20 ; void *malloc(size_t size)
| |||||| 0x004019c0 488905b11720. mov qword [0x00603178], rax ; [0x603178:8]=0
| |||||| 0x004019c7 c70573172000. mov dword [0x00603144], 0 ; [0x603144:4]=1
Well statfs
is a function which gets the statistics of the file system , from man
SYNOPSIS
#include <sys/vfs.h> /* or <sys/statfs.h> */
int statfs(const char *path, struct statfs *buf);
int fstatfs(int fd, struct statfs *buf);
DESCRIPTION
The statfs() system call returns information about a mounted filesystem. path is the pathname of any file within the mounted filesystem.
buf is a pointer to a statfs structure defined approximately as follows:
On every call of the statfs
same argument are passed and the return of every should satisfy the uniq condition ,
The return this is xor with a local_130h
, actually the return is the file system type , all file system contains a uniq magic number
BPF_FS_MAGIC 0xcafe4a11
HOSTFS_SUPER_MAGIC 0x00c0ffee
ISOFS_SUPER_MAGIC 0x9660
To bypass this stage, i set the RIP from the first comparison to the last and set the local_130h
with appropriate value after all the xor of the return value , I not sure this is the right method , but it does the trick
Next !
.----------------------------------------------.
| 0x40211d ;[gm] |
| ; JMP XREF from 0x004020fd (main) |
| mov edi, 0x6031a0 |
| call sym.imp.pthread_mutex_lock;[gf] |
| ; 0x402548 |
| mov edi, str._e_36m______Launching_stage_3_e |
| call sub.printf_fed;[gg] |
| mov edi, 0x6031a0 |
| call sym.imp.pthread_mutex_unlock;[gh] |
| lea rax, [local_50h] |
| lea rdx, [local_120h] |
| ; 16 |
| lea rdi, [rdx + 0x10] |
| mov ecx, 0 |
| mov edx, 0x4015db |
| ... |
`----------------------------------------------'
Here we have to input a Password ,
Fist some strings are loaded to the stack
mov qword [local_20h], str.psscr
mov qword [local_18h], str.auwod
mov qword [local_10h], str.snoli
There is a string length is compared with 0xf
mov rax, qword [input]
add rax, 0xf
mov byte [rax], 0
mov rax, qword [input]
mov rdi, rax
call sym.imp.strlen;[gj]
after there is a loop which check the input with strings on the stack , the three stings are selected according to the index of the input and is checked , well i did it in the long way of using gdb extracting characters from the comparison , I need to learn to script in gdb ! .
| 0x00401678 c745dc000000. mov dword [count], 0
| ,=< 0x0040167f e952010000 jmp 0x4017d6
| | ; JMP XREF from 0x004017da (fcn.004015db)
| .--> 0x00401684 8b4ddc mov ecx, dword [count]
| || 0x00401687 ba56555555 mov edx, 0x55555556
| || 0x0040168c 89c8 mov eax, ecx
| || 0x0040168e f7ea imul edx
| || 0x00401690 89c8 mov eax, ecx
| || 0x00401692 c1f81f sar eax, 0x1f
| || 0x00401695 29c2 sub edx, eax
| || 0x00401697 89d0 mov eax, edx
| || 0x00401699 89c2 mov edx, eax
| || 0x0040169b 01d2 add edx, edx
| || 0x0040169d 01c2 add edx, eax
| || 0x0040169f 89c8 mov eax, ecx
| || 0x004016a1 29d0 sub eax, edx
| || 0x004016a3 83f801 cmp eax, 1 ; 1
| ,===< 0x004016a6 7472 je 0x40171a
| ||| 0x004016a8 83f802 cmp eax, 2 ; 2
| ,====< 0x004016ab 0f84c7000000 je 0x401778
| |||| 0x004016b1 85c0 test eax, eax
| ,=====< 0x004016b3 0f8519010000 jne 0x4017d2
| ||||| 0x004016b9 8b45dc mov eax, dword [count]
| ||||| 0x004016bc 4863d0 movsxd rdx, eax
| ||||| 0x004016bf 488b45f8 mov rax, qword [input]
| ||||| 0x004016c3 4801d0 add rax, rdx ; '('
| ||||| 0x004016c6 0fb630 movzx esi, byte [rax]
| ||||| 0x004016c9 8b4ddc mov ecx, dword [count]
| ||||| 0x004016cc ba56555555 mov edx, 0x55555556
| ||||| 0x004016d1 89c8 mov eax, ecx
| ||||| 0x004016d3 f7ea imul edx
| ||||| 0x004016d5 89c8 mov eax, ecx
| ||||| 0x004016d7 c1f81f sar eax, 0x1f
| ||||| 0x004016da 29c2 sub edx, eax
| ||||| 0x004016dc 89d0 mov eax, edx
| ||||| 0x004016de 8d0c00 lea ecx, [rax + rax]
| ||||| 0x004016e1 ba67666666 mov edx, 0x66666667
| ||||| 0x004016e6 89c8 mov eax, ecx
| ||||| 0x004016e8 f7ea imul edx
| ||||| 0x004016ea d1fa sar edx, 1
| ||||| 0x004016ec 89c8 mov eax, ecx
| ||||| 0x004016ee c1f81f sar eax, 0x1f
| ||||| 0x004016f1 29c2 sub edx, eax
| ||||| 0x004016f3 89d0 mov eax, edx
| ||||| 0x004016f5 c1e002 shl eax, 2
| ||||| 0x004016f8 01d0 add eax, edx
| ||||| 0x004016fa 29c1 sub ecx, eax
| ||||| 0x004016fc 89ca mov edx, ecx
| ||||| 0x004016fe 4863d2 movsxd rdx, edx
| ||||| 0x00401701 488b45e0 mov rax, qword [psscr]
| ||||| 0x00401705 4801d0 add rax, rdx ; '('
| ||||| 0x00401708 0fb600 movzx eax, byte [rax]
| ||||| 0x0040170b 4038c6 cmp sil, al
| ,======< 0x0040170e 7405 je 0x401715
| ,=======< 0x00401710 e905010000 jmp 0x40181a
| |||||!| ; JMP XREF from 0x0040170e (fcn.004015db)
| =`------> 0x00401715 e9b8000000 jmp 0x4017d2
| | |||!| ; JMP XREF from 0x004016a6 (fcn.004015db)
| | ||`---> 0x0040171a 8b45dc mov eax, dword [count]
| | || || 0x0040171d 4863d0 movsxd rdx, eax
| | || || 0x00401720 488b45f8 mov rax, qword [input]
| | || || 0x00401724 4801d0 add rax, rdx ; '('
| | || || 0x00401727 0fb630 movzx esi, byte [rax]
| | || || 0x0040172a 8b4ddc mov ecx, dword [count]
| | || || 0x0040172d ba56555555 mov edx, 0x55555556
| | || || 0x00401732 89c8 mov eax, ecx
| | || || 0x00401734 f7ea imul edx
| | || || 0x00401736 89c8 mov eax, ecx
| | || || 0x00401738 c1f81f sar eax, 0x1f
| | || || 0x0040173b 29c2 sub edx, eax
| | || || 0x0040173d 89d0 mov eax, edx
| | || || 0x0040173f 8d0c00 lea ecx, [rax + rax]
| | || || 0x00401742 ba67666666 mov edx, 0x66666667
| | || || 0x00401747 89c8 mov eax, ecx
| | || || 0x00401749 f7ea imul edx
| | || || 0x0040174b d1fa sar edx, 1
| | || || 0x0040174d 89c8 mov eax, ecx
| | || || 0x0040174f c1f81f sar eax, 0x1f
| | || || 0x00401752 29c2 sub edx, eax
| | || || 0x00401754 89d0 mov eax, edx
| | || || 0x00401756 c1e002 shl eax, 2
| | || || 0x00401759 01d0 add eax, edx
| | || || 0x0040175b 29c1 sub ecx, eax
| | || || 0x0040175d 89ca mov edx, ecx
| | || || 0x0040175f 4863d2 movsxd rdx, edx
| | || || 0x00401762 488b45e8 mov rax, qword [auwod]
| | || || 0x00401766 4801d0 add rax, rdx ; '('
| | || || 0x00401769 0fb600 movzx eax, byte [rax]
| | || || 0x0040176c 4038c6 cmp sil, al
| | ||,===< 0x0040176f 7405 je 0x401776
| |,======< 0x00401771 e9a4000000 jmp 0x40181a
| |||||!| ; JMP XREF from 0x0040176f (fcn.004015db)
| ====`---> 0x00401776 eb5a jmp 0x4017d2
| |||| !| ; JMP XREF from 0x004016ab (fcn.004015db)
| |||`----> 0x00401778 8b45dc mov eax, dword [count]
| ||| || 0x0040177b 4863d0 movsxd rdx, eax
| ||| || 0x0040177e 488b45f8 mov rax, qword [input]
| ||| || 0x00401782 4801d0 add rax, rdx ; '('
| ||| || 0x00401785 0fb630 movzx esi, byte [rax]
| ||| || 0x00401788 8b4ddc mov ecx, dword [count]
| ||| || 0x0040178b ba56555555 mov edx, 0x55555556
| ||| || 0x00401790 89c8 mov eax, ecx
| ||| || 0x00401792 f7ea imul edx
| ||| || 0x00401794 89c8 mov eax, ecx
| ||| || 0x00401796 c1f81f sar eax, 0x1f
| ||| || 0x00401799 29c2 sub edx, eax
| ||| || 0x0040179b 89d0 mov eax, edx
| ||| || 0x0040179d 8d0c00 lea ecx, [rax + rax]
| ||| || 0x004017a0 ba67666666 mov edx, 0x66666667
| ||| || 0x004017a5 89c8 mov eax, ecx
| ||| || 0x004017a7 f7ea imul edx
| ||| || 0x004017a9 d1fa sar edx, 1
| ||| || 0x004017ab 89c8 mov eax, ecx
| ||| || 0x004017ad c1f81f sar eax, 0x1f
| ||| || 0x004017b0 29c2 sub edx, eax
| ||| || 0x004017b2 89d0 mov eax, edx
| ||| || 0x004017b4 c1e002 shl eax, 2
| ||| || 0x004017b7 01d0 add eax, edx
| ||| || 0x004017b9 29c1 sub ecx, eax
| ||| || 0x004017bb 89ca mov edx, ecx
| ||| || 0x004017bd 4863d2 movsxd rdx, edx
| ||| || 0x004017c0 488b45f0 mov rax, qword [snoli]
| ||| || 0x004017c4 4801d0 add rax, rdx ; '('
| ||| || 0x004017c7 0fb600 movzx eax, byte [rax]
| ||| || 0x004017ca 4038c6 cmp sil, al
| ||| ,===< 0x004017cd 7402 je 0x4017d1
| |||,====< 0x004017cf eb49 jmp 0x40181a
| |||||!| ; JMP XREF from 0x004017cd (fcn.004015db)
| ||||`---> 0x004017d1 90 nop
| |||| !| ; JMP XREF from 0x004016b3 (fcn.004015db)
| |||| !| ; JMP XREF from 0x00401715 (fcn.004015db)
| |||| !| ; JMP XREF from 0x00401776 (fcn.004015db)
| --`-----> 0x004017d2 8345dc01 add dword [count], 1
| || | !| ; JMP XREF from 0x0040167f (fcn.004015db)
| || | |`-> 0x004017d6 837ddc0e cmp dword [count], 0xe ; [0xe:4]=-1 ; 14
| || | `==< 0x004017da 0f8ea4feffff jle 0x401684
| || | 0x004017e0 c7055e192000. mov dword [0x00603148], 0 ; [0x603148:4]=1
| || | 0x004017ea 488b45f8 mov rax, qword [input]
| || | 0x004017ee 4889058b1920. mov qword [0x00603180], rax ; [0x603180:8]=0
| || | 0x004017f5 bfa0316000 mov edi, 0x6031a0
| || | 0x004017fa e8a1f6ffff call sym.imp.pthread_mutex_lock
| || | 0x004017ff bf68244000 mov edi, str._e_32m____Key_x_is_correct_e_0m_n ; 0x402468
| || | 0x00401804 e8e4f7ffff call sub.printf_fed ; int printf(const char *format)
| || | 0x00401809 bfa0316000 mov edi, 0x6031a0
| || | 0x0040180e e8adf6ffff call sym.imp.pthread_mutex_unlock
| || | 0x00401813 b800000000 mov eax, 0
| || | ,=< 0x00401818 eb46 jmp 0x401860
| || | | ; JMP XREF from 0x00401651 (fcn.004015db)
| || | | ; JMP XREF from 0x00401673 (fcn.004015db)
| || | | ; JMP XREF from 0x00401710 (fcn.004015db)
| || | | ; JMP XREF from 0x00401771 (fcn.004015db)
| || | | ; JMP XREF from 0x004017cf (fcn.004015db)
| ``-`----> 0x0040181a c7051c192000. mov dword [0x00603140], 1 ; [0x603140:4]=1
| | 0x00401824 c70516192000. mov dword [0x00603144], 1 ; [0x603144:4]=1
| | 0x0040182e c70510192000. mov dword [0x00603148], 1 ; [0x603148:4]=1
| | 0x00401838 c7050a192000. mov dword [0x0060314c], 1 ; [0x60314c:4]=1
| | 0x00401842 bfa0316000 mov edi, 0x6031a0
| | 0x00401847 e854f6ffff call sym.imp.pthread_mutex_lock
| | 0x0040184c bf88244000 mov edi, str._e_31m____Key_x_is_incorrect_e_0m_n ; 0x402488
| | 0x00401851 e897f7ffff call sub.printf_fed ; int printf(const char *format)
| | 0x00401856 bfa0316000 mov edi, 0x6031a0
| | 0x0040185b e860f6ffff call sym.imp.pthread_mutex_unlock
| | ; JMP XREF from 0x00401818 (fcn.004015db)
| `-> 0x00401860 c9 leave
\ 0x00401861 c3 ret
Password is : passwordisuncolo
Stage 4 Here I Come !
mov byte [local_20h], 8
; '^'
mov byte [local_1fh], 0x5e
; '\'
mov byte [local_1eh], 0x5c
mov byte [local_1dh], 0
mov byte [local_1ch], 0x14
mov byte [local_1bh], 0
; 0x40242a
; "ARCTYPE"
mov edi, str.ARCTYPE
call sym.imp.getenv;[ga]
mov qword [local_28h], rax
cmp qword [local_28h], 0
je 0x401479;[gb]
Here a environmental variable named ARCTYPE is read , then the len is checked if it is 5 , after that the input is xor with a predefined key which is pushed onto the stack on the beginning and it is checked with amd64 , it turn’s out the input should be “i386 “
key = [8,0x5e,0x5c,0,0x14]
flag = "amd64"
result = ""
for i in range(0,len(key)):
for j in range(0,256):
if key[i] ^ j == ord(flag[i]):
result+=chr(j)
break
So we have to set this variable before executing
For the last Check the a value at the memory address 0x00603150
is checked and i patched this location in binary using radare , to 0 which is the required condition
(gdb) set environment export ARCTYPE="i386 "
(gdb) set environment LD_PRELOAD=./uid_evil.so
(gdb) b * 0x004018ea
Breakpoint 1 at 0x4018ea
(gdb) r
Starting program: /home/nemesis/Downloads/rev
/bin/bash: cannot set uid to -1: effective uid 0: Invalid argument
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[↑] Launching stage 1
[New Thread 0x7ffff701a700 (LWP 15633)]
[↑] Launching stage 2
[*] Key x is correct
[New Thread 0x7fffee819700 (LWP 15634)]
[Thread 0x7ffff701a700 (LWP 15633) exited]
[↑] Launching stage 3
[New Thread 0x7ffff6819700 (LWP 15635)]
Enter password: [Switching to Thread 0x7fffee819700 (LWP 15634)]
Thread 3 "rev" hit Breakpoint 1, 0x00000000004018ea in ?? ()
(gdb) x/10i $rip
=> 0x4018ea: je 0x4018f1
0x4018ec: jmp 0x401ab2
0x4018f1: mov rax,QWORD PTR [rbp-0xc0]
0x4018f8: xor QWORD PTR [rbp-0x130],rax
0x4018ff: mov rax,QWORD PTR [rbp-0xc0]
0x401906: cmp rax,0x9660
0x40190c: je 0x401913
0x40190e: jmp 0x401ab2
0x401913: lea rdx,[rbp-0xc0]
0x40191a: mov rax,QWORD PTR [rbp-0x128]
(gdb) set $rip=0x004019b6
(gdb) x/x $rbp-0x130
0x7fffee818e20: 0x00000000
(gdb) set {int} 0x7fffee818e20 = 0xc153c198
(gdb) c
Continuing.
passwordisuncolo
[*] Key x is correct
[*] Key x is correct
[↑] Launching stage 4
[New Thread 0x7ffff6018700 (LWP 21142)]
[Thread 0x7ffff6819700 (LWP 15635) exited]
[Thread 0x7fffee819700 (LWP 15634) exited]
[*] Key x is correct
[Thread 0x7ffff6018700 (LWP 21142) exited]
Entering the last check:
[*] Key x is correct
flag{...}
[Inferior 1 (process 15580) exited normally]
(gdb)
and there goes the flag