|
|
- Có 1 mảng kí tự, viết hàm đảo ngược chuỗi mà không dùng biến tạm
Nếu như theo mình hiểu thì có 1 data structure là array of char a[0..n]
Như vậy thì đảo ngược chỉ là swap a[i], a[n-i] for i:0->n/2 thêm xử lý n chẵn + lẻ là ok
swap ko sử dụng biến tạm thì như rickb, không thì
a=a+b
b=a-b
a=a-b
dễ hình dung hơn
Trả lời như vậy có đạt yêu cầu không anh Z0rro ?
|
|
|
mackhach wrote:
Mình muốn hỏi là hiện nay thì có những dạng mã hóa Pass Admin nào, và dạng mã hóa pass nào là an toàn nhất cho site của mình. Chứ mình thấy mã hóa bằng md5 thì không khó lắm đối với attacker.
Mong các bạn góp ý kiến dùm, chứ mình search ở google thì thấy nói chung chung quá
Có gì thiếu sót thì bỏ quá cho, vì mình thấy vấn đề này 4rum cũng đã bàn nhiều rồi...
Thank you
Bạn thấy md5 có nhược điểm nào ? Bạn cần "dạng mã hóa" có những đặc tính như thế nào?
|
|
|
StarGhost wrote:
@Z0rr0: Mình thấy có câu "đảo ngược chuỗi mà không dùng biến tạm" rất là hay, nhưng mà có vẻ hơi khoai khi mà hỏi phỏng vấn. Mình ngồi nghĩ 15 phút mới ra được 1 cách recursion, dưng mà lại tốn kém cả về bộ nhớ lẫn tính toán. Kiểu này đi phỏng vấn chắc trượt quá.
Mình nghĩ cũng không phải là khoai lắm, lúc học algorithm thì mấy cái như swap 2 số không cần biến tạm được dạy hết rồi
|
|
|
http://lmgtfy.com/?q=data+link+layer+error+control
Có gì không hiểu post lên đây hỏi
|
|
|
StarGhost wrote:
Còn khái niệm PC ảo và vật lý, thì nói thật là đây là lần đầu mình nghe thấy. Mình cho rằng PC chỉ có một cái, và là cái PC của CPU. Bạn đã nói rằng PC chứa virtual address, tức là CPU chỉ biết đến virtual address thì làm sao mà quản lý được địa chỉ vật lý của RAM?
Không muốn chen ngang phần tranh luận đang gay cấn nhưng mà mình thấy chỗ này thì StarGhost vặn kinh quá... nếu nói thế thì phải xem lại khái niệm "quản lý" là thế nào ?
Ví dụ như cần làm việc X
anh A là sếp quản lý anh B, A ra lệnh anh B làm việc X rồi don't care anh B làm thế nào miễn là anh B ra kết quả là được,
hay là anh A còn phải cho anh B biết việc X gồm có các bước x1,x2,x3,x4,x5... rồi anh B cứ theo thế mà làm ?
À hỏi luôn câu này cũng khá thú vị ) , nếu VAddress gần nhau thì PAddress có gần nhau không ( có relative to không ? )
|
|
|
khanhqhi wrote:
Theo em thì OS quản lý HDD theo từng block một. Ví dụ như nó coi thư mục hoặc file là một inode trong đó nếu inode đó là thư mục thì inode đó sẽ chứa địa chỉ của các inode khác (inode khác ở đây có thể là địa chỉ inode của file hoặc là của thư mục con của nó). Nếu inode là file thì nó sẽ chứa địa chỉ(địa chỉ vật lý thật) của các block (kích thước mỗi block thì e cũng không rõ lắm khoảng vài KB hay sao đó) các block này chứa dữ liệu. (Em học nguyên lý hệ điều hành thấy thế không biết phải không )
Quản lý từng block một nhưng mà không có nghĩa là đếm 1,2,3... mỗi block nó có địa chỉ riêng, và địa chỉ của nó thì OS sẽ quyết định,nó thì chính là mấy cái CHS. Ví dụ như de-fragmentation chẳng hạn, đó là việc OS dịch chuyển data về các vị trí gần nhau, để khi access sẽ nhanh hơn vì HDD không cần phải quay nhiều vòng quá.
Khái niệm quản lý này cũng hơi "mơ hồ"... vì thật ra ở từng lớp của kiến trúc máy tính đều có sự liên hệ từ lớp trên xuống lớp dưới. User click -> OS thực hiện -> CPU dịch, ra lệnh cho các thiết bị v.v.., nên lúc trả lời mình nghĩ cần xác định rõ đang nhìn trên khía cạnh ở lớp nào, nếu nhìn từ user->OS thì rõ ràng là OS có thể tác động đến address của data trên bộ nhớ ngoài (vd HDD) một cách indirect.
|
|
|
Hm... hỏi khó quá bạn, làm sao so sánh "batch file" với "lập trình C" được ? một cái là file, một cái là "lập trình"...
Nếu so sánh "batch file" vs "C file" thì Batch File nôm na là một file gồm chuỗi các lệnh sẽ được interpret ( thông dịch ) bởi Window command interpreter ( ví dụ như cmd.exe, command.com v.v..)
Còn "C file" là một text file được viết = ngôn ngữ lập trình C, file này sẽ được compile (biên dịch) bởi compiler ( vd : gcc ) chuyển sang mã máy có thể thực hiện bởi hệ điều hành.
So sánh "lập trình trên Batch" và "lập trình C" thì cơ bản là lập trình nào thì cũng giống nhau cả, phải biết data structure, algorithm. Tuy nhiên xét mặt ngôn ngữ thì batch bị giới hạn bời các tập lệnh có sẵn của command nên không thể làm được nhiều việc như C được.
(làm được gì thì mời bạn từ từ tìm hiểu)
==> Kết luận chung vẫn là tùy mục đích sử dụng mà chọn ngôn ngữ làm việc cho phù hợp.
ga_le_te wrote:
Mà nhân tiện các anh, chị có thể chỉ giúp em cách học C hiệu quả được không ạ? em học mãi mà vẫn thấy khó khăn quá.
Khó chỗ nào ? Đọc và thực hành từ từ sẽ thành thạo, practice makes perfect.
Thân,
wd.
|
|
|
Reinstall TCP/IP thử
http://www.petri.co.il/reinstall_tcp_ip_on_windows_xp.htm
|
|
|
baothu wrote:
Kihote wrote:
@lamer
Anh Nam giải thích dùm cho độc giả xíu .Sao lại chọn hình con ốc sên làm bìa .Cái đoạn ngoác miệng ngạc nhiên vì vỏ nó bị nứt thì cũng hiểu ,nhưng sao lại là .ốc sên nhỉ Anh ám chỉ phần mềm chạy chậm do lỗi hay là sao ? .
ốc sên - động vật thân "mềm" ~ phần mềm
cái vỏ - tượng trưng cho một lỗi nào đó của phần mềm (mà lập trình viên ảo tưởng nó rất vững chắc)
vỏ bị vỡ,lộ phần mềm -> nguy hiểm rất cao
chắc là thế
) mình đoán thế này:
shell = vỏ (ốc)
|
|
|
Mình quen xài VIM có sẵn trên nix sử dụng lâu thấy rất hiệu quả. Add thêm ctags, là có cả auto-complete trọn bộ
Syntax highlight có sẵn, auto-compile với phím tắt manually set, project management, tab .... Sau một thời gian sử dụng thấy code rất nhanh, không cần sử dụng chuột. Nhược điểm là không user-friendly lắm
Nếu cần mì ăn liền thì Eclipse/Netbeans rất tốt, chỉ cần thêm vài cái plug-in của C++ là okie, chạy cứ gọi là ầm ầm.
|
|
|
Thử làm theo cái này
http://www.webmaster-forums.net/server-management/could-not-get-lock-varlibdpkglock-open-11-resource-temporarily-unavailable-error-d
Nếu không được bạn có thể chạy lệnh này
Code:
rồi đưa kết quả lên đây không ?
|
|
|
sorry em không hiểu ý anh PD, em thấy đoạn anh quote chỉ ra rằng người thiết kế protocol đã rất cẩn thận lưu ý developer khi xử dụng chung với IMAP, POP3 and ACAP, tuy vậy những cảnh báo đó không có trong bản RFC với HTTP (?!? http://tools.ietf.org/html/rfc2818)
MitM dù có thể có cer của client và auth với server, nhưng nếu client và server trong TLS state (đã negotiate và trao đổi key xong) thì attacker cũng không thể fake client dc vì không có correct key.
Em cũngg cùng chung suy nghĩ này với StarGhost
StarGhost wrote:
Về mặt nguyên tắc thì toàn bộ communication phải được bound với credentials, bao gồm cả requests lẫn replies
|
|
|
StarGhost wrote:
1) việc gắn 2 messages không phải do attacker làm, mà là do server làm.
Oh mình hiểu việc này chứ ...
Lúc đầu đọc ở trên bài của mrro mình nghĩ là trong trường hợp 3 khác ở chỗ là attacker không cần connect đến server trước, nhưng thật ra việc này không thể được, vì nếu attacker không connect thì sẽ không có session key giữa attacker vs server. Do đó server không thể decrypt cái msg "GET ..." mà attacker send.
Vừa rồi đọc kỹ lại paper bằng tiếng Anh và nghiền ngẫm cái ở trên mới biết mình hiểu nhầm ý mrro.
Thật ra 2 và 3 chỉ khác ở chỗ, ở 3, attacker chủ động gửi re-negotiation request đến server, thay vì kích hoạt server gửi.
Scenario: Client-initiated renegotiation
TLS equally allows the client side of the connection to initiate a renegotiation. This case
is perhaps more attractive to the attacker because he does not need to elicit a Hello
Request from the server, so no particular server-side configuration is required for this
attack to succeed.
In the HTTPS domain, a practical attack involves the MITM splicing an initial request
with an un-terminated HTTP “ignore” header onto the beginning of the client's intended
request, again stealing whatever authentication or authorization information provided.
Note that this does not require pipelining or HTTP keep-alive. In all other respects, the
server sees the same sort of request buffer as above.
Trong paper, tác giả còn đề cập đến 1 số cách giải quyết problem này
- trước khi client muốn request bất cứ thứ gì thì phải trình certificate ra (server ignore mọi thứ trước đó ??)
- thêm session ID vào việc re-negotiation
- sửa đổi cách thức làm việc giữa HTTP và TSL
- client phải authenticate server trước khi send certificate cho server ( cái này chưa hiểu lắm anh mrro có thể giải thích không ? )
Mọi người có thể thảo luận và cùng tìm hiểu thêm
|
|
|
Thanks anh mrro đã post 1 topic rất hay.
Em có vài điều thắc mắc
1) Ở hướng tấn công thứ 3 :
Ý tưởng thực hiện tấn công rất giống với hướng 2, chỉ khác nhau ở bước số 2, attacker sẽ không gửi GET /iphone/login nữa mà gửi trực tiếp luôn request của hắn, kèm theo một cái "X-ignore-this" header.
Lúc này attacker chưa có kết nối với server, vậy lấy đâu ra session key để server decrypt cái msg này mà gắn vào phần của client ?
2) Em thấy cái cách tấn công 2 và 3 không hẳn là bug về design của TSL protocol, mà là bug của implementation nhiều hơn. Ví dụ như các vấn đề về buffer này nọ, không có thấy đề cập trong design ? ( !??! vừa đọc thử cái spec, không thấy nói về vấn đề này )
p/s Cái link trên hình như die rồi, em tìm thấy cái khác ở đây : http://packetstormsecurity.org/0911-advisories/Renegotiating_TLS.pdf
|
|
|
hidetran wrote:
Mình đang học về hoán vị và tổ hợp có lặp !
Các bạn cho mình hỏi về thuật toán tìm các chỉnh hợp có lặp của 1 xâu ký tự nhé !
Ví dụ - Xâu : DVT thì có các chỉnh hợp là:
1: DVT
2: DTV
3: VDT
4: VTD
5: TVD
6: TDV
Cái quan trọng là tìm ra được thuật toán !
Bài tập này cũng mong các cao thủ Pascal xem giúp !
Cảm ơn các bạn nhé !
Bạn có hiểu : tổ hợp, hoán vị, chỉnh hợp là gì chưa thế ?
Nếu như dãy ở trên in ra thì nó không phải là "chỉnh hợp" và thông tin của bạn cũng chưa đủ để xác định "chỉnh hợp" nếu đúng theo ý nghĩa của nó.
Bạn xem lại các định nghĩa rồi đặt vấn đề lại nhé
wd.
|
|
|
GDB – Cheatsheet : Những lệnh hay dùng của GDB
Mình là fan của gdb, mình đã sử dụng nó cho hầu hết các project trên linux của mình, tuy chỉ là command based nhưng rất hữu dụng nếu sử dụng hợp lý, ngoài là công cụ debug nếu sử dụng đúng gdb là công cụ reverse code rất hữu hiệu. Dò trên 4rum chưa thấy có bài nào viết, mình xin chia xẻ chút kinh nghiệm.
Do thời gian có hạn, nên mình sẽ chỉ viết những lệnh mình thấy hữu dụng nhất mà mình cảm nhận quá trình làm việc. Bạn nào biết lệnh nào “lợi hại” xin post chung vào topic này, mình sẽ update.
Quy định trong bài viết :
$ xyz : lệnh xyz được ví dụ khi thực hiện trên shell (bash,sh,ksh...). Để thử nghiệm, type xyz và nhấn ENTER
(gdb) zyx : lệnh zyx được ví dụ khi thực hiện bên trong GDB ( sau khi khởi động ). Để thử nghiệm, type zyx trong gdb và nhấn ENTER. ( Một số lệnh đòi hỏi gdb phải attach vào chương trình trước xin xem ở dưới )
1) Khởi động gdb
a) Cách 1:
gdb [--args] path_đến_program : khởi động gdb và set file cần debug ngay lập tức. Nêu cần khai báo tham số cho program thì sử dụng --args ở phía trước gdb
Code:
$ gdb helloworld
$ gdb ls
$ gdb --arg /bin/ls –al
b) Cách 2:
gdb : khởi động gdb không dùng tham số gì cả, bạn sẽ vào trong phần làm việc của gdb.
file [path đến program]: gõ lệnh này trong phần làm việc của gdb để chọn program cần debug.
Code:
Lưu ý cách 2 này bạn không thể khai báo tham số trước cho chương trình. ( Xem tiếp để biết làm cách nào add tham số. )
*** Để thoát khỏi gdb :
(gdb) quit
2) Kích hoạt chương trình:
run [args] : kích hoạt chương trình đang được “để ý” bởi gdb. [args] là tham số cần để chương trình chạy
Code:
(gdb) File ls
(gdb) Run –al
3) Xem code của chương trình
Để xem được source code của chương trình ngay trong gdb, bạn phải compile chương trình bằng cách thêm tham số debug : -g để compiler sinh ra debugging information, tiện cho việc debug hiệu quả. Xem thêm ở đây : http://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html
Code:
$ gcc –g –gdb –o xxx xxx.c
Sau đó trong gdb bạn có thể sử dụng lệnh "list" để xem source code của chương trình đang debug:
list [File:]line_number : xem code tại 1 dòng xác định, ( trong trường hợp có nhiều file thêm vào thông số [File:].
list [File:]Function : tương tự như trên nhưng xem tại điểm bắt đầu của hàm Funtion.
list : nếu không có tham số nào thì list sẽ cho xem source vị trí hiện tại đang debug. Nếu gõ liên tiếp sẽ cho xem các dòng tiếp sau đó.
Trong trường hợp bạn muốn debug 1 file binary mà không có source code. Sử dụng:
disassemble FUNC
Code:
disassemble MEM1 MEM2: disassemble từ memory address MEM1 đến memory address MEM2
Code:
(gdb) disassemble 0xbfffbbbb 0xbfffcccc
*** Lưu ý assembly mà gdb tại ra là dạng AT&T, i.e destination đứng sau source:
mov 0x0 %eax <-- eax = 0
4) Break Point và Watch Point:
- BreakPoint:
Khi chạy chương trình, bạn muốn chương trình của bạn dừng lại ở một số đoạn nào để debug. Bạn sử dụng lệnh: break. Cú pháp tương tự như lệnh list
break [File:]line_number
Code:
break [File:]Function
Code:
break *MEM : dừng lại khi execute đến memory address MEM ( hữu dụng khi làm việc với binary file)
Code:
- Watch Point:
Sử dụng watch point khi muốn theo dõi 1 variable / expression, dừng chương trình khi nó thay đổi.
Code:
(gdb) watch i
(gdb) watch src.data == des.data
5) Để xem các bạn đã có những breakpoints / watchpoints nào :
info breakpoints
Để xóa 1 breakpoint/watchpoint:
delete breakp_id/watch_id ( xem id bằng lệnh info )
Disable/Enable 1 breakpoint/watchpoint:
disable breakpoints [breakp_id] ( nếu không đề cập breakp_id thì toàn bộ sẽ bị disable )
enable breakpoints [breakp_id] ( ngược lại với disable )
6) Condition: Bạn có thể thêm condition cho breakpoint/watchpoint. Khi đó chương trình sẽ chỉ dừng lại ở vị trí đã set nếu như condition của bạn có giá trị true. Cú pháp:
Condition breakp_id / watch_id expression
Code:
(gdb) condition 1 x==y && x==999
( x và y là variable của chương trình )
7) Program flow : sau khi break bạn có thể bắt gdb execute từng dòng code theo program của mình
step over : next
step in : step
continue : continue
Nếu execute theo instruction:
step over: nexti
step in: stepi
Để xem mình đang ở đâu trong program, được gọi bởi function nào :
where
backtrace
Code:
Program received signal SIGINT, Interrupt.
0xb75ebc32 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
(gdb) where
#0 0xb75ebc32 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
#1 0xb756c1f3 in __read_nocancel () from /lib/tls/libc.so.6
#2 0x080b2c0c in rl_getc ()
#3 0x080b2bcb in rl_read_key ()
#4 0x080a3a08 in readline_internal_char ()
#5 0x080a3bc5 in readline_internal_char ()
#6 0x080a3bf0 in readline_internal_char ()
#7 0x080a378a in readline ()
#8 0x0805db45 in yy_input_name ()
#9 0x08082ad0 in termination_unwind_protect ()
= )) có ai biết mình đang trace cái j không ?
8) Xem và cập nhật giá trị các biến, thanh ghi và bộ nhớ :
Để xem giá trị các biến : sử dụng print variable
Code:
(gdb) print i
(gdb) print inst.data
Để xem giá trị ô nhớ : x[/[cout][format][size]] memory
(gdb) x 0x12345678
(gdb) x/20 0x12345678 : xem 20 ô liên tiếp bắt đầu từ 0x12345678
(gdb) x/20xb 0x12345678 : xem 20 ô liên tiếp dưới dạng hex và in ra từng byte.
[format]: o(octal), x(hex), d(decimal), u(unsigned decimal), t(binary), f(float), a(address), i(instruction), c(char), s(string)
[size]: b(byte,1 byte), h(halfword, 2 bytes), w(word, 4 bytes), g(giant, 8 bytes)
Để xem thanh ghi: Tương tự xem ô nhớ, thay memory bằng thanh ghi:
Code:
(gdb) x $eax
(gdb) x $eip
Hoặc sử dụng lệnh :
info register [REG]
Code:
Để cập nhật/ chỉnh sửa các giá trị :
set destination = something
(gdb) set $eax = 1
(gdb) set *(0xbfffdddd) = “windak”
9) Một số tip khác khi sử dụng :
- Shortcut :
Khi sử dụng thành thạo và quen với các lệnh của gdb, bạn có thể bắt đầu sử dụng các lệnh tắt. Gdb cho phép shortcut command bằng cách viết phần prefix của command đó.
(gdb) r <=> (gdb) ru <=> (gdb) run
(gdb) b <=> (gdb) break
(gdb) disass <=> (gdb) disassemble ( lưu ý số prefix phải đủ dài để gdb xác định là lệnh nào)
(gdb) i b <=> (gdb) info break
- Debug program đang chạy ( process ):
gdb [prog] [pid] ( pid = process id, xem thêm lệnh “ps” của linux )
- Xem hướng dẫn của một lệnh
help [command]
(gdb) help break
(gdb) help next
- Sử dụng liên tiếp 1 lệnh
Nhấn Enter trong gdb nếu bạn muốn gdb tiếp tục thực hiện lệnh phía trước. Hữu dụng khi xài chung với "next","nexti","step","stepi","list".
- Thực hiện một số command khi chương trình dừng ở break:
command breakp_id/watch_id
Code:
(gdb) br main
(gdb) command 1
> x $eax
> end
(gdb)
Trên là một số kiến thức cơ bản của gdb mà mình thu thập, khi viết bài không khỏi sai sót mong mọi người cùng đóng góp để hoàn thiện.
Một tài liệu advance nếu bạn hứng thú: Using GNU's GDB Debugger: http://dirac.org/linux/gdb/
References:
$gdb --help
(gdb) help
Thanks,
wd.
|
|
|
Như cái hình folder option của bạn ấy ? thử bấm restore chưa ?
|
|
|
Thế cuối cùng problem của bạn đã dc giải quyết chưa ?
Không thấy nói j sau khi mở regedit bằng cách vào Task manager ?
|
|
|
Xem cái list của bạn tớ không thấy có gì khả nghi, có lẽ virus/worm đã được quét sạch rồi, chỉ có 2 cái này :
O4 - HKCU\..\Run: [Deluxe Tree] C:\Documents and Settings\Thanh Binh\Desktop\Christmas.exe
O4 - HKCU\..\Run: [FreeXmasTree] C:\Documents and Settings\Thanh Binh\Desktop\FreeXmasTree.exe
Nếu nó không phải là của bạn thì nên remove nó đi
Sau đó làm theo hướng dẫn này thử :
http://www.askvg.com/solution-exe-files-always-open-with-notepad-or-other-applications/
wd.
|
|
|
StarGhost wrote:
@puffy: cái vụ seteuid() của bạn mình không đồng ý nhé. Không biết bsd kernel hoạt động ra sao, chứ trong linux thì chả cần seteuid(), chỉ cần SUID bit được set trong file permission thi khi file đó được chạy, euid sẽ tự động được set luôn thành file owner.
Confirm đúng như StarGhost nói khi chạy trên máy mình.
Cũng cám ơn bác puffy, nhờ vậy biết linux != bsd chỗ này, trước giờ tưởng như nhau hệch hệch
Code:
cat test.c
int main(int argc, char* argv[]) {
int a = 1;
int b = 1;
char x = 'A';
char y = 'B';
printf ("Euid : %d, ID: %d \n", geteuid(), getuid());
return 0;
}
....
windak@windak-pc$./test
Euid : 1000, ID: 1000
....
user@windak-pc$./test
Euid : 1000, ID: 1001
Ngoài ra cách xử dụng wrap của StarGhost
Code:
int main(){
execl("/home/user/test","test",0);
return 0;
}
gcc -o wrap wrap.c
ls -al :
Code:
-rwx------ 1 windak windak 6582 2009-10-28 20:27 test
-rws--x--x 1 windak user 6368 2009-10-28 20:31 wrap
cũng rất hiệu quả
Code:
user@windak-pc$./wrap
Euid : 1000, ID: 1001
user@windak-pc$./ptrace
Please wait...
Number of machine instructions : 115862
...
windak@windak-pc$./ptrace
Please wait...
Euid : 1000, ID: 1000
Number of machine instructions : 237642
Thanks các bác
wd.
|
|
|
Hi bác puffy,
Có thể mình sơ xuất trong chuyện seteuid, mình sẽ test lại như bác nói, để xem nếu nó seteuid thì có ptrace từ đầu được không và khi đó thì "test" sẽ có euid là j.
Chỉ confirm lại phát nữa là ở ví dụ trên mình chạy ptrace dưới quyền "user", mà "user" dĩ nhiên không có quyền read cái test, khi ptrace invoke vào "test", "test" cũng không có quyền của "windak"
Thanks.
wd.
|
|
|
StarGhost wrote:
WinDak wrote:
Không phải không thể, như bạn xem kỹ bài ở trên mình vẫn có thể ptrace được SUID program, trong khi ptrace của tớ euid là "user". Vấn đề là khi đó thì euid mình vẫn chỉ là euid của ptrace chứ không được copy từ SUID của process child.
Như vậy thì có gì mâu thuẫn? Nếu bạn gọi ptrace() trước, thì process sẽ không có suid/sgid. Nếu process đã có suid/sgid rồi, thì bạn không thể ptrace() được nữa. Đây là nguyên tắc security cho ptrace().
Có ai nói mâu thuẫn gì đâu , vì chưa hiểu ý StarGhost là sau khi run thì mới ptrace, cái này mình chưa thử, nếu ptrace trước thì sẽ chạy được, như ở trên đã trình bày.
Câu hỏi ở đây là lí do gì ptrace vẫn có khả năng trace vào memory của process ? Nếu protect process memory đi trong trường hợp này thì sẽ hợp lí hơn.
Vừa search ra cái này http://www.quantumg.net/sudojump.php mọi người xem cùng chơi.
wd.
|
|
|
StarGhost wrote:
WinDak wrote:
Một cái nữa mình đã thử là thử fopen(/etc/shadow) khi đang ptrace thì bị block ngay tại trận, như vậy ptrace không care đến cái SUID mà mình đã set.
Không hiểu câu này của bạn. Bạn cơ bản không thể ptrace() được process có suid hoặc sgid, trừ phi process của bạn có euid là root. Một ví dụ điển hình là khi dùng gdb để debug suid/sgid programs.
Không phải không thể, như bạn xem kỹ bài ở trên mình vẫn có thể ptrace được SUID program, trong khi ptrace của tớ euid là "user". Vấn đề là khi đó thì euid mình vẫn chỉ là euid của ptrace chứ không được copy từ SUID của process child.
StarGhost wrote:
Nếu bạn muốn dấu algorithm này kia thì mình có một cách này. Đầu tiên bạn viết program của bạn như bình thường. Sau đó set permission cho nó, ví dụ 700, trong đó owner là bạn. Sau đó bạn viết một suid program khác gọi cái program này (dùng execve()).
Theo lý thuyết đây chắc là 1 cách . Mình sẽ thử nghiệm
Thanks.
wd.
|
|
|
Hi anh lamer,
vậy có phải là không hợp lý không ? Cho dù có sự khác biệt về 2 quyền, vẫn tốt hơn nếu như ta block quyền access memory nếu như không có quyền access tập tin ?
Giải sử mình có 1 tập tin chỉ muốn người khác execute thôi, không muốn bị xem trộm các thông tin bên trong => (datastructure, giải thuật v.v.. ) impossible ?
Nếu có cách nào như vậy xin chỉ dẫn ^^.
Mình nghĩ do thằng ptrace thôi
@gamma : rất có thể là khả năng này, ptrace là kernel function như vậy nghĩa là người develop nó không check quyền của user đang execute ? nếu có thời gian tớ sẽ ngó qua thử cái này.
Một cái nữa mình đã thử là thử fopen(/etc/shadow) khi đang ptrace thì bị block ngay tại trận, như vậy ptrace không care đến cái SUID mà mình đã set.
Kết luận đến đây: Nếu có những thông tin private, cách tốt nhất là tạo file riêng và set permission cho nó, không nên để trong file binary.
wd.
|
|
|
Bạn down cái này về
http://free.antivirus.com/hijackthis/
Chạy scan and log, rồi post cái report lên đây xem
|
|
|
Hi StarGhost,
Mình cũng không nghĩ cái này là bug của Linux mà là do design, chỉ càm thấy nó hơi nonsense và unrational một tí vì vẫn leak được sau khi mà loại bỏ cái read permission đi.
Từ đó vẫn còn thắc mắc trong đầu lý do nào phần code/data segment của nó trong memory lại không được bảo vệ ? Liệu có phải là do khó khăn trong design hay là sự bất cẩn ?
|
|
|
Chào mọi người,
Mấy hôm nay ngồi chơi cái wargame ở io.smashthestack.org, tiện thể tìm hiểu thêm về Linux. Hôm nay mình phát hiện mọi điều khá "thú vị" và cũng hơi bất ngờ... nên share cùng mọi người.
Đầu tiên với account có quyền sysadmin mình tạo 1 file như thế này :
Code:
int main(int argc, char* argv[]) {
int a = 1;
int b = 1;
char x = 'A';
char y = 'B';
return 0;
}
Compile : gcc -o test test.c
Sau đó mình tạo một user mới và copy file "test" này vào home folder của user này, chmod +s và remove read perm chgrp thành user. Sau khi làm xong thì nó trông như thế này :
Code:
-rws--x--x 1 windak user 6255 2009-10-25 02:50 test
Login thử vào bằng user : "user" và "cat test" -> permission denied,
thử gdb :
...(gdb) disass main
...No symbol table is loaded
thử execute ./test -> ok
Như mọi người biết, 1 khi một chương trình được execute thì nó sẽ được load vào memory, như vậy trên lí thuyết nếu ta execute cái binary này và read từ memory ra, ta sẽ có thể dumb được source của nó ==> READ được nó ?!!??
Mình nghi ngờ với khả năng này, do cũng chưa bao h liếc qua cái source kernel... Thế là test thử :
Vẫn là quyền của "user" mình tạo file này :
Code:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <syscall.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/user.h>
#include <unistd.h>
#include <errno.h>
int main(void)
{
long long counter = 0; /* machine instruction counter */
int wait_val; /* child's return value */
int pid; /* child's process id */
puts("Please wait");
struct user_regs_struct regs;
long ins;
switch (pid = fork()) {
case -1:
perror("fork");
break;
case 0: /* child process starts */
ptrace(PTRACE_TRACEME, 0, 0, 0);
execl("/home/user/test", "test", NULL);
break;
/* child process ends */
default:/* parent process starts */
wait(&wait_val);
/*
* parent waits for child to stop at next
* instruction (execl())
*/
while (wait_val == 1407 ) {
counter++;
if (ptrace(PTRACE_SINGLESTEP, pid, 0, 0) != 0)
perror("ptrace");
if (ptrace(PTRACE_GETREGS,pid,0,®s)!=0){
// perror("ptrace");
}
else {
ins = ptrace(PTRACE_PEEKTEXT, pid,
regs.eip, NULL);
printf("Instruction executed: %lx\n", ins);
}
wait(&wait_val);
/* wait for next instruction to complete */
}
/*
* continue to stop, wait and release until
* the child is finished; wait_val != 1407
* Low=0177L and High=05 (SIGTRAP)
*/
}
printf("Number of machine instructions : %lld\n", counter);
return 0;
}
code này mình chép từ đây : http://tldp.org/LDP/LG/issue81/sandeep.html có chỉnh sửa một chút
compile :
gcc -o ptrace ptrace.c
Đoạn code trên của mình thật ra chỉ làm mỗi công việc là debug cái file test sau khi nó được nhét vào memory và in ra nó đang execute đoạn mã nào.
Sau đấy mình run thử
user@windak-pc$ ./ptrace > see
windak@windak-pc$./ptrace > how
Đồng thời trên 1 terminal khác dưới quyền "windak" mình run :
Code:
gdb test
(gdb) disass main
Dump of assembler code for function main:
0x0804831c <main+0>: push %ebp
0x0804831d <main+1>: mov %esp,%ebp
....
0x08048338 <main+28>: movl $0x1,-0x4(%ebp)
0x0804833f <main+35>: movl $0x1,-0x8(%ebp)
0x08048346 <main+42>: movb $0x41,-0x9(%ebp)
0x0804834a <main+46>: movb $0x42,-0xa(%ebp)
0x0804834e <main+50>: mov $0x0,%eax
0x08048353 <main+55>: leave
0x08048354 <main+56>: ret
(gdb) x/20 0x0804831c
0x804831c <main>: 0x83e58955 0xe48318ec 0x0000b8f0 0xc0830000
0x804832c <main+16>: 0x0fc0830f 0xc104e8c1 0xc42904e0 0x01fc45c7
0x804833c <main+32>: 0xc7000000 0x0001f845 0x45c60000 0x45c641f7
0x804834c <main+48>: 0x00b842f6 0xc9000000 0x909090c3 0x90909090
0x804835c: 0x90909090 0x5de58955 0x26748dc3 0x27bc8d00
Và thật ngạc nhiên... mình cũng tìm được đoạn code sau trong cả see và how :
Code:
Instruction executed: 83e58955
Instruction executed: ec83e589
Instruction executed: 8318ec83
Instruction executed: b8f0e483
Instruction executed: b8
Instruction executed: 830fc083
Instruction executed: c10fc083
Instruction executed: c104e8c1
Instruction executed: 2904e0c1
Instruction executed: 45c7c429
Instruction executed: 1fc45c7
Instruction executed: 1f845c7
Instruction executed: 41f745c6
Instruction executed: 42f645c6
Instruction executed: b8
Instruction executed: 9090c3c9
Instruction executed: 909090c3
Như vậy có thât sự đã "READ" được nó ?!? .. Liệu đây có phải là một bug của Linux kernel hay mình đang mơ ngủ =,,= nhầm lẫn chỗ nào đó....
Đây là thông số máy của mình
Code:
$ uname -a
Linux windak-pc 2.6.28-11-generic #42-Ubuntu SMP Fri Apr 17 01:57:59 UTC 2009 i686 GNU/Linux
$ gcc -v
Reading specs from /usr/lib/gcc/i486-linux-gnu/3.4.6/specs
Configured with: ../src/configure -v --enable-languages=c,c++,f77,pascal --prefix=/usr --libexecdir=/usr/lib --with-gxx-include-dir=/usr/include/c++/3.4 --enable-shared --with-system-zlib --enable-nls --without-included-gettext --program-suffix=-3.4 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --with-tune=pentium4 i486-linux-gnu
Thread model: posix
gcc version 3.4.6 (Ubuntu 3.4.6-1ubuntu2)
Giờ đi ngủ, hi vọng mai tỉnh táo sẽ xem xét lại lần nữa. Mọi người xem cùng nhé.
wd.
|
|
|
ma_sp của bạn là kiểu gì, s là kiểu gì.
|
|
|
|
|
|
|